使用消息队列的好处
- 解耦
允许独立的修改或者扩展两边的处理过程,只要确保其遵循同样的约束接口。
- 可恢复性
系统的一部分组件失效时,不会影响整个系统。即使部分处理消息的线程挂掉,消息加入队列,也能在系统恢复后被处理。
- 缓冲
用于解决生产者和消费者速度不一致的情况。
- 灵活性和峰值处理
在流量激增的情况下不会导致系统奔溃
- 异步处理
用户收到消息不想立即处理,需要的时候再进行处理。
消费队列模式
- 点对点
只有一个消费者 flume
- 发布订阅
只要不删消息都在
队列主动推送:缺点推送的速度统一,但是每一个订阅者的处理速度不一
消费者主动拉取的模式:缺点需要消费者进行长轮询看有没有新消息,浪费资源
kafka 是主动拉取模式,消费者的消费速度可以由自己决
被动拉取的模式, 维护一个用户列表,消息来到,通知消费者,消费队列的两端是可以不同时在线,但是被动通知还需实时监测消费者是否在线
kafka 架构
image.png-
zookeeper 帮助kafka 维护集群 ,存储 topic 信息, topic 分区的 leader ,follow 位置 等信息。消费者会在zookeeper中存储消费的偏移量。0.9 之前。0.9后将偏移量保存在kafka集群topic,存在磁盘。默认存7天。
-
topic 主题会存在 分区 和 副本数, 分区存在 leader 和 follower
分区的好处,提高读写的并行度,提高负载。 副本的作用,用于容灾处理
- 同一个消费者组里的消费者同一时刻不能消费同一个topic的同一个分区。
消费者组,提高消费数据的能力。消费者组里的消费者个数和分区一致是最好。
消费者组分配的策略问题。
- 生产者将数据交付分区,存在策略问题。
kafka中的副本数不能超过 可用broker,分区数可以超过。
kafka分区存储
image.png每一个分区会维护一个偏移量,不是通过全局进行维护偏移量,所以不能保证数据全局有序,只能保证分区内的有序性。
配置 文件存储 最大 1 G , 当存储超过1G ,
每一个分区下面 有 log 文件 和 index 文件, 使用index 定义当前消费数据,log里面只存储数据, index用于快速定位数据位置
Kafka 采用分片 和 索引机制 按照 1 G进行分片, index 里面存储 log数据的索引, 采用二分查找定位 在哪一个索引中,后面是数据的大小
生产者策略
-
分区:默认是 RR 的轮询分区划分规则, 若指定了Key 则将key的hash值 % 分区号进行分区
-
kafka数据的可靠性: 分区必须确认收到,同时副本备份成功。 ack
半数以上follower完成备份 发送 ACK, 问题是选举新的leader ,容忍 n 台故障,需要 2n + 1 个副本
全部完成, 问题是延迟长, Kafka 选择这种,但是问题是 存在一个慢 ,或者挂掉,
- ISR 代表同步副本,leader 从 ISR 中选新 leader, 通信时间 ,在延迟时间内去掉
kafka 中维护 ISR 的队列
当leader 接受到消息后,通知 ISR 中的follow 完成备份
- acks 0 收到, 1 leader 完成 -1 leader,follower所有follow完成,(重复数据)
产生同步数据 ,follower 备份完成后, 这是leader 挂掉, producer 任务没收到,向follewer备份选举后的重复发送数据
一致性: follower还没同步完成,同步一半 leader 挂了,选举后作为leader 后原leader 活了,导致数据不一致
消费数据一致性:Leo: 每一个分区副本的最大 offset ,设置一个 HW 指的是高水位,所有分区leo的最小位置,HW之前的数据才对消费者可见
存储数据一致性: 重新选leader 给所有分区发生消息,直接截取数据到HW.
- exactly-once : ack 为0 at-less-most
幂等性 + 至少一次 为精准一次
使用幂等性,在kafka 的 broker 消除数据的重复, kafka使用幂等性,默认 ack 为-1
首先给每一个生产者 添加一个 id , 给每一个消息 添加一个序列号, 如果同一个 生产者, 同一个消息序列号, 发往同一个分区,如果已经接受过,就进行去重。
但是生产者挂了重启,那么它的id 号也就变了,也就不能保证精准 一致性
消费者策略
- 分区 , RR 轮询,将当前消费者组不同的主题,当做一个整体,经轮询。好处,消费者组里面的消费最多差一个。
保证消费者组里面消费的topic 是一样的。 Range 是按照单个主题进行划分,将不同的topic 不当做一个整体进行考虑。
触发时在消费者组里面消费者个数变化时会触发分区,重新设置分配分配策略。
- offset
消费者组 + 主题 + 分区 决定 offset, 消费者连接
Kafka 可以顺序写磁盘, 零拷贝技术
Range 分区
Range 分区不会把主题看做一个整体进行划分
假设 有两个主题, T1(0,1,2), T2(0,1,2), 两个消费者组 (A,B) (C)
A 消费者 订阅 T1 , B 订阅 T1, T2 ,C 订阅了 T1
RR : 如果采用的RR 发现 A,B 消费者共用同一个组, 则会把 A,B 订阅的topic 当做一个整体进行考虑。
A,B 进行轮询的分区有: T1 0 T1 1 T1 2 T2 0 T2 1 T2 3
Range : 按主题划分,先考虑谁订阅了这个主题,然后再进行划分
kafka API
kafka producer 的 main 线程 将消息发送给 RecordAccumlator , Sender 线程 不断从 RecordAccumlator 中进行拉取数据。
异步发送, 经过拦截器,序列化器,分区器
Kafka 面试题
消费者提交消费位移的是当前消费到的最新消息的 offset + 1
什么情况下会导致消费重复?
写 处理 数据 再提交 offset 会重复消费。 可能提交失败
什么情况下会导致漏消息?
先提交 offset 再消费 数据。
网友评论