Kafka教程(三):原理及存储
一、思维导图
1、实时更新连接
https://www.mubucm.com/doc/1GRE2U7qYuj
2、思维导图图片
二、具体内容
-
8.系统架构
-
架构推导
-
拓扑结构
-
多对多
-
leader读写,follower同步
-
-
结构组成
-
分类topic存储数据
-
提高吞吐量,进行分区
-
多副本数据一致性通过leader统领
-
动态选举保证分区可用性
-
通过zk获取集群内的元信息和状态信息
-
通过偏移量获取消息读取位置
-
-
-
broker
-
一个kafka集群包括多个broker
-
一个server代表一个broker
-
-
生产者和消费者
-
向broker发消息的客户端叫生产者
-
消费者
-
从broker读消息的客户端叫消费者
-
消费者组
-
单个或多个消费者组成消费者组
-
是实现消息广播(发多个消费者)和单播的手段
-
广播:每个消费者都有独立的cg
-
单播:一个cg包含多个消费者
-
-
-
消费到的偏移量之前记录在zookeeper中,现在记录在内置topic中(__consumer_offset)
-
-
-
主题和分区
-
topic
-
存储数据的逻辑分类(数据库中的表)
-
-
partition
-
topic数据的具体管理单元(HBASE中表的region)
-
通过key的哈希桶或轮询方式将消息发送到特定分区
-
好处:数据负载均衡、提高读写并发度和吞吐量
-
-
-
分区副本replica
-
leader
-
生产者与消费者只能跟leader交互(读写数据)
-
是分区副本replica的角色
-
-
follower
-
又名observer观察者
-
通过心跳信息从leader拉取、复制数据
-
leader宕机,则从follower中选举出leader
-
-
-
消息偏移量offset
-
是一个自增id,用于定位消息的存储位置
-
只保证一个partition中消息的顺序
-
不保证topic的整体顺序(即多个partition间)
-
-
ISR副本同步列表
-
In-Sync Replica
-
每个分区的leader维护一个ISR列表
-
存放跟得上leader的follower副本
-
是否跟得上通过:replica.lag.time.max.ms=10000配置
-
leader的同步时间-每个follower的最后一次同步时间
-
AR=ISR+OSR
-
条件
-
踢出ISR:参数
-
重新加入:OSR副本的LEO(log end offset)追上leader的LEO
-
-
-
数据存储架构
-
整体存储结构
-
topic(逻辑)
-
partition(物理)
-
replica副本
-
log日志
-
logsegment日志分段
-
.log日志文件
-
.index偏移量索引文件
-
.timeindex时间戳索引文件
-
-
物理存储目录
-
目录规范
-
topic名-分区号
-
如:topic1-0
-
-
文件规范
-
消息会追加到log末尾,为了避免数据定位效率低下
-
对log文件采取分片+索引机制
-
具体方案
-
每个partition分为多个segment存储
-
每个segment对应.log和.index两个文件
-
以当前segment第一条消息的offset命名
-
-
索引寻找消息
-
文件名(offset)+偏移量(每个文件从0开始)-》index的索引
-
根据索引确定log中的位置(对应位置上)
-
索引项的密度由log.index.interval.bytes决定
-
常通过二分法定位偏移量的位置
-
-
-
-
消息message存储结构
-
API编程中有两个封装类
-
ProducerRecord
-
ConsumerRecord
-
-
MessageSet下包含多个Message、offset及对应的size
-
校验crc/magic版本/key和value的长度、K和value
-
attributes存储压缩编码、时间戳类型
-
-
-
-
9.关键原理加强
-
日志分段切分条件
-
分段文件大小大于1G(log.segment.bytes)
-
文件中消息的最小时间戳与当前时间差值大于log.roll.xxx
-
ms(优先级高)
-
hours(默认,7天)
-
-
偏移量或时间戳索引文件大于设定大小
-
log.index.size.max.bytes
-
-
追加消息的偏移量与日志起始偏移量差值大于Integer最大值
-
-
controller控制器
-
概述
-
含义
-
kafka集群的状态管理者,是集群中的某个broker
-
维护集群所有分区和副本的状态,以及分区leader的选举
-
-
负责内容
-
分区leader选举
-
ISR变化时,通知broker更新元数据信息
-
增加分区时,负责分区的重新分配
-
-
位置
-
成功竞选控制器的节点会在zookeeper中创建/controller临时节点
-
节点内容包括:version-1,brokerid,timestamp
-
-
竞选过程:读取brokerid的值
-
不为-1
-
放弃竞选
-
内存保存当前控制器的brokerid,并标识为activeControllerId
-
-
为-1
-
多个broker均尝试创建
-
先到先得
-
-
-
-
职责
-
监听partition的变化
-
/admin/reassign_partition节点注册监听器,处理topic增减
-
isr_change_notification节点注册监听器,处理ISR集合变更
-
/admin/prefered-replica-election节点注册监听器,处理优先副本选举
-
-
监听topic增减变化
-
/brokers/topics节点注册监听器,处理topic增减
-
/admin/delete_topics注册监听器,处理topic删除
-
-
监听broker相关变化
-
/brokers/ids节点注册监听器,处理broker增减
-
-
更新集群的元数据信息
-
从zk获取与topic、partition、broker有关信息并进行管理
-
从/brokers/topics/topic节点注册监听器,监听分区分配变化
-
同步最新信息给其他所有broker
-
-
启动并管理分区状态和副本状态
-
开启定时任务维护分区leader副本的均衡
-
-
分区的负载分布
-
controller负责分区副本在broker上的分配
-
副本因子小于节点数
-
第一个分区leader随机选,其他分区leader依次后移
-
剩余副本相对前一个副本便宜随机数
-
-
分区leader的选举
-
时机
-
创建分区
-
leader下线
-
-
策略
-
AR顺序查找第一个存活的副本,且该副本在ISR集合中
-
-
-
-
生产者原理解析
-
工作流程
-
主线程-消息累加器RecordAccumulator-Sender线程
-
各模块职责
-
主线程由kafkaProducer创建消息,通过拦截器、序列化器、分区器后缓存到消息累加器
-
Sender线程从消息累加器中获取消息并发送到kafka
-
消息累加器用来缓存消息,以便Sender可以批量发送,减少传输的资源消耗
-
-
参数设置
-
缓存大小:buffer.memory,默认32M
-
生产者发送速度大于发送到服务器速度
-
要么被阻塞,要么抛异常
-
通过max.block.ms设置,默认60000
-
-
-
结构
-
RecordAccumulator
-
每个分区维护一个Deque双端队列
-
写入时,追加到尾部
-
读取时,从头部读取
-
一个消息批次称为一个ProducerBatch,可以凑多为一,通过batch.size决定
-
需要向很多分区发消息,建议调大buffer.memory
-
-
Sender
-
缓存消息结构转换,将分区转换为Node
-
消息还会保存到InFlightRequest,保存发出未响应的请求
-
通过参数设置缓存未响应请求的个数:max.in.flight.request,默认为5
-
-
-
-
消息的应答(确认)机制
-
即:配置消息发送到分区的几个副本才算发送成功
-
通过acks参数决定
-
0
-
通过网络发出去则成功
-
速度快,可能发生错误,大概率丢消息
-
-
1
-
leader收到消息并写入分区数据文件返回确认或错误响应
-
会丢消息:follower同步消息前leader崩溃
-
-
-1/all
-
所有同步副本都收到消息
-
与min.insync.replica结合决定至少多少副本收到消息
-
生产者等待所有副本收到,速度慢
-
只有最小同步副本数大于2,才不会丢数据,负责只有一个leader
-
-
-
-
重要的生产者参数
-
max.request.size
-
生产者发送消息最大值,默认1M
-
与其他参数联动(如broker的message.max.bytes)
-
-
retries和retry.backoff.ms
-
配置生产者的重试次数,默认为0
-
存在异常:网络抖动、leader选举
-
后者为重试时间间隔,避免无效的频繁重试
-
保证顺序还需设置in.flight
-
-
compression.type
-
默认不压缩,压缩即空间换时间
-
包含类型:gzip/snappy/lz4
-
-
batch.size
-
凑够批次大小,才会发送消息
-
和吞吐量成正比,和延迟成反比
-
-
linger.ms
-
生产者发送batch前等待更多消息加入的时间
-
在batc填满或时间超过时发送
-
增加延迟,提高吞吐量
-
-
enable.idempotence
-
是否开启幂等性
-
幂等性
-
语句重复做,不影响最终结果
-
如:int i=1/i++,满足&不满足
-
在kafka即,消息发多次只存一次
-
-
-
partitioner.class
-
指定分区器,默认分区器根据有无key、value进行哈希或轮询
-
自定义分区器需要实现Partitioner接口
-
-
-
-
消费者组再均衡分区分配策略
-
意义:提高数据处理并行度
-
触发
-
新消费者加入cg
-
消费者真/假下线
-
主动退出消费者组,如unsubscribe
-
消费者组节点变更
-
订阅的主题或分区发生变化
-
-
含义:分区的消费权转移给另一个消费者
-
策略(消费者参数partition.assignment.strategy)
-
range(默认)
-
partition数/消费者数
-
按区间分配,多出来的给前两个,一开始就多分配
-
-
round robin:TopicPartition按哈希码排序,轮询方式分配
-
新:Sticky Strategy
-
最大化均衡,尽可能保留原有分区
-
先取消自身分区再重新分区
-
-
新:Cooperative Sticky Strategy
-
最大化均衡,尽可能保留原有分区
-
不会取消所有分区
-
-
-
-
消费者组再均衡流程
-
组内事务协调角色
-
组协调器:Group Coordinator(服务端的某个broker)
-
组长:Group Leader(消费者组中的某个消费者)
-
-
Group Coordinator
-
每个消费者组对应一个Group Coordinator进行管理
-
是kafka服务端用于管理消费者组的组件
-
与消费者客户端的ConsumerCoordinator交互
-
二者的实则是负责执行消费者的Rebalance操作
-
-
再均衡流程
-
eager协议:再均衡发生时,停止所有消费者的工作,取消所有分区
-
cooperative协议:把eager的一次全局再均衡,转换成负责分区的小均衡
-
-
eager协议再均衡步骤
-
定位group coordinator组协调器
-
位置:__consumer_offset分区的leader所在broker上
-
先定位其分区号(groupid的哈希码对分区总数50取余)
-
确定分区中leader的broker节点
-
-
加入组Join The Group
-
消费者组leader选举(随机)
-
选择分区随机策略
-
各消费者支持的分配策略第一个投票,计算选票数作为消费责组策略
-
分区分配策略由Group Coordinator执行
-
-
组信息同步SYNC Group
-
消费者组leader将分配方案,通过Group Coordinator转发给组内消费者
-
-
心跳联系Heart Beat
-
消费者正常工作后向协调器Coordinator发送心跳
-
参数
-
心跳间隔时间:heartbeat.interval.ms
-
session.timeout.ms
-
-
-
-
再均衡监听器
-
功能:控制消费者发生再均衡时执行特定操作
-
再均衡时,处理消费位移
-
避免再均衡时,重复消费
-
调用subscribe重载方法,内部包含两个方法,分别进行实现
-
-
-
-
kafka系统的CAP保证
-
分布式系统的CAP理论
-
内容:三个特性最多满足两个
-
三个特性
-
C(consistency):一致性
-
读写一致
-
-
A(availability):可用性
-
P(Partition tolerance)分区容错性
-
-
对kafka来讲,可靠性(分区容错性)和可用性优先考虑,兼顾一致性
-
-
分区副本机制
-
从0.8.0开始引入分区副本,带来数据冗余
-
CAP理论解释:通过副本及动态选举提高了其分区容错性和可用性,但增加了一致性的困难
-
-
分区副本的数据一致性困难
-
基本手段:follower定期向leader请求数据同步
-
带来数据不一致的场景
-
分区副本读到的offset进度不一致(动态过程中)
-
followers副本选举为leader后消费者所见的不一致
-
分区间副本最终数据不一致(选举后写入其他数据,原来leader变为follower)
-
-
-
一致性问题解决方案(HW)
-
核心思想
-
维护步进式的临时一致线(High Watermark)
-
高水位线HW=ISR副本中的最小LEO
-
offset<HW,是各副本间一致且安全的(所有副本已备份好的数据)
-
-
问题解决
-
消费者所见不一致:只允许看到HW以下的message
-
分区副本数据最终不一致:根据新leader的HW对数据阶段,保证与新leader的数据一致
-
-
-
HW方案的天生缺陷
-
leader和follower进行RPC通信更新LEO和HW时,需要额外一轮请求才能完成更新
-
在leader切换过程中,存在丢数和不一致的问题
-
-
Leader-Epoch-checkpoint机制引入
-
格式:epoch,offset,epoch为leader的版本,递增
-
副本成为leader,更新epoch和LEO;成为follower请求最新epoch,一致则取leader的LEO
-
可以解决HW的数据丢失、数据最终不一致问题
-
-
LEO/HW/LSO术语
-
LEO-最大偏移量,LSO-最后一个稳定的偏移量
-
HW-各副本LEO最小值,LW-副本中最小偏移量
-
-
不清洁选举
-
非ISR副本可以选举为leader,由unclean.leader.election.enable控制
-
会产生数据丢失及不一致问题
-
-
-
以上内容整理于 幕布文档
本文来自博客园,作者:哥们要飞,转载请注明原文链接:https://www.cnblogs.com/liujinhui/p/16754858.html