从Kafka到Pulsar | 青训营笔记

299 阅读9分钟

这是我参与「第四届青训营 」笔记创作活动的第6天

消息队列

1.消息队列应用场景

MQ消息通道

异步解耦 削峰填谷 高可用 发布订阅

Snipaste_2022-08-04_20-15-51.jpg

EventBridge数据总线

  • 事件源:将云服务、自定义应用、SaaS应用等应用程序产生的事件消息发布到事件集。
  • 事件集:存储接收到的事件消息,并根据事件规则将事件消息路由到事件目标。
  • 事件目标:消费事件消息。 Snipaste_2022-08-04_20-17-37.jpg

Data Platform流数据平台

Snipaste_2022-08-04_20-18-53.jpg

  1. 提供批/流数据处理能力
  2. 各类组件提供各类Connect
  3. 提供Streaming/Function能力
  4. 根据数据schema灵活的进行数据预处理

2.主流消息队列的相关介绍

Snipaste_2022-08-04_20-20-27.jpg

Kafka

1.架构介绍

Snipaste_2022-08-04_20-21-46.jpg

Zookeeper

Snipaste_2022-08-04_20-23-15.jpg

  • 选举机制: Paxos机制
  • 提供一致性:写入(强一致性),读取(会话一致性)
  • 提供可用性:一半以上节点存活即可读写
  • 提供功能:watch 机制,持久/临时节点能力

Broker角色

Snipaste_2022-08-04_20-25-39.jpg

  • 若干个 Broker节点组成 Kafka集群
  • Broker作为消息的接收模块,使用React 网络模型进行消息数据的接收。
  • Broker作为消息的持久化模块,进行消息的副本复制以及持久化
  • Broker 作为高可用模块,通过副本间的Failover进行高可用保证

Controller

Snipaste_2022-08-04_20-27-52.jpg Controller选举:

  • Broker启动会尝试去zk中注册controller节点。
  • 注册上controller节点的broker即为controller
  • 其余 broker 会 watch controller节点,节点出现异常则进行重新注册

Snipaste_2022-08-04_20-30-36.jpg Controller作用:

  • Broker 重启/宕机时,负责副本的Failover切换
  • Topic创建/删除时,负责Topic meta信息广播
  • 集群扩缩容时,进行状态控制
  • Partition/Replica状态机维护

Coordinator

Snipaste_2022-08-04_20-32-09.jpg 负责topic-partition <-> consumer的负载均衡
根据不同的场景提供不同的分配策略

  • Dynamic Membership Protocol
  • Static Membership Protocol
  • Incremental Cooperative Rebalance

2.Kafka高可用

可用性定义
Snipaste_2022-08-04_20-34-04.jpg
Kafka实现高可用:

  1. 副本同步机制:
    • 提供lsr副本复制机制,提供热备功能
    • 写入端提供ack=0,-1,1机制,控制同步强弱
  2. 副本切换机制:
    • 提供clean/unclean副本选举机制

Kafka副本ISR机制

Snipaste_2022-08-04_20-39-39.jpg

  1. AR
    • Assign Replica,已经分配的所有副本
  2. OSR
    • Out Sync Replica
    • 很久没有同步数据的副本
  3. ISR
    • 一直都在同步数据的副本.可以作为热备进行切换的副本
    • min.insync.replicas最少isr数量配置

Kafka 写入ACK机制

  • Ack = 1
    • Leader副本写入成功,Producer 即认为写成功
  • Ack = 0
    • OneWay模式
    • Producer发送后即为成功
  • Ack = -1
    • ISR中所有副本都成功,Producer才认为写成功

Kafka如何保证消息不丢

Kafka副本同步

Snipaste_2022-08-04_20-46-13.jpg

  • LEO
    • Log End Offset,日志最末尾的数据
  • HW
    • ISR中最小的 LEO作为 HW
    • HW的消息为Consumer可见的消息

Kafka副本选举

Snipaste_2022-08-04_20-49-00.jpg

  • Clean选举
    • 优先选取Isr中的副本作为leader
    • 如果lsr中无可用副本,则partition不可用
  • Unclean选举
    • 优先选取 Isr中的副本作为leader
    • 如果lsr中无可用副本,则选择其他存活副本

3. Kafka集群扩缩

Snipaste_2022-08-04_20-51-33.jpg

Kafka集群扩缩容之后的目标

  • Topic维度
    • partition在各个broker 之间分布是均匀的
    • 同一个partition 的replica不会分布在一台broker
  • Broker维度
    • Broker 之间replica的数量是均匀的

Kafka集群扩容步骤

  • 扩容 Broker节点
    • Leader副本写入成功,Producer即认为写成功
  • 计算均衡的Replica分布拓扑
    • 保证Topic的partition在broker间分布均匀
    • 保证Broker 之间Replica分布均匀
  • Controller负责新的副本分布元数据广播
    • Controller将新的leader/follower 信息广播给broker
  • Broker负责新副本的数据同步
    • Broker上有需要同步数据的副本则进行数据同步
  • 计算均衡的Replica分布拓扑
    • 保证Topic的partition在 broker间分布均匀
    • 保证 Broker之间Replica分布均匀
  • Controller负责新的副本分布元数据广播
    • Controller将新的leader/follower信息广播给broker
  • Broker负责新副本的数据同步
    • Broker 上有需要同步数据的副本则进行数据同步
  • 下线缩容的Broker节点
    • 数据同步完毕之后下线缩容的 Broker节点

Kafka集群扩缩容问题

  • 扩缩容时间长
    • 涉及到数据迁移,在生产环境中一次扩缩容可能要迁移TB甚至PB的数据
  • 扩缩容期间集群不稳定
    • 保证数据的完整性,往往会从最老的数据进行同步,这样会导致集群时刻处于从磁盘读取数据的状态,disk/net/cpu负载都会比较高
  • 扩缩容期间无法执行其他操作
    • 在一次扩缩容操作结束之前,无法进行其他运维操作(扩缩容)

4.Kafka未来演进之路

Snipaste_2022-08-04_20-58-47.jpg

Kafka去除zk依赖

依赖ZooKeeper存在问题:

  • 元数据存取困难
    • 元数据的存取过于困难,每次重新选举的controller需要把整个集群的元数据重新restore,非常的耗时且影响集群的可用性
  • 元数据更新网络开销大
    • 整个元数据的更新操作也是以全量推的方式进行,网络的开销也会非常大。
  • 强耦合违背软件设计原则
    • Zookeeper对于运维来说,维护Zookeeper也需要一定的开销,并且kaika强耦合与zk也并不好,还得时刻担心zk的宕机问题,违背软件设计的高内聚,低耦合的原则。
  • 网络分区复杂度高
    • Zookeeper本身并不能兼顾到broker与broker之间通信的状态,这就会导致网络分区的复杂度成几何倍数增长.
  • 并发访问k问题多
    • Zookeeper本身并不能兼顾到broker与broker之间通信的状态,这就会导致网络分区的复杂度成几何倍数增长。

Kafka依赖KRaft

  • Process.Roles = Broker
    • 服务器在KRaft模式下充当BrokerProcess
  • Roles = Controller
    • 服务器在KRaft模式下充当Controller
  • Process.Roles = Broker,Controller
    • 服务器在KRaft模式下充当Broker和Controlle
  • Process.Roles = null
    • 那么集群就假定是运行在ZooKeeper模式下。

Pulasr

1.架构介绍

Snipaste_2022-08-04_21-03-58.jpg Pulsar客户端连接集群的两种方式

  • Pulsar Client -> Broker
  • Pulsar Client -> Proxy

Pulsar Proxy

Snipaste_2022-08-04_21-05-13.jpg

Pulsar Proxy的作用及应用场景

  • 部分场景无法知道Broker地址,如云环境或者Kubernetes 环境
  • Proxy提供类似GateWay代理能力,解耦客户端和Broker,保障Broker安全

Pulsar Broker

Snipaste_2022-08-04_21-08-22.jpg

  • Pulsar Broker 无状态组件,负责运行两个模块
    • Http服务器
      • 暴露了restful接口,提供生产者和消费者topic查找api
    • 调度分发器
      • 异步的tcp服务器,通过自定义二进制协议进行数据传输
  • Pulsar Broker作为数据层代理
    • Bookie通讯
      • 作为Ledger代理负责和Bookie进行通讯
  • 流量代理
    • 消息写入Ledger存储到Bookie
    • 消息缓存在堆外,负责快速响应

Pulsar Storage

Snipaste_2022-08-04_21-10-45.jpg

  • Pulsar数据存储Segment在不同存储中的抽象
    • 分布式Journal系统(Bookeeper)中为Journal/Ledger
    • 分布式文件系统(GFS/HDFS)中为文件
    • 普通磁盘中为文件
    • 分布式 Blob存储中为 Blob
    • 分布式对象存储中为对象
  • 定义好抽象之后,即可实现多介质存储

Snipaste_2022-08-04_21-12-32.jpg

  • L1(缓存):
    • Broker使用堆外内存短暂存诸消息
    • 适用于Tail-Read读场景
  • L2(Bookkeeper):
    • Bookkeeper使用Qurom写,能有效降低长尾,latency低
    • 适用于Catch-Up较短时间内的较热数据
  • L3(S3等冷存):
    • 存储成本低,扩展性好
    • 适用于Catch-Up长时间内的冷数据

Pulsar IO连接器

Snipaste_2022-08-04_21-14-21.jpg

  • Pulsar lO分为输入(Input)和输出(Output)两个模块,输入代表数据从哪里来,通过Source实现数据输入。输出代表数据要往哪里去,通过 Sink 实现数据输出。
  • Pulsar提出了IO(也称为Pulsar Connector),用于解决Pulsar与周边系统的集成问题,帮助用户高效完成工作。
  • 目前Pulsar IO支持非常多的连接集成操作:例如HDFS、Spark、Flink、Flume、ES、HBase等。

Pulsar Functions(轻量级计算框架)

  • Pulsar Functions是一个轻量级计算框架,提供一个部署简单、运维简单、API简单的FAAS平台。
  • Pulsar Functions提供基于事件的服务,支持有状态与无状态的多语言计算,是对复杂的大数据处理框架的有力补充。
  • 使用Pulsar Functions,用户可以轻松地部署和管理function,通过function 从 Pulsar topic读取数据或者生产新数据到Pulsar topic。

2.Bookeeper

Bookeeper整体架构

Snipaste_2022-08-04_21-18-42.jpg

Bookeeper基本概念

Snipaste_2022-08-04_21-19-17.jpg

  • Ledger: BK的一个基本存储单元,BK Client的读写操作都是以Ledger为粒度的
  • Fragment: BK的最小分布单元(实际上也是物理上的最小存储单元),也是 Ledger的组成单位,默认情况下一个Ledger 会对应的一个Fragment(一个Ledger也可能由多个Fragment组成)
  • Entry:每条日志都是一个Entry,它代表一个record,每条record都会有一个对应的entry id

3.Pulsar功能介绍

Pulsar生产模式

Snipaste_2022-08-04_21-22-01.jpg

Pulsar消费模式

Snipaste_2022-08-04_21-23-59.jpg Exclusive消费模式

Snipaste_2022-08-04_21-25-20.jpg 独占订阅(Stream流模型): 独占订阅中,在任何时间,一个消费者组(订阅)中有且只有一个消费者来消费Topic中的消息。
Failover模式

Snipaste_2022-08-04_21-27-02.jpg 故障切换(Stream流模型):使用故障切换订阅,多个消费者(Consumer)可以附加到同一订阅。但是,一 个订阅中的所有消费者,只会有一个消费者被选为以订阅的主消费者。其他消费者将被指定为故障转移消费者。
Shared消费模式

Snipaste_2022-08-04_21-29-01.jpg 共享订阅(Queue队列模型):使用共享订阅,在同一个订阅背后,用户按照应用的需求挂载任意多的消费者。订阅中的所有消息以循环分发形式发送给订阅背后的多个消费者,并且一个消息仅传递给一个消费者。
Key_Shared消费模式

Snipaste_2022-08-04_21-30-30.jpg 按Key共享订阅(Queue队列模型):使用共享订阅,在同一个订阅背后,用户按照应用的需求挂载任意多的消费者。订阅中的所有消息以key-hash 发送给订阅背后的多个消费者,并且一个消息仅传递给一个消费者。

Pulsar vs Kafka

  • 存储架构
    • 存储计算分离之后带来的优劣势
    • 多层架构,状态分离之后的优势
  • 运维操作
    • 应对突发流量变化,集群扩缩容是否便捷
    • 运维任务是否影响可用性
    • 集群部署是否灵活
  • 功能特性
    • 多语言&多协议
    • 多租户管理
    • 生产消费模式
  • 生态集成