这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天
作用
应用场景
- 异步
- 削峰
- 解耦
- 消息通讯
常用
- Kafka
- RocketMQ
- Pulsar
- BMQ
Kafka
使用场景
- 搜索服务
- 直播服务
- 订单服务
- 支付服务
使用流程
创建集群、新增Topic、编写生产者逻辑、编写消费者逻辑
ZooKeeper
负责集群元数据的管理、控制器的选举等
基本概念
- Topic 逻辑队列
- Cluster 物理集群
- Producer 生产者
- Consumer 消费者
- ConsumerGroup 消费者组,每一个分区只能被一个消费组中的一个消费者所消费
Topic
一个消息中间件可能由多个队列,生产者和消费者需要知道处理那个队列,给队列取名字,Topic,不同Topic可以建立不同的Topic
- Broker 一台Kafa服务器
- partition 对Topic的分区(存储上可以看作是一个可追加的日志文件),提高topic的吞吐量,实际上的partition会分布在不同的broker中
- offset 消息在partition内的位置,消息被追加到分区日志文件的时候都会分配一个特定的offset,offset是消息在分区中的唯一标识,Kafka用它保证消息在分区内的顺序性
- Replica 每个分片有多个Replica 副本,分区中所有副本称为AR,所有与leader副本保持一定程度同步的副本组成ISR(包括leader),与leader副本同步滞后过多的副本OSR
- HW 高水位,标识了一个特定的消息offset,消费者只能拉取到这个offset之前的消息
- LEO 标识当前日志文件中吓一跳待写入消息的offset,分区ISR中每个副本会维护自身的LEO,ISR中最小的LEO即为分区的HW
Broker 传统数据拷贝
磁盘空间->内核空间->应用空间
磁盘->Read Buffer->Application Buffer->Socket Buffer->NIC Buffer->消费者进程
Borker 零拷贝
磁盘->Read Buffer->NIC Buffer->消费者进程
consumer
消息接收端
解决partition在consumer中的分配:
- 手动分配,由业务决定;缺点:consumer挂掉,新建consumer困难
- 自动分配 High Level,由一个协调者coordinator
Consumer Rebalance
帮助自动分配
高可用-分布式分区出问题?ISR
一个Topic中的数据在不同partition上,kafka会把这些partition做备份(分布于不同的broker中)。
partition分为主分区和备份分区,主分区用于读写,备份分区只做备份,若主分区Broker挂了,那么会选举其他的Broker来作为主分区,实现高可用。
为何能支持高吞吐
- Producer:批量发送可以减小IO;数据压缩,通过压缩,减少消息大小,目前支持:Snappy、Gzip、LZ4、ZSTD
- Broker:顺序写,减小磁盘的寻道时间,零拷贝
- 偏移量索引文件 二分查找
- 时间戳索引文件 在offset层加一层二级索引
消费者分区分配策略
RangeAssignor、roundrobinAssigntor、StickyAssignor
存储视图
缺点
- 系统复杂性高
- 数据一致性:分布式服务的问题,但是消息队列使这个问题暴露更严重,可用分布式事务解
- 可用性:中间件MQ可能会挂
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖Page Cache
- Controller和Cooridinator和Broker在同一进程中,大量IO会造成其性能下降
重启操作
- 关闭、重启
- Leader切换,追赶数据
- 数据同步完成
- Leader回切
BMQ
兼容Kafka协议,存算分离,云原生消息队列,在重启、替换、扩缩容方面有速度优势
Broker
Partition状态机
保证对于任意分片在同一时刻只能在一个Broker上存活
写文件
先写入Buffer再写入磁盘
写文件Failover
写文件失败:...
泳道Topic
解决主干泳道流量隔离问题以及泳道资源重复创建问题
Databus
- 配置简单(相比于SDK)
- 支持动态配置,更改配置不需要停服务
Mirror
通过最终一致的方式,解决跨域读写问题
Index
Parquet
RocketMQ
基于低延时场景,实时业务使用较多
- Tag
- ConsumerQueue:分区