- 使用消息队列时如何保证消息的顺序性及高并发
- 首先需要保证生产端的消息时有序的
- ack=-1
- max.in.flight.requests.per.connection=1
- 消费端
- 抽象出一个监听程序,负责offset的提交
- 提交连续offset的最大值
- 数据库需要支持幂等
- 做好依赖检查
- 抽象出一个监听程序,负责offset的提交
- 首先需要保证生产端的消息时有序的
- Kafka 集群线上大量消息积压怎么处理
- 增加硬件资源
- 为Consumer维护一个线程池
- 使用一个监听器提交连续的offset的最大值
- 消费线程需要支持重复消费
- 问题
- 很难保证单分区的顺序性
- 会造成重复消费,需要幂等写或者两阶段提交
- 创建一个新的Topic,增加新Topic的partition数量和消费者数量
- Kafka为什么会快
- 消息分区(partition) 提升了并行消息吞吐量
- 消息sender() 子线程是批量发送消息到PageCache当中,当一批消息发送成功之后会返回一个ACK
- 顺序写,Linux会定时将PageCache当中的flush当中,但是原有的PageCache上的数据并不会马上删除
- 每次消费者消费数据的时候,如果在PageCache存在会将文件描述信息拷贝到Socket缓冲区,将数据拷贝到网卡设备,这个过程就是零拷贝
- 如果PageCache上面不存在数据则会发起一次IO请求从硬盘上加载数据到PageCache当中,这个加载过程不仅仅是只加载需要发送的信息还会把响铃块的数据进行加载
- Kafka系统的Broker端配置
- socket.receive.buffer.bytes:102400 -> Socket接收数据大小,能够降低网络延迟成本
- 往返延迟 100ms
- 网络传输速度:10MB/s
- socket.receive.buffer.bytes * 1s /100ms > 10MB
- num.network.threads:3 网络线程数
- socket.request.max.bytes:104857600 发送到socket缓存区的请求书的大小
- queued.max.requests:请求队列的最大个数 default 500 一般设置为活跃的客户端数量
- queued.max.request.bytes:请求队列的最大长度 default -1
- num.io.thread:服务可用的IO线程数 default 8
- log.flush.interval.ms:多少时间将pageCache的数据flush到硬盘上 default null
- log.flush.interval.message: 达到多少数据的时候将pageCache的数据flush到硬盘上 default Integer.MAX_VALUE,改为1的时候就是同步flush
- num.replica.fetchers: default 1 是将leader数据同步到follower的线程数
- 假设每个broker上有20个leader 每个leader有2个副本 可以将线城数设置到40
- replica.fetch.min.bytes: 复制消息的字节数 default 1
- replica.fetch.wait.max.ms: 复制等待时间 default 500
- socket.receive.buffer.bytes:102400 -> Socket接收数据大小,能够降低网络延迟成本
- kafka 的消费模式/确认模式
- single
- 单条消费
- 手动确认
- 自动确认
- 单条消费
- batch
- 批量消费
- 手动确认
- 自动确认
- 批量消费
- 手动确认消息方法
- acknowledage:确认消息
- nack(sleepMils)
- nack(index,sleepMils)
- single
- Kafka 分区(Partition)
- Kafka会将主题划分到多个分区当中,多个订阅者会从一个或多个分区当中消费数据
- 通过分区策略的划分,实现了负载均衡和水平扩展
- 范围策略 :有是个分区 三个线程 那么就会有一个分区多个
- 轮询策略 :将数据依次发送到每个分区当中 是默认策略 有很好的负载均衡效果
- 随机策略 :随意的将消息发送到各个分区
- 按Key保存:Kafka允许为每个消息指定一个Key,并将相同Key的消息保存在同一个分区当中
- Sticky : 将一个Partiton的Batch写满之后再写下一个,能够有效提升吞吐量降低CPU(Kafka2.4之后的版本)
- 每个分区包含多个副本
- ISR机制 指能够和leader保持同步的follower+leader本身组成的集合
- 针对每个Topic维护一个ISR集合
- Kafka只会保证ISR集合中的所有副本保持完全同步
- Kafka一定会保证leader接收到消息然后完全同步给ISR当中的所有副本
- IISR保证了同步,一旦出现延迟和长时间不同步的情况就会被剔出
- 配置
- replica.lag.time.max.ms 在该事件间隔内没有同步就会被提出
- replica.lag.max.message 消息条数配置在0.9版本之后已经被剔除
- Kafka会在ISR机制的集合当中针对副本进行竞选,在选举成功的leader上进行消息的增删,其他副本上进行同步,因此我们至少需要三个副本在leader失败后能有一主一副来保证可用性
- ISR机制 指能够和leader保持同步的follower+leader本身组成的集合
- 延时队列
- KafKa
- 当消费者消费时还没有达到延时时间的消息再回写回partition中
- 精确度不高
- 基于时间轮实现
- TimingWheel
- TimerTaskList
- TimerTaskEntry
- TimerTaskQueue
- DelayQueue+Kafka
- 把消息划分延时等级储存到DelayQueue
- 发送到期消息到Kafka
- 消费者消费
- RocksDB + Kafka
- 延时消息模块RocksDB
- 当消费者消费时还没有达到延时时间的消息再回写回partition中
- RabbitMQ
- 死信队列
- KafKa
- Kafka为什么会快-PageCache
- 生产者生产消息的时候会按照偏移量使用pwrite()的系统调用写入到PageCache当中
- 消费者在消费数据的时候会使用sendfile()的系统调用,零拷贝的将数据从pageCache传输到broker的socketBuffer当中进行网络传输
- 同样的在leader/fellower,只要leader/follower之间处于ISR机制当中,也会采用想用相同的方式将数据从leader的broker同步到follower的broker当中
- pageCache的数据会随着内核当中的flusher线程调度写到磁盘当中,当消费者需要消费的数据不在pageCache当中的时候才回去磁盘当中获取并拿出相邻的块放入到pageCache当中方便下次读取
- 总结:在整个消息传递的过程当中,几乎只会对pageCache进行读写,很少的进行磁盘范问。其次,Kafka的持久化是追加顺序写,充分利用了磁盘的顺序访问快的特点
- log.flush.interval.ms: 多少时间将pageCache的数据flush到硬盘上 default null
- log.flush.interval.message: 达到多少数据的时候将pageCache的数据flush到硬盘上 default Integer.MAX_VALUE,改为1的时候就是同步flush
Kafka 一些基本原理
最新推荐文章于 2025-09-17 16:51:13 发布
文章讨论了如何在使用Kafka时确保消息的顺序性和处理高并发场景。关键点包括限制生产者并发度,使用监听程序管理offset提交,处理消息积压,优化Broker配置以及理解Kafka的PageCache机制以提高性能。同时,介绍了Kafka的分区策略、ISR机制和延时队列的实现方式。

173

被折叠的 条评论
为什么被折叠?



