Kafka
Kafka 入门到精通。
- Kafka 硬件配置选择
- Kafka 生产者
- Kafka Broker
- Kafka 消费者
- Kafka总体
针对Kafka3.0.0
Kafka 传统定义:
分布式 的基于发布订阅的消息队列Message Queue。主要应用于大数据实时处理领域。
最新的定义:
新的开源的分布式事件流平台 Event Streaming Platform。 用于数据管道 流分析 数据集成 和关键任务的应用。
消息队列 应用场景:
缓存/削峰 解耦 异步通信。
消息队列两种模式
点对点模式
消费者主动拉取数据 消息收到后清除消息
发布/订阅模式
可以有多个Topic主题
消费者消费数据后 不删除数据
每个消费者相互独立 都可以消费到数据。
kafka 架构
Producer + Topic -->>Consumer
方便扩展----->>>
并提高吞吐量。 一个Topic 分为多个Partition。
配合分区设计 提出消费者组的概念 组内每个消费者并行消费。
为了提高可用性。每个Partition 增加若干副本 类似NameNode HA
副本 有Leader 和Follower 之分。
ZK中记录谁是Leader Kafka 2.8.0 以后也可以配置不采用ZK 。
处理操作 只针对 Leader 副本 Follower 是一个备份。
入门
集群规划
Kafka broker 代码是Scala 写的。
安装配置 broker.id logdirs zookeeper.connect
kafka 启动停止脚本
Topic 相关命令。
分区只能增加不能减少。
生产者脚本。
链接Broker端。 bootstrap-server 。
消费者脚本
Kafka 生产者
Java 序列化 比较重。
Sender 线程。
batch.size. 16k 一批。 批次大小。
linger.ms 等待时间。默认0ms
InFlightRequest 默认每个broker 节点最多缓存5个请求。
应答级别:
ACK。 0 ,-1/all,1.
异步发送。
异步发送。回调异步发送----->>>>> onCompletion 方法。
同步发送
生产者分区
拦截器 一般不用。 序列化器。很少去自定义。
分区的好处
1.便于合理的使用存储资源。 合理控制分区的任务 可以实现负载均衡。
2. 提高并行度。
生产者分区策略
- 指明partition 的情况下,直接将 指明的值 作为Partition的值,
- 没有指明但是有key的情况下,将key hash 值与Partition 取余得到partition 的值。
- 既没有分区 也没有Key的值 采取 Sticky Partition。黏性分区器。
尽可能一直使用该分区 待该分区Batch 已满 或已完成 随机一个分区进行使用。 和上一次不同,
自定义分区 分配。
生产经验
生产者如何提高吞吐量。
批次大小
等待时间
压缩Snappy
缓冲区大小。Record Accumulator
数据可靠
数据应答级别。ACK。0 不需要应答。 1 需要Leader 收到后进行应答。-1 所有节点收齐数据后进行应答。
ISR:
数据完全 可靠:
ACK级别=-1 && 分区副本数大于等于2 && ISR里应答的最小副本数量大于等于2.
***ACK =-1 :leader 和ISR队列里所有的Follower应答 可靠性低 效率低。***
注意⚠️ 是Leader和ISR队列里 所有的Follower 。
ACK=0 很少使用。
ACK=1 一般用于传输普通日志。 允许丢个别数据
ACK=-1 一般用于传输和前有关的场景。对可靠性要求比较高的。
ACK=1 会有数据重复
重试次数。设置 retries 。
数据重复
数据传递的语义:
至少一次:ACK 为-1。+ 分区副本>=2 + ISR 里应答的 最小副本数量>=2
最多一次:ACK=0
精确一次:
幂等性和事务。
幂等性: Producer 不论向 Broker 发送多少次 重复数据,Broker 端都只会持久化一条,保证不重复。
精确一次:幂等性+ 至少一次。
幂等性判断条件:
PID + Partition + SeqNumber 。 具有相同的主键的消息提交时 Broker 只会持久化一条。 其中PID 是每次和Kafka重启都会分配一个新的,Partition 表示分区号 Sequence Number 是单调自增。
幂等性能保证单分区 单会话内不重复。
enable.idempotence = true 开启幂等性。
生产者 事务:
开始事务 必须开启幂等性。
事务协调器 Transaction Coordinator
事务id对50取模,算出事务属于哪个分区,分区Leader 副本所在的broker 节点即为这个transaction id对应的 transaction Coordinator 对应的节点。
Producer 在 使用事务之前,必须先自定义一个唯一的事务id ,有了transactional.id 即使客户端挂掉了,它重启也能处理未完成的事务。
事务 5个API。
必须指定 transaction id。
数据有序
单分区内 有序。多分区分区间无序。
数据乱序
请求缓存 InFlightRequests 最多缓存 5个请求。
1.x之前 保证单分区有序---->>>> 设置参数 不需要考虑幂等性。
kafka。1.x版本 之前保证单分区有序。 条件如下:
max.in.flight.requests.per.connection =1 只有一个 飞行中的请求。 未开启幂等性。
开启幂等性—>>>> 需要设置 小于等于5.
Kafka Broker
pretty Zoo :查看ZK相关信息。
ZK存储了 Kafka 哪些信息?
1. ids 记录了有哪些 服务器
2.记录了 谁是Leader 有哪些服务器可以用。 每个主题的分区,ISR都是谁。
consumers : 0.9 版本之前存储offset 信息。 0.9版本之后 存储在Kafka的主题中。
3.辅助Leader 选举。的Controller 。相关信息。
Kafka Broker 总体工作流程
AR Kafka 分区中所有副本的统称
生产相关-----节点的服役和退役
服役节点。对某些节点进行 负载均衡。
分配数据到 新的节点上。
reassign- partition
退役旧节点。
移动不同主题上的数据。
创建执行 计划。 generate。
执行 /// 执行完毕 后验证。
回顾
Kafka Broker 副本相关信息
Kafka Broker Leader 选举流程
选举规则:
ISR中存活为前提,按照AR中 排在前面的优先。
注意⚠️ 是按照 AR的顺序 而非ISR的顺序。
Kafka broker、 Follower 故障 Leader 故障。
LEO:Log End Offset :每个副本最后一个offset LEO 其实就是offset+1
HW :高水位线。 所有副本中最小的LEO 。
Leader 故障 :这只能保证 副本之间数据的一致性。并不能保证 数据不重复或不丢失。
分区副本的分配
尽可能 保证均匀。
生产经验:手动调整分区副本
手动干预副本。
创建副本存储计划—>>>>. ~.json
reassgin-partitions.sh. 验证命令。
个别服务器配置较低 可以手动干预
Broker Leader Partition 负载均衡
auto.leader.rebalance.enable. 默认是true。
不均衡 比例10% leader.imbalance.check.interval.seconds . 检测时间300s 。
leader.imbalance.per.broker.percentage =10%
建议不要开启 触发再平衡会消耗大量性能, 不需要再平衡也可以保证均匀,
生产经验 增加副本因子。
手动增加 副本 存储计划。 不能通过命令行的方式。
kafka 文件存储
Topic 是一个逻辑概念,partition 是 物理的概念。
每个分区对应一个log文件。 再切割物理单元 -->>Segment . 1G
Seg = .log + .index + .timeindex + 其他文件。 .timeindex 保留时间 到7天。
生产者产生数据会 不断追加到log 文件的末端。
index 中只记录一条所有。
index 为稀疏索引---->>>>. 大约 每往log 中写入4Kb数据 会往index 文件中写入一条索引。
参数为 log.index.interval.bytes 默认 4kb
保存offset 为相对offset 。 确保offset 保存值 不会特别大,因此能将offset 的值控制在固定的大小。
Kafka 文件清理策略
log.retention.hours 默认7天。
log.retention.ms 最高优先级 ms 最低优先级 小时。 默认check 周期是 5min 。
日志清理策略:
delete 和compact 两种
默认采用删除策略:
基于时间 默认打开。以Seg 中所有记录 最大的时间戳 作为文件时间戳
基于大小 – 默认关闭。超过总大小 删除最早的Seg 默认-1 不删除。
压缩:
相同Key的value值 只保留最新的版本。
压缩后的offset 可能是不连续的。
kafka 高效读写
1 本身是 分布式集群,可以采用分区技术 并行度高
2 读数据采用稀疏索引 可以快速定位要消费的数据
3 顺序读写磁盘。 顺序写600M/s
Kafka消费者组 初始化
- coodinator 辅助 实现消费者 组的初始化 和分区分配。
节点选择。 group_id 的hashcode 值%50. __consumer_offsets 的分区数量。 - 再平衡 会影响Kafka 性能。
- Consumer 和Coordinator 通信时间超时 超时时间45s,超时会触发再平衡。
- Consumer 处理拉过来数据的时间过长 超时。5min。也会触发再平衡。
消费者组 详细消费流程。
抓取字节 大小。 或者一批数据 最小超时时间。
消费者API的代码中 必须 配置 消费者组id 命令行启动消费者 不填写消费者组id 会被自动填写随机消费者组id 。
消费一个主题,消费一个分区。
消费者组 案例。
生产经验之 分区的分配 和再均衡
Kafka 四种分区分配策略:
Range Round Robin。 Sticky。 Cooperative Sticky。
Range 分配:
默认是Range + Cooperative Sticky
Range 如果宕机了 会将任务整体分配给。其他的consumer。
而后再 均衡 重新执行新的分配计划。
RoundRobin 轮询的方式
所有Topic 分 区 进行分配。 如果有宕机的 情况,会将宕机的节点数据 继续分配给 存活节点。
Sticky 以及再平衡
每个消费者 都与ZK进行交互获取offset 会进行大量网络通信。
exclude.internal.topic = false 默认是不允许 看系统主题里的相关数据。 设置为true。
key是 组id,+ topic, +分区号,
自动OFFSET 。
enable.auto.commit auto.commit.interval.ms 自动提交时间间隔ms 默认5000ms.
手动OFFSET
同步提交 :必须等到offset 消费完之后开启消费一波。 commitSync
异步提交。
指定OFFSET 消费。
earlist // latest // none
保证 分区分配方案制定完毕后 获取 seek
按照指定时间消费。
时间转换为对应的offset。
offsetsForTimes
消费者事务
漏消费 和重复消费
重复消费: 自动提交OFFSET 引起。 走到一半 挂了。
手动提交 数据在内存中未落盘。
精确一次消费。
消费者采取事务的方式 ,下游消费者采用 事务 可回滚。
数据积压
增加分区 ,增加消费者个数。
每次拉取500—1000条。
生产端:
时间 /batch_size批次/ 压缩/ 缓冲区大小。
回顾 day02
Kafka Eagle 的监控
EFAK
Kafka Kraft 模式
去掉ZK 。2.8+ 。
基本架构对比。
Kafka 外部系统的集成
Flume / Spark /Flink /SpringBoot
Flume 安装。配置
集成Flume 生产者。Flume消费者。
Flink:
基于Flink1.13.
作为生产者。
作为消费者。
SpringBoot:
作为生产者
作为消费者。
Spark 生产者
Spark消费者 Spartk Streaming。
~ LocationStrategies
位置策略
位置策略,
控制特定的主题分区在哪个执行器上消费的。
在executor针对主题分区如何对消费者进行调度。
位置的选择是相对的,位置策略有三种方案:
1.PreferBrokers
首选kafka服务器,只有在kafka服务器和executor位于同一主机,可以使用该中策略。
2.PreferConsistent
首选一致性.
多数时候采用该方式,在所有可用的执行器上均匀分配kakfa的主题的所有分区。
综合利用集群的计算资源。
3.PreferFixed
首选固定模式。
如果负载不均衡,可以使用该中策略放置在特定节点使用指定的主题分区。手动控制方案。
没有显式指定的分区仍然采用(2)方案。
Kafka 生产调优
硬件相关
机械硬盘 和 固态硬盘 顺序读写速度差不多。
Kafka 堆内存+ 页缓存。 Kafka 内部配置 + 服务器内存。
堆内存:10-15G
页缓存:segment 1g*25% *10 分区 /3 台服务器=1G
建议32Core CPU
网络选择:
千兆网卡即可。 20M/s
生产者
read-only。 重启集群
per-broker。每个broker 动态加载
cluster-wide 集群动态生效。
Broker
自动创建Topic 置为false
消费者
整体调优
- 提升 吞吐量
- 数据精准一次
- 合理设置分区
- 单条日志大于1M
- 服务器挂了
- 集群压力测试