分布式基础概念 - 消息中间件 [Kafka]
Kafka 架构设计
Consumer Group:消费者组,消费者组内每个消费者负责消费不同分区的数据,提高消费能力。逻辑上的一个订阅者。
Topic:可以理解为一个队列,Topic 将消息分类,生产者和消费者面向的是同一个 Topic。
Partition:为了实现扩展性,提高并发能力,一个 Topic 以多个 Partition 的方式分布到多个 Broker 上,每个 Partition 是一个 有序的队列。一个 Topic 的每个 Partition 都有若干个副本(Replica),一个 Leader 和若干个 Follower。生产者发送数据的对象,以及消费者消费数据的对象,都是 Leader。Follower 负责实时从 Leader 中同步数据,保持和 Leader 数据的同步。Leader 发生故障时,某个 Follower 还会成为新的 Leader
Zookeeper:Kafka 集群能够正常工作,需要依赖于 Zookeeper,Zookeeper 帮助 Kafka 存储和管理集群信息。
如图所示:
Kafka 高性能高吞吐的原因
磁盘顺序读写:保证了消息的堆积
顺序读写,磁盘会预读,预读即在读取的起始地址连续读取多个页面,主要时间花费在了传输时间,而这个时间两种读写可以认为是一样的。
随机读写,因为数据没有在一起,将预读浪费掉了。需要多次寻道和旋转延迟。而这个时间可能是传输时间的许多倍。
零拷贝:避免 CPU 将数据从一块存储拷贝到另外一块存储的技术
传统的数据复制:
读取磁盘文件数据到内核缓冲区
将内核缓冲区的数据 copy 到用户缓冲区
将用户缓冲区的数据 copy 到 socket 的发送缓冲区
将 socket 发送缓冲区中的数据发送到网卡、进行传输
零拷贝:磁盘文件->内核空间读取缓冲区->网卡接口->消费者进程
分区分段+索引
Kafka 的 message 消息实际上是分布式存储在一个一个小的 segment 中的,每次文件操作也是直接操作的 segment。为了进一步的查询优化,Kafka 又默认为分段后的数据文件建立了索引文件,就是文件系统上的.index 文件。这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也提高了数据操作的并行度
批量压缩:多条消息一起压缩,降低带宽
批量读写
直接操作 page cache,而不是 JVM、避免 GC 耗时及对象创建耗时,且读写速度更高,进程重启、缓存也不会丢失
Kafka 的副本同步机制
如图:
LEO:下一条待写入位置
firstUnstableOffset:第一条未提交数据
LastStableOffset:最后一条已提交数据
LogStartOffset:起始位置
isolation.level=read_committed:只能消费到 LastStableOffset,read_committed 可以消费到 HW 的上一条
一个 partition 对应的 ISR 中最小的 LEO 作为分区的 HW,consumer 最多只能消费到 HW 所在的位置 leader 收消息后会更新本地的 LEO,leader 还会维护 follower 的 LEO 即 remote LEO,follower 发出 fetch 同步数据请求时(携带自身的 LEO)、leader 会更新 remote LEO,更新分区的 HW,然后将数据响应给 follower、follower 更新自身 HW(取响应中的 HW 和自身的 LEO 中的较小值),LEO+1
ISR:如果一个 follower 落后 leader 不超过某个时间阈值,那么则则 ISR 中,否则将放在 OSR 中。
同步副本时,follower 获取 leader 的 LEO 和 LogStartOffset,与本地对比、如果本地的 LogStartOffset 超出了 leader 的值,则超过这个值的数据删除,再进行同步,如果本地的小于 leader 的、则直接同步
Kafka 消息高可靠解决方案
消息发送:
ack:0、不重试,1、lead 写入成功就返回了,all/-1、等待 ISR 同步完再返回
unclean.leader.election.enable : false,禁止选举 ISR 以外的 follower 为 leader
tries > 1,重试次数
min.insync.replicas > 1:同步副本数,没满足该值前、不提供读写服务、写操作会异常
消费:
手工提交 offset
broker:减小刷盘间隔
事务消息
Kafka 的 rebalance 机制
consumer group 中的消费者与 topic 下的 partion 重新匹配的过程何时会产生 rebalance:
consumer group 中的成员个数发生变化
consumer 消费超时
group 订阅的 topic 个数发生变化
group 订阅的 topic 的分区数发生变化
coordinator:通常是 partition 的 leader 节点所在的 broker,负责监控 group 中 consumer 的存活,consumer 维持到 coordinator 的心跳,判断 consumer 的消费超时
coordinator 通过心跳返回通知 consumer 进行 rebalance
consumer 请求 coordinator 加入组,coordinator 选举产生 leader consumer
leader consumer 从 coordinator 获取所有的 consumer,发送 syncGroup(分配信息)给到 coordinator
coordinator 通过心跳机制将 syncGroup 下发给 consumer
完成 rebalance
leader consumer 监控 topic 的变化,通知 coordinator 触发 rebalance
如果 C1 消费消息超时,触发 rebalance,重新分配后、该消息会被其他消费者消费,此时 C1 消费完成提交 offset、导致错误
解决:coordinator 每次 rebalance,会标记一个 Generation 给到 consumer,每次 rebalance 该 Generation 会+1,consumer 提交 offset 时,coordinator 会比对 Generation,不一致则拒绝提交
历史相关精彩内容
如有问题,欢迎加微信交流:w714771310,备注- 技术交流 。或关注微信公众号【码上遇见你】。
版权声明: 本文为 InfoQ 作者【派大星】的原创文章。
原文链接:【http://xie.infoq.cn/article/fdc6f9614a7c147ca84f4ba7f】。
本文遵守【CC BY-NC-ND】协议,转载请保留原文出处及本版权声明。
评论