这是我参与「第四届青训营 」笔记创作活动的第10天
Kafka
架构
生产者、Broker、消费者、Zookeeper(Broker id、ids等)
以下图片为个人理解,如有不妥请指正!
参数配置
- 机器数量=2 *(峰值生产速度 * 副本数 / 100)+ 1
- 副本数:2 / 3 -> 提高可靠增加IO
- 日志保存(7天 ,建议3天
- 硬盘大小=数据量 * 副本 * 天数 / 70%
- 分区数=期望吞吐量 / min(producer,consumer吞吐量)
- Topic数量=日志类型数量
- 内存:默认1g
生产者
面向一个topic
-
发送方式:同步、异步、带回调函数异步
-
分区分配策略:producer可以指定分区,将数据存储在(key的hash值 % 分区数)号分区中
-
提高吞吐:批次大小(batch.size:16k->32k) / 等待时间(linger.ms:0->5-100ms) / 压缩(compression.type) / 缓冲区大小(32m->64m)
-
数据可靠:
Ack:
- Ack=0:生产者发送消息增加offset,继续生产;数据可能丢失
- Ack=1:Leader应答增加offset;
- Ack=-1:Leader和ISR队列所有Follwer应答增加offset;数据可能重复
幂等性(enable.idempotence) :生产者发送的消息Broker端只持久化一条(单分区单会话)
精确一次= 幂等性 + 至少一次( ( ack=-1 + 分区副本数>=2 + ISR 最小副本数量>=2) )+无限重试
-
数据重复:开启事务( 必须指定transactional.id)或在下一级(分组、开窗)
Broker
与zookeeper交互保证集群运行,版本0.9之后offset保存在topic中。
服役新节点
- 创建一个要均衡的主题
- 生成一个负载均衡的计划
- 创建副本存储计划
- 执行副本存储计划
- 验证副本存储计划
退役旧节点
- 生成执行计划,同服役
Flower挂:踢出isr,其他不影响,上线后读取log里面副本中最小的offset(HW),直到>=HW
Leader挂:从isr选新,其余follower从新Leader同步
offset提交
自动(可能重复消费) / 手动(可能漏消费);
为避免可以将消费过程与提交offset过程做原子绑定,要求下游支持事务。
消费者
-
拉取数据
-
Consumer Group (CG ):消费者组,由多个 consumer组成,面向一个topic。
1.消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费,一个消费者可以消费多个分区(组内只有自己消费此分区);
2.消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者
-
再平衡及Range(将TopicAndPartition按照hashCode排序,轮询发给每个消费线程)
-
保证数据有序:开启幂等性->缓存数量小于5个,会在服务端重新排序 ;关闭幂等性->缓存数量设为1(因幂等性,所以单分区有序)
-
副本同步队列:zookeeper会维持一个isr队列,Leader挂掉会顺延isr中下一个服务,当心跳超过45s或者处理消息超过5分钟就会认为服务不可用并剔除出isr。
-
数据可靠:手动提交offset
-
可以按照时间消费数据:需要将offset转换为时间戳KafkaUtil.fetchOffsetsWithTimestamp
数据积压
消费能力不足:增加topic分区数,提升消费者数量,消费者数 = 分区数;
下游处理不及时(生产速度>拉取速度):提高每批次拉取的数量;
如何实现高效读写
- 本身是分布式集群,同时采用分区技术,并发度高;
- 顺序写磁盘:生产者生产数据是追加到log文件的末端;
- 读数据采用稀疏索引,可以快速定位
- 零复制技术