从 Kafka 到 Pulsar的数据流演进之路
这是我参与「第四届青训营」笔记创作活动的的第十二天
1.消息队列概述
消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。
1.EventBridge事件总线
事件源:将云服务、自定义应用、SaaS应用等应用程序产生的事件消息发布到事件集。
事件集:存储接收到的事件消息,并根据事件规则将事件消息路由到事件目标。
事件目标:消费事件消息。
2.Data Platform 流数据平台
- 提供批/流数据处理能力
- 各类组件提供各类 Connect
- 提供 Streaming/Function 能力
- 根据数据 schema 灵活的进行数据预处理
3.主流消息队列的相关介绍
2.Kafka 详解
1.Kafka 架构介绍
2.ZooKeeper
Kafka 存储数据:
- Broker Meta 信息(临时节点)
- Controller 信息(临时节点)
- Topic 信息(持久节点)
- Config 信息(持久节点)
- 选举机制
- Paxos 机制
- 提供一致性
- 写入(强一致性)
- 读取(会话一致性)
- 提供可用性
- 一半以上节点存活即可读写
- 提供功能
- watch 机制
- 持久/临时节点能力
3.Broker
- 若干个 Broker 节点组成 Kafka 集群
- Broker 作为消息的接收模块,使用 React 网络模型进行消息数据的接收
- Broker 作为消息的持久化模块,进行消息的副本复制以及持久化
- Broker 作为高可用模块,通过副本间的Failover 进行高可用保证
4.Controller
1.选举
- Broker 启动会尝试去 zk 中注册 controller 节点
- 注册上 controller 节点的 broker 即为 controller
- 其余 broker 会 watch controller 节点,节点出现异常则进行重新注册
2.作用
- Broker 重启/宕机时,负责副本的 Failover 切换
- Topic 创建/删除时,负责 Topic meta 信息广播
- 集群扩缩容时,进行状态控制
- Partition/Replica 状态机维护
5.Coordinator
- 负责 topic-partition <-> consumer 的负载均衡
- 根据不同的场景提供不同的分配策略
- Dynamic Membership Protocol
- Static Membership Protocol
- Incremental Cooperative Rebalance
6.Kafka 高可用
1.Kafka 副本ISR机制
- AR
- Assign Replica,以及分配的所有副本
- OSR
- Out Sync Replica,很久没有同步数据的副本
- ISR
- 一直都在同步数据的副本
- 可以作为热备进行切换的副本
- min.insync.replicas 最少 isr 数据配置
2.Kafka 写入 Ack 机制
- Ack = 1
- Leader 副本写入成功,Producer 即认为写成功
- Ack = 0
- OneWay 模式
- Producer 发送后即为成功
- Ack = -1
- ISR 中所有副本都成功,Producer 才认为写成功
3.Kafka 副本同步
- LEO
- Log End Offset,日志最末尾的数据
- HW
- ISR 中最小的 LEO 作为 HW
- HW 的消息为 Consumer 可见的消息
4.Kafka 副本选举
- Clean 选举
- 优先选取 lsr 中的副本作为 leader
- 如果 lsr 中无可用副本,则 partition 不可用
- Unclean 选举
- 优先选取 lsr 中的副本作为 leader
- 如果 lsr 中无可用副本,则选择其他存活副本
7.Kafka 集群扩缩容
- Topic 维度
- partition 在各个 broker 之间分布是均匀的
- 同一个 partition 的 replica 不会分布在一台 broker
- Broker 维度
- Broker 之间 replica 的数量是均匀的
1.扩容步骤:
- 扩容 Broker 节点
- Leader 副本写入成功,Producer 即认为写成功
- 计算均衡的 Replica 分布拓扑
- 保证 Topic 的 partition 在 broker 间分布均匀
- 保证 Broker 之间 Replica 分布均匀
- Controller 负责新的副本分布元数据广播
- Controller 将新的 leader/follower 信息广播给 broker
- Broker 负责新副本的数据同步
- Broker 上有需要同步数据的副本则进行数据同步
2.缩容步骤
- 计算均衡的 Replica 分布拓扑
- 保证 Topic 的 partition 在 broker 间分布均匀
- 保证 Broker 之间 Replica 分布均匀
- Controller 负责新的副本分布元数据广播
- Controller 将新的 leader/follower 信息广播给 broker
- Broker 负责新副本的数据同步
- Broker 上有需要同步数据的副本则进行数据同步
- 下线缩容的 Broker 节点
- 数据同步完毕之后下线缩容的 Broker 节点
3.kafka 集群扩缩容问题
- 扩缩容时间长
- 涉及到数据迁移,在生产环境中一次扩缩容可能要迁移 TB 甚至 PB 的数据
- 扩缩容期间集群不稳定
- 保证数据的完整性,往往会从最老的数据进行同步,这样会导致集群时刻处于从磁盘读取数据的状态,disk/net/cpu 负载都会比较高
- 扩缩容期间无法执行其他操作
- 在一次扩缩容操作结束之前,无法进行其他运维操作(扩缩容)
8.Kafka 未来演进之路
1.Kafka 去除 zk 依赖
依赖 ZooKeeper 存在的问题:
- 元数据存取困难
- 元数据更新网络开销大
- 强耦合违背软件设计原则
- 网络分区复杂度高
- 并发访问 zk 问题多
2.Kafka 依赖 KRaft
- rocess.Roles = Broker
- 服务器在 KRaft 模式下充当 Broker
- Process.Roles = Controller
- 服务器在 KRaft 模式下充当 Controller
- Process.Roles = Broker,Controller
- 服务器在 KRaft 模式下充当 Broker 和 Controller
- Process.Roles = null
- 集群就假定是运行在 ZooKeeper 模式下
3.Pulsar 详解
1.Pulsar 架构介绍
2.Pulsar Proxy
Pulsar 客户端连接集群的两种方式:
- Pulsar Client -> Broker
- Pulsar Client -> Proxy Pulsar Proxy 的作用及应用场景:
- 部分场景无法知道 Broker 地址,如云环境或 Kubemetas 环境
- Proxy 提供类似 GateWay 代理能力,解耦客户端和 Broker,保障 Broker 安全
3.Pulsar Broker
Pulsar Broker 无状态组件,负责运行两个模块
- Http 服务器
- 暴露了 restfull 接口,提供生产者和消费者 topic 查找 api
- 调度分发器
- 异步的 top 服务器,通过自定义二进制协议进行数据传输 Pulsar Broker 作为数据层代理
- Bookie 通讯
- 作为 Ledger 代理负责和 Bookie 进行通讯
- 流量代理
- 消息写入 Ledger 存储到 Bookie
- 消息缓存在堆外,负责快速响应
4.Pulsar Storage
Pulsar数据存储Segment在不同存储中的抽象:
- 分布式Journal 系统(Bookeeper)中为Journal/Ledger
- 分布式文件系统(GFS/HDFS)中为文件
- 普通磁盘中为文件
- 分布式 Blob存储中为Blob
- 分布式对象存储中为对象 定义好抽象之后,即可实现多介质存储
L1(缓存):
- Broker使用堆外内存短暂存储消息
- 适用于Tail-Read读场景 L2(Bookkeeper):
- Bookkeeper使用Qurom写,能有效降低长尾,latency 低
- 适用于Catch-Up较短时间内的较热数据 L3(S3等冷存):
- 存储成本低,扩展性好
- 适用于Catch-Up长时间内的冷数据
5.Pulsar lO连接器
- Pulsar lO 分为输入 (Input)和输出(Output)两个模块,输入代表数据从哪里来,通过Source 实现数据输入。输出代表数据要往哪里去,通过 Sink 实现数据输出
- Pulsar提出了IO(也称为Pulsar Connector),用于解决Pulsar与周边系统的集成问题,帮助用户高效完成工作。
- 目前Pulsar IO支持非常多的连接集成操作:例如HDFS、Spark、Flink、Flume、ES、HBase等。
6.Pulsar Functions(轻量级计算框架)
- Pulsar Functions是一个轻量级计算框架,提供一个部署简单、运维简单、API简单的FAAS平台。
- Pulsar Functions提供基于事件的服务,支持有状态与无状态的多语言计算,是对复杂的人数据处理框架的有力补充。
- 使用Pulsar Functions,用户可以轻松地部署和管理function,通过function 从 Pulsar topic读取数据或者生产新数据到 Pulsar topic。
4.Bookeeper
1.Bookeeper基本概念
- Ledger: BK的一个基本存储单元,BK Client的读写操作都是以Ledger为粒度的
- Fragment: BK的最小分布单元(实际上也是物理上的最小存储单元),也是 Ledger 的组成单位,默认情况下一个Ledger 会对应的一个 Fragment (一个Ledger也可能由多个Fragment组成)
- Entry:每条日志都是一个Entry,它代表一个record,每条record都会有一个对应的entry id
2.Bookkeeper Ledger
1.新建Bookkeeper Ledger
- nsemble size(E):一个Ledger所涉及的Bookie集合
- Write Quorum Size(Qw):副本数
- Ack Quorum Size(Qa):写请求成功需要满足的副本数
2.Bookkeeper Ledger分布
- 从Bookie Pool挑选 Bookies构成Ensemble
- Write Quorum Size决定发送给哪些Bookies
- Ack Quorum Size决定收到几个Ack即为成功
3.Bookkeeper 一致性
Bookkeeper写一致性
- LastAddPushed
- LastAddConfirmed
- Fencing避免脑裂 Bookkeeper读一致性:
- 所有的 Reader都可以安全读取 Entry ID小于或者等于LAC的记录,从而保证reader不会读取未确认的数据,从而保证了reader之间的一致性。
4.Bookkeeper读写分离
写入优化:写入时,不但会写入到Journal中还会写入到缓存(memtable)中,定期会做刷盘(刷盘前会做排序,通过聚合+排序优化读取性能)
读取优化:先读Memtable,没命中再通过索引读磁盘;Ledger Device中会维护一个索引结构,存储在RocksDB中,它会将(Ledgerld,Entryld)映射到(EntryLogld,文件中的偏移量)
5.Bookkeeper with pulsar
Topic-Partition:
- Topic由多个partition组成
- Partition由多个segment 组成
- Segment对应Ledger 特点:
- Partition <-> Broker之间只是映射关系
- Broker在扩缩容的过程中只需要更改映射即可
5.Pulsar 特性介绍
1.Pulsar生产模式
2.Pulsar消费模式
1.Exclusive消费模式
独占订阅(Stream流模型),独占订阅中,在任何时间,一个消费者组(订阅)中有且只有一个消费者来消费Topic中的消息。
2.Failover消费模式
故障切换(Stream流模型),使用故障切换订阅,多个消费者(Consumer)可以附加到同一订阅。但是,一个订阅中的所有消费者,只会有一个消费者被选为该订阅的主消费者。其他消费者将被指定为故障转移消费者。
3.Shared消费模式
共享订阅(Queue队列模型),使用共享订阅,在同一个订阅背后,用户按照应用的需求挂载任意多的消费者。订阅中的所有消息以循环分发形式发送给订阅背后的多个消费者,并且一个消息仅传递给一个消费者。
4.Key Shared消费模式
按Key共享订阅(Queue队列模型),使用共享订阅,在同一个订阅背后,用户按照应用的需求挂载任意多的消费者。订阅中的所有消息以key-hash 发送给订阅背后的多个消费者,并且一个消息仅传递给一个消费者。
3.Pulsar 多租户
- 当前支持Plugin类型
- KOP (Kafka on Pulsar)
- ROP (RocketMQ on Pulsar)
- AOP (AMQP on Pulsar)
- Mop (MQTT on Pulsar)
- 实现 Plugin需要支持的功能
- 路由查询
- Message Protocol
- Offset & Msgld
4.Pulsar vs Kafka
- 存储架构
- 存储计算分离之后带来的优劣势
- 多层架构,状态分离之后的优势
- 运维操作
- 应对突发流量变化,集群扩缩容是否便捷
- 运维任务是否影响可用性
- 集群部署是否灵活
- 功能特性
- 多语言&多协议
- 多租户管理
- 生产消费模式
- 生态集成