Kafka 原理详解(详解在注释里面,图片加载需要时间)
2023-07-04 08:40:44 0 举报
AI智能生成
知识要点和原理解析,详细信息和图片均在黄色图标的注释中,鼠标移动到黄色图标上即会显示,图片加载有时较慢。
作者其他创作
大纲/内容
消息队列实现方式
点对点模式:一对一
发布/订阅模式:一对多
push(推)模式
pull(拉)模式(kafka采用该方式)
架构图
组件构成
broker
一台 kafka 服务器就是一个 broker
一个kafka集群由多个 broker 组成
一个 broker 可以容纳多个 topic的多个partition
Topic(主题)
kafka将消息以topic为单位进行归类
在kafka集群中,可以有无数的主题
生产者和消费者消费数据一般以主题为单位。更细粒度可以到分区级别
一个topic 可以划分为多个partition,分布到多个 broker上管理
Partition(分区)
特征
topic是逻辑的概念,partition是物理的概念
每个partition由一个kafka broker服务器管理(即一个broker包含一个或多个partition)
partition 中的每条消息都会被分配一个递增的id(offset),每个 partition 是一个有序的队列,kafka 只保证按一个 partition 中的消息的顺序,不保证一个 topic 的整体(多个 partition 间)的顺序
每个partition都可以有多个副本
partition的表现形式就是一个一个的文件夹
每一个分区会有一个编号,编号从0开始
Partition的副本数
目的
保障 partition 的高可用
特征
leader replica分布
轮询算法
默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,否则报错,一般情况下等于broker的个数
follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)
处于同步状态的副本叫做in-sync-replicas(ISR)
follower通过拉的方式从leader同步数据
消费者和生产者都是从leader读写数据,不与follower交互
好处
对于 kafka 集群
实现topic数据的负载均衡
对于消费者
提高并发度,提高效率
Segment
特征
一个partition当中由多个segment文件组成
每个segment文件,包含两部分,一个是.log文件,另外一个是.index文件。
.log文件包含了发送的数据存储,.index文件记录的是.log文件的数据索引值,以便于加快数据的查询速度;
索引文件与数据文件的关系
索引文件中元数据指向对应数据文件中message的物理偏移地址
消息Message
字段的含义
Producer(生产者)
Consumer
Consumer Group
特征
同一个消费者组里的所有消费者不能同时消费消息,只能有一个消费者去消费
同一个消费者组里面是不会重复消费消息的
同一个消费者组的一个消费者不是以一条一条数据为单元的,是以分区(partition)为单元,就相当于消费者和分区建立某种socket,进行传输数据,所以,一旦建立这个关系,这个分区的内容只能是由这个消费者消费
模式转换
队列模型
发布-订阅模型
消息分流
注意
消费者数目及partition数目对应关系
partition数目 > 消费者数目
partition数目 = 消费者数目
partition数目 < 消费者数目
两个或多个消费者组
Group Coordinator
cluster、broker、topic、partition、消费者、费者组 关系
线程安全
Metadata
MetadataCache
topic 的详细信息
概括
元数据的作用
客户端
可以通过元数据获取服务地址,进行通信。(类似于服务发现)
服务端
可以通过元数据共享集群状态,一旦出现状态变化能够快速感知到,并且让各个 broker 快速更新元数据去保持一致。
Producer Metadata 的更新策略
1、 周期性的更新
2、失效检测,强制更新
如何触发
在 NetworkClient 的 poll() 方法调用时,就会去检查这两种更新机制,只要达到其中一种,就行触发更新操作
Metadata更新时特点
异步发送
负载选择
生产者
生产者缓存架构
主线程的逻辑
Sender 线程的逻辑
生产者拦截器 ProducerInterceptor
分类
生产者拦截器
自定义拦截器
序列化(Serializer)
分区器(Partitioner)
分区策略
分区作用
解决水平扩展的问题
解决消息顺序读取的问题
解决负载均衡的问题
键(key)的作用
ProducerRecord对象
key的作用
作为消息的附加信息
用来决定消息被写到主题的哪个分区中。拥有相同键的消息会被写到同一个分区中。
情况分类
情况一:键为空,不指定分区器
情况二:键为空,指定了分区器
partition方法
情况三:键不为空,指定了分区器
情况四:键不为空,没有指定分区器
分区策略
Partitioner接口
策略分类
BuiltInPartitioner(内置的默认分区器):随机
nextPartition方法
DefaultPartitioner(默认分区器)- 已废弃
DefaultPartitioner核心逻辑
UniformStickyPartitioner(统一粘性分区器)- 已废弃
如何选择新的粘性分区
与DefaultPartitioner不同点
RoundRobinPartitioner(轮询分区器)
逻主要辑源码
不是真的轮询
自定义分区策略
实现Partitioner接口、partition方法
配置自定义分区策略
弃用默认分区器DefaultPartitioner
DefaultPartitioner策略
弃用的原因
分配倾斜
配倾斜出现的原因
linger.ms
举例
对粘性分区策略问题的优化方案
partitioner.class将具有默认值null
改进的主要变化
2.8.0版本的partition()方法逻辑
3.3.0版本partition()方法逻辑
消息累加器(优化点)
构成
结构图
消息缓存模型
ProducerBatch的内存大小
内存分配
ProducerBatch的创建和释放
1、内存16K,缓存池中有可用内存
2、内存16K,缓存池中无可用内存
3、内存非16K,非缓存池中内存够用
4、内存非16K 非缓存池内存不够用
消息累加器作用
减少网络传输的资源消耗
减少磁盘I/O资源消耗
消息累加器的结构
Sender线程
KafkaProducer.send()逻辑
生产者消息产生及发送流程
比较重要的生产者参数
acks
acks=1
acks=0
acks=-1/all
max.request.size
retries和retry.backoff.ms
max.in.flight.requests.per.connection
compression.type
connection.max.idle.ms
linger.ms(优化点)
receive.buffer.bytes&send.buffer.bytes
request.timeout.ms
问题和答案
发送消息的时候, 当Broker挂掉了,消息体还能写入到消息缓存中吗
当最新的ProducerBatch还有空余的内存,但是接下来的一条消息很大,不足以加上上一个Batch中,会怎么办呢?
那么创建ProducerBatch的时候,应该分配多少的内存呢?
消费者、消费者组
消费者组是什么
三个特性
Consumer Group 下可以有一个或多个Consumer 实例
Group ID 是一个字符串, 在Kafka集群中唯一标识Consumer Group
Consumer Group 下所有实例订阅主体的单个分区,只能分配给组内某个Consumer实例消费。同一个分区消息可能被多个Group 消费。
Kafka消费者组解决了哪些问题?(与传统消息系统比较)
消息队列模型伸缩性差
发布/订阅模型下伸缩性差
Consumer Group 之间彼此队里,互不影响
用Consumer Group机制,实现了传统两大消息引擎
分区策略(重点)
设置partition值需要考虑的因素
推荐partition的数量一定要大于等于同时运行的consumer的数量
建议partition的数量大于等于集群broker的数量
分配策略
RangeAssignor(范围)(默认分配策略)
分配
1、以topic为单位
2、先对topic下的partition进行排序
3、再对topic下的consumer进行排序
4、将partition依次分配给consumer
每个topic都会重复上面4步的分配流程
配置参数
如何进行计算分区
解析
举例
缺点
分区数和消费者数无法整除时会造成倾斜
RoundRobin(轮询)
两种情况
如果所有consumer实例的订阅是相同的,那么partition会均匀分布
如果同一消费者组内,所订阅的消息是不相同的,那么在执行分区分配的时候,就不是完全的轮询分配,有可能会导致分区分配的不均匀
配置参数
工作原理:TopicAndPartition组合给consumer均分
举例
由于分配时是按所有Partition来的,所以即使Topic之间Partition的数量是不平均的,分配结果也是基本平均的,克服了RangeAssignor的缺点
缺点
示例
consumer订阅信息不一致时造成分配不平衡
总结
使用RoundRobin策略有两个前提条件
同一个Consumer Group里面的所有消费者的num.streams( 这个参数就是告诉 MirrorMaker 要创建多少个 KafkaConsumer 实例)必须相等
每个消费者订阅的主题必须相同
StickyAssignor(粘滞策略)
目标
1、分区的分配尽可能的均匀
2、分区的分配尽可能和上次分配保持相同
配置参数
示例一(消费者的订阅信息都是相同)
C1下线
采用RoundRobinAssignor策略
采用StickyAssignor策略
示例二(订阅信息不同的情况)
初始状态
采用RoundRobinAssignor策略
采用StickyAssignor策略
C0下线
采用RoundRobinAssignor策略(重新分配)
采用StickyAssignor策略
自定义分配策略
Coordinator-协调者
请求类型
组协调器
GroupCoordinator 的启动
Coordinator的确定与分区分配
1、确定consumer group位移信息写入__consumers_offsets这个topic的那个分区
2、该分区leader所在的broker就是被选定的coordinator
分区步骤
1、第1步就是找到这个coordinator,对于每1个consumer group,Kafka集群为其从broker集群中选择一个broker作为其coordinator。
2、找到coordinator之后,发送JoinGroup请求。
消费者加入组流程 JoinGroup
3、JoinGroup返回之后,发送SyncGroup,得到自己所分配到的partition
partition的分配策略和分配结果其实是由client决定的
组协调器同步流程 SyncGroup
heartbeat的实现原理
那这个定期发送如何实现呢?
是通过DelayedQueue来实现的
重平衡Rebalance
触发与通知
Rebalance 的触发条件
1、当 Consumer Group 组成员数量发生变化(主动加入或者主动离组,故障下线等);
2、当订阅主题数量发生变化;
3、当订阅主题的分区数发生变化;
Rebalance 如何通知其他 consumer 进程?
靠 Consumer 端的心跳线程
协议 (protocol) 说明
Heartbeat请求
LeaveGroup请求
SyncGroup请求
JoinGroup请求
DescribeGroup请求
consumer group状态机
核心是 rebalance 操作
重平衡发生在 PreparingRebalance 和 AwaitingSync 状态机中
重平衡所涉及的参数
session.timeout.ms
heartbeat.interval.ms
max.poll.interval.ms
Rebalance Generation
重平衡场景举例
有新的成员加入消费组
消费组成员崩溃
消费组成员主动离开
消费组成员提交位移时
优缺点
优点
给消费者组带来了高可用性和伸缩性。
缺点
再均衡期间消费者无法读取消息,整个群组有一小段时间不可用
partition被重新分配给一个消费者时,消费者当前的读取状态会丢失,有可能还需要去刷新缓存,在它重新恢复状态之前会拖慢应用程序。因此需要进行安全的再均衡和避免不必要的再均衡
kafka 静态消费组成员(优化点)
为什么需要
基本原理
静态消费者情况下重平衡逻辑及注意事项
参数说明
group.instance.id
session.timeout.ms
问题
为什么在一个group内部,1个parition不能被多个consumer拥有?
时序性
offset
如果有多个客户端配置了不同的分配策略, 那么会以哪个配置生效呢?
1、选择所有 Member 都支持的分配策略;
2、在 1 的基础上,优先选择每个partition.assignment.strategy配置靠前的策略。
消费者消费并提交了之后,其他消费者是如何知道我已经消费了,从而不会重新消费的呢?
为什么要在consumer中选一个leader出来,进行分配,而不是由coordinator直接分配呢?
offset管理机制
位移保存
老版本(Kafka0.9版本之前)
保存在 ZooKeeper 中
好处
减少了 Kafka Broker 端的状态保存开销
服务器节点做成无状态的,这样可以自由地扩缩容,实现超强的伸缩性
缺点
ZooKeeper不适合进行频繁的写更新
新版本(从0.9版本开始)
位移保存在 Kafka内部主题的方法,也就是__consumer_offsets
broker无状态
那访问压力去哪了呢?
位移主题(Offsets Topic)
特征
__consumer_offsets 的主要作用是保存 Kafka 消费者的位移信息
它要求这个提交过程不仅要实现高持久性,还要支持高频的写操作
消息格式却是 Kafka 自己定义的,用户不能修改
Kafka Consumer 有 API 帮你提交位移
分区数
消息格式
key
Group ID,主题名,分区号
value
主要保存的是offset 的信息,当然还有时间戳等信息
offset 的分类
LogStartOffset
ConsumerOffset
HighWatermark
特征
在分区高水位以下的消息被认为是已提交消息,反之就是未提交消息。
位移值等于高水位的消息也属于未提交消息。也就是说,高水位上的消息是不能被消费者消费的。
主要作用
定义消息可见性,即用来标识分区下的哪些消息是可以被消费者消费的。
帮助 Kafka 完成副本同步
LogEndOffset
offset内部原理
原理图
位移提交
自动提交
相关参数
enable.auto.commit
auto.commit.interval.ms
提交的时机
存在的问题
数据丢失
重复消费
手动提交
参数配置
设置 enable.auto.commit 为 false
提交方式
同步提交
存在的问题
同步操作,即该方法会一直等待,直到位移被成功提交才会返回
异步提交
存在的问题
不会自动重试
当消费者异常关闭或者触发了再均衡前,如果偏移量还未提交就会造成偏移量丢失
解决
解决方案
分区级别提交造成的数据重复
解决方法
异步和同步提交相结合
精细化提交(分批提交)
再平衡监听器提交
Rebalance 可能导致数据重复消费
对于Kafka而言,从poll方法返回消息的那一刻开始这条消息已经算是“消费”完成了
实现ConsumerRebalanceListener 接口
1、初始化消费者
2、实现监听接口
3、运行程序
无论是同步提交还是异步提交都会造成消息丢失或重复
位移提交的异常处理-CommitFailedException(优化点)
原因:消息的处理时间超长
避免因处理超时导致的ReBanlance情况采取的措施
缩短单条消息处理的时间
增加 Consumer 端允许下游系统消费一批消息的最大时长
减少下游系统一次性消费的消息总数
下游系统使用多线程来加速消费
自动提交会不会发生这样的情况
消费者位移重设
位移维度
Earliest
Latest
Current
Specified-Offset
hift-By-N
时间维度
DateTime
Duration
位移重设的方式
代码实现
Offset Commit提交过程
消费端
broker端
Offset Fetch获取过程
消费端
broker端
Compact 策略
索引及日志文件
文件存储机制
每个分区就对应一个Log对象,在物理磁盘上则对应于一个子目录
日志段是Kafka保存消息的最小载体
kafka利用分段+索引的方式来解决查找效率问题
参数log.segment.bytes
限定了每个日志段文件的大小,最大为1GB。
超过该限制会进行日志切分滚动log rolling
active log segment:正在被写入的日志
ConcurrentSkipListMap:跳表-索引段
Message结构
offset
消息大小
消息体
索引机制
分类
偏移量索引文件
格式
index文件
如何通过offset找到对应的消息?
时间戳索引文件
查找
查找原理
格式
索引项:稀疏索引
索引项间隔:log.index.interval.bytes
索引文件以稀疏索引的方式来构建
稀疏索引是通过MappedByteBuffer将索引文件映射到内存中(pageCache),加快索引的查询速度
索引文件排序
按照位移/时间戳升序排序
用二分法查找索引,时间复杂度是O(logN)
检索原理
索引段:ConcurrentSkipListMap
ConcurrentSkipListMap的方法
索引项:稀疏矩阵
MMAP(MappedByteBuffer)
有限内存加载所有segment?
检索整体流程图
日志定位过程
例子
日志切分
每个LogSegment中的日志数据文件大小均相等
消息⽇志清理
两种⽇志清理策略
⽇志删除
⽇志删除策略
基于时间
删除时机
删除过程
基于⽇志⼤⼩
删除时机
删除过程
基于偏移量
删除时机
删除过程
⽇志压缩
⽇志压缩策略
参数配置
图示
⽇志压缩过程
⽇志压缩原理
改进后的二分法
log文件存储格式
offset index
传统二分法源码
问题(pageCache)
改进后的二分法
源码
效果
为什么设置热区大小为8192字节
副本同步机制
高可靠性
概念
AR(Assigned Repllicas)
ISR(In-Sync Replicas)
ISR是AR中的一个子集
OSR(Out-Sync Relipcas)
公式:AR = ISR + OSR
高水位
作用主要
定义消息可见性
帮助 kafka 完成副本机制的同步
三种角色
leader 副本
相应 clients 端读写请求的副本
Follower 副本
被动的备注 leader 副本的内容,不能响应 clients 端读写请求
ISR 副本
包含了 leader 副本和所有与 leader 副本保持同步的 Followerer 副本
LEO
HW
图示
repcation机制
ISR机制
ISR (In-Sync Replicas):副本同步队列
延迟
replica.lag.time.max.ms:延迟时间
replica.lag.max.messages:延迟条数
ISR机制选择
最后选择了时间,去掉消息数差异
replica.lag.time.max.ms理解
follower故障及leader故障
follower故障
leader故障
副本不同的异常情况
如果leader crash时,ISR为空怎么办?
unclean.leader.election
true(默认)
false
HW和LEO更新机制
高水位更新机制
远程副本的主要作用
运行过程中哪些数据会发生变更
更新部分
不会更新部分
更新时机
follower和leader更新follower的LEO的时间
follower的LEO更新时间
leader端的follower副本的LEO更新时间
leader 副本和 Follower 副本更新流程
更新流程图
follower默认每500ms从leader拉取一次数据
follower同步成功后也会给leader发送ack
副本同步机制举例
1、初始状态
2、第一次同步
1、Leader 副本处理生产者的逻辑
2、Leader 副本处理 Follower 副本拉取消息的逻辑
3、Follower 副本从 Leader 拉取消息的处理逻辑
经过这一次拉取,我们的 Leader 和 Follower 副本的 LEO 都是 1,各自的高水位依然是0,没有被更新。
3、第二次同步
1、Leader 副本处理 Follower 副本拉取消息的逻辑
2、Follower 副本从 Leader 拉取消息的处理逻辑
至此,一次完整的消息同步周期就结束了。事实上,Kafka 就是利用这样的机制,实现了 Leader 和 Follower 副本之间的同步。
HW保证消费者消费数据一致性,是否丢数据由ack保证。(重点)
副本同步过程中一致性保证(重点)
单纯的多副本可以保证kafka高可用,但是并不能保证kafka数据的不丢失
如果要保证写入kafka的数据不丢失
同步过程中数据丢失/不一致 - Leader Epoch
为什么Kafka需要Leader Epoch?
Kafka通过Leader Epoch来解决follower日志恢复过程中潜在的数据不一致问题
问题前提
高水位(High Watermark)
副本策略(ISRs)
有一个前提:min.isr设置的是1
问题分析
场景一:日志丢失问题
第1步状态
第2步状态:A重启了
第3步状态:B崩溃了
问题在哪里?
场景二:日志错乱问题
第1步状态
第2步状态
第3步状态
问题在哪里?
ISRs中选出的leader一定是安全(包含所有已提交数据)的吗?
Leader Epoch的引入
leader epoch
KIP-101引入如下概念
Leader Epoch解决方案
场景一
如果发起LeaderEpochRequest的时候 B 就已经挂了怎么办?
场景二
不保证数据不丢失,只保证副本间一致性
leader后不会截断自己的日志,日志截断只会发生在follower身上
Kafka Broker 写入数据的过程
隐患:如果数据写入 PageCache 后 Kafka Broker宕机会怎样?机子宕机/掉电?
Kafka Broker 宕机: 消息不会丢失
机子宕机/掉电: 消息会丢失
拓展:Kafka 日志刷盘机制
推荐采用默认值,即不配置该配置,交由操作系统自行决定何时落盘,以提升性能。
相关配置
针对 broker 配置
针对 topic 配置
查看 Linux 后台线程执行配置
保证数据可靠性(重点)
哪些环节可能丢消息?
producer可靠性
生产者发送消息一般流程
Producer丢失消息
发生在生产者客户端
几个解决的思路
发生在消息发送过程中
生产端发送消息流程
此环节丢失消息的场景
Producer消息没有发送成功
不恰当配置
回顾下重要的参数: acks
acks=0
acks=1
ack=all / -1
Acks=all 就可以代表数据一定不会丢失了吗?
数据重复
解决办法:幂等性
幂等原理
broker端可靠性
Kafka Broker 写入数据的过程数据丢失
pageCache刷盘触发条件
主动调用sync或fsync函数
可用内存低于阀值
dirty data时间达到阀值
理论上,要完全让kafka保证单个broker不丢失消息是做不到的,只能通过调整刷盘机制的参数缓解该情况。比如,减少刷盘间隔,减少刷盘数据量大小。时间越短,性能越差,可靠性越好(尽可能可靠)
主从同步数据丢失
副本之间的数据同步也可能出现问题
解决方案:ISR 和 Epoch 机制
对应需要的配置参数如下
1、acks=-1 或者 acks=all
2、replication.factor >= 3
3、min.insync.replicas > 1
consumer可靠性
自动提交
自动提交存在的问题
数据丢失
重复消费
手动提交
手动同步提交存在的问题
手动异步提交存在的问题
手动提交会出现数据重复
消息堆积造成数据丢失
解决措施
怎么确保消息 100% 不丢失?
生产端
设置重试:props.put("retries", "10")
设置acks=all
设置回调:producer.send(msg, new CallBack(){...})
Broker
内存:使用带蓄电池后备电源的缓存cache
Kafka 版本 0.11.x 以上:支持 Epoch 机制
replication.factor >= 3: 副本数至少有 3 个
min.insync.replicas > 1: 代表消息至少写入 2个副本才算发送成功。前提需要 acks=-1
unclean.leader.election.enable=false: 防止不在 ISR 中的 Follower 被选举为 Leader
消费端
客户端版本升级至0.10.2 以上版本
取消自动提交auto.commit = false,改为手动 ack
尽量提高客户端的消费速度,消费逻辑另起线程进行处理
幂等生产者
原理
注意问题
只能保证单分区上的幂等性
只能实现单会话上的幂等性
想实现多分区(partition)以及多会话(session)上的消息无重复,应该怎么做呢?
事务(transaction)
事务
Kafka为什么要引入事务
1、跨会话的幂等性写入
2、跨会话的事务恢复
3、跨多个 Topic-Partition 的幂等性写入
幂等性不能跨多个分区运作,而事务可以弥补这个缺陷。
前面3个是针对producer的,Consumer 端难以保证事务性
事务性保证
拒绝僵尸实例(Zombie fencing)
Kafka中的事务特性主要用于以下两种场景
1、生产者发送多条消息可以封装在一个事务中,形成一个原子操作
2、read-process-write模式:将消息消费和生产封装在一个事务中,形成一个原子操作
使用示例源码
事务性要解决的问题
在写多个 Topic-Partition 时,执行的一批写入操作,有可能出现部分 Topic-Partition 写入成功,部分写入失败(比如达到重试次数),这相当于出现了中间的状态,这并不是我们期望的结果;
Producer 应用中间挂之后再恢复,无法做到 Exactly-Once 语义保证(幂等性无法保证重启后精准一次性);
事务性实现的关键
1、事务原子性:2PC
2、TransactionCoordinator高可用
3、Producer 在 Fail 恢复后操作
4、如何标识一个事务操作的状态
事务性的整体流程
1. Finding a TransactionCoordinator
2. Getting a PID
3. Starting a Transaction
4. Consume-Porcess-Produce Loop
5.Committing or Aborting a Transaction
思考
如果多个 Producer 使用同一个 txn.id 会出现什么情况?
Consumer 端如何消费事务数据?
Consumer 的消费策略
read_committed
read_uncommitted
Last Stable Offset(LSO)
Server 处理 read_committed 类型的 Fetch 请求?
这种机制有没有什么问题呢?
Consumer 如何过滤 abort 的事务数据
方案
Consume过滤abort
1、如果这个数据是 control msg(也即是 marker 数据)
2、如果这个数据是正常的数据
3、检查abortedProducerIds队列
Consumer 消费数据时,其顺序如何保证
如果 txn.id 长期不使用,server 端怎么处理?
消息有序性
全局有序
如何保证:需要1个Topic只能对应1个Partition
consumer也要使用单线程或者保证消费顺序的线程模型
局部有序
不增加partition数量的情况下想提高消费速度
消息重试对顺序消息的影响
max.in.flight.requests.per.connection
不设置该参数,失败记录捕获后自行处理(优化点)
控制器组件(Controller)
控制器是如何被选出来的?
启动时选举
leader异常选举
控制器是做什么的?
1、主题管理(创建、删除、增加分区)
2、分区重分配
3、Preferred 领导者选举
4、集群成员管理(新增 Broker、Broker 主动关闭、Broker 宕机)
5、数据服务
控制器保存了什么数据?
这里面比较重要的数据有
所有主题信息
所有 Broker 信息
所有涉及运维任务的分区
控制器故障转移(Failover)
控制器故障转移的过程
epoch防止脑裂
每个和控制器交互的请求都会携带controller_epoch字段
分区Leader的选举
消费组Leader的选举
PageCache
概念
基于两个因素进行缓存
1、磁盘访问的速度比内存慢好几个数量级(毫秒和纳秒的差距);
2、被访问过的数据,有很大概率会被再次访问。
PageCache文件读写流程
读Cache
写Cache
触发脏数据刷新到磁盘的条件
超时
脏数据占用内存空间过大
Buffer cache
page cache与buffer cache作用
两类缓存的逻辑关系(PageCache 和 Buffer cache)
第一阶段:仅有Buffer Cache
第二阶段:Page Cache、Buffer Cache两者并存
Page Cache仅负责其中mmap部分的处理,而Buffer Cache实际上负责所有对磁盘的IO访问。
冗余存储
第三阶段:Page Cache、Buffer Cache两者融合
两者的关系
不适应大文件
带来 2 个问题
解决方案
零拷贝
写数据用mmap
读操作用sendfile
CommitFailedException异常怎么处理?
处理的总时间超时
解决方法
1、缩短单条消息处理的时间
2、增加 Consumer 端允许下游系统消费一批消息的最大时长
3、减少下游系统一次性消费的消息总数
4、下游系统使用多线程来加速消费
综合以上这 4 个处理方法,推荐你首先尝试采用方法 1 来预防此异常的发生
Standalone Consumer独立消费者group.id冲突
扩容
0 条评论
下一页
为你推荐
查看更多