- 1. Apache Pulsar功能与特性
- 2. Apache Pulsar组件介绍
- 3. Pulsar与Kafka对比
- 4. Pulsar的架构
1. 多租户模式
- 租户和namespace是Pulsar支持多租户的两个核心概念
- 在租户级别,Pulsar为特定的租户预留合适的存储空间、应用授权和认证机制
- 在命名空间级别,可以调整副本设置,管理跨集群的消息复制。Pulsar还有一系列的配置策略(policy),包括存储配额、broker控制produce和consume的流量、消息过期策略和命名空间之间的隔离策略
2. 灵活的消息系统
- Pulsar在Topic级别只需保存一份数据,同一份数据可多次消费。以流式、队列等不同的订阅模型进行消息消费
- 同时pulsar通过事务实现Exactly-Once语义, 可以确保数据不丢不重
3. 云原生架构
- Pulsar使用计算与存储分离的云原生架构。上层是无状态Broker,负责消息分发和服务;下层是持久化的存储层Bookie集群,存储是分片的。
- 云原生需满足以下几个要求:
- DevOps:指的就是开发和运维不在是分开的两个团队, 而是你中有我, 我中有你的一个团队
- 微服务:指的是应用需要具备低耦合 + 高内聚
- 持续交付:指的在不影响用户使用服务的前提下, 频繁将新功能发布给用户使用, 当然这一点也是云原生中比较难以达到的
- 容器化:指的是在运维的时候, 不需要在关心每个服务所使用的技术栈, 每个服务都被无差别的封装在容器中, 可以被无差别的管理和维度, 比如目前docker和k8s
4. segmented Sreams(分片流)
- Pulsar将无界的数据看作是分片的流,分片分散存储在分层存储(tiered storage)、BookKeeper集群和Broker节点(内存)上,而对外提供一个统一的、无界数据的视图
5. 支持跨地域复制
- Pulsar中的跨地域复制,是基于复制订阅模式(Replicated-subscriptions)将Pulsar中持久化的消息在多个集群间备份。在某个集群失效情况下,该功能可以在其他集群恢复消费者的消费状态,从而达到热备模式下消息服务的高可用
1. 层级储存
- Infinite Stream: 以流的方式永久保存原始数据
- 分区的容量不再受限制
- 充分利用云存储或现有的廉价存储(例如HDFS)
- 数据统⼀表征:客户端无需关心数据究竟存储在哪⾥
2. Pulsar IO(Connector)连接器
- Pulsar IO分为输入(Input)和输出(Output)两个模块,用于解决Pulsar与周边系统的集成问题
- 目前支持非常多的连接集成操作: 例如HDFS 、Spark、Flink 、Flume 、ES 、HBase等
3. Pulsar Functions(轻量级计算框架)
- Pulsar Functions是一个轻量级的计算框架,可以给用户提供一个部署简单、运维简单、API简单的FASS(Function as a service)平台。Pulsar Functions提供基于事件的服务,支持有状态与无状态的多语言计算。通过function从Pulsar topic读取数据或者生产新数据到Pulsar topic
-
模型概念 Kafka: producer – topic – consumer group – consumer Pulsar: producer – topic - subsciption - consumer
-
消息消费模式 Kafka: 主要集中在流(Stream)模式, 对单个partition是独占消费 Pulsar: 提供了统一的消息模型和API。其中流(Stream)模式 – 独占和故障切换订阅方式;队列(Queue)模式 – 共享订阅的方式
-
消息确认(ack) Kafka: 使用偏移量offset Pulsar: 使用专门的cursor管理。累积确认和kafka效果一样; 提供单条或选择性确认
-
消息保留 Kafka: 根据设置的保留期来删除消息, 有可能消息没被消费, 过期后被删除, 不支持TTL Pulsar: 消息只有被所有订阅消费后才会删除, 不会丢失数据,. 也可以设置保留期, 保留被消费的数据。支持TTL
- Apache Kafka是以分区为存储中心,而Apache Pulsar是以Segment为存储中心
Kafka目前存在的痛点:
- Kafka很难进行扩展,因为Kafka把消息持久化在broker中,迁移主题分区时,需要把分区的数据完全复制到其他broker中
- 当需要通过更改分区大小以获得更多的存储空间时,会与消息索引产生冲突,打乱消息顺序
- 如果非ISR的副本被选为leader时,会出现消息丢失的情况
- 使用Kafka时,你需要充分规划broker、主题、分区和副本的数量,才能避免 Kafka扩展导致的问题。但很难规划好
- Kafka集群的分区再均衡会影响相关生产者和消费者的性能
- 发生故障时,Kafka主题无法保证消息的完整性
- Kafka的broker并不维护consumer的消费状态
- 如果使用率很高,则必须尽快删除旧消息,否则就会出现磁盘空间不够用的问题
- Kafka原生的跨地域复制机制(MirrorMaker)有问题
- 要想进行实时数据分析,就不得不选用第三方工具
单个Pulsar集群由以下三部分组成:
- 多个broker负责处理和负载均衡(当一个broker的负载到达一定阈值,会将要处理的消息转移到负载较小的broker)producer发出的消息,和将这些消息分派给 consumer。Broker依赖ZooKeeper集群处理特定的任务
- 多个BookKeeper负责消息的持久化存储
- 一个zookeeper集群,用来处理Pulsar集群之间的协调任务
1. Broker Pulsar的broker是一个无状态组件, 主要由两个组件组成:
- 一个HTTP服务器(service discovery), 它暴露了REST系统管理接口以及在生产者和消费者之间进行Topic查找的API
- 一个调度分发器dispatcher, 它是异步的TCP服务器,通过自定义二进制协议应用于所有相关的数据传输
消息通常从Managed Ledger缓存中读取,除非读取的数据超过缓存大小,则从BookKeeper那里读取Entries(Entry是BookKeeper中的一条记录)
为了支持全局Topic异地复制,Broker会控制Replicators追踪本地发布的Entries,并把这些Entries用Java客户端重新发布到其他区域
2. Zookeeper 使用Apache Zookeeper进行元数据存储、集群配置和协调
- 配置存储: 存储租户,命名域和其他需要全局一致的配置项
- 每个集群有自己独立的ZooKeeper保存集群内部配置和协调信息,例如归属信息、broker负载报告、BookKeeper ledger信息
3. Bookeeper 未确认送达的消息需要持久化存储直到它们被确认送达。所有消息都被保存并同步N份 bookKeeper是一个分布式的预写日志(WAL)系统
一个ledger分布在多个Bookies中,Ledger是一个只追加的数据结构,并且只有一个写入器,这个写入器负责多个bookKeeper存储节点的写入。 Ledger的Entry会被复制到多个bookies。 Ledgers的特点:
- 可以创建ledeger,添加内容到ledger和关闭ledger
- 当一个ledger被关闭后,除非明确的要写数据,ledger只会以只读模式打开
- 当ledger中的Entry不再有用的时候,整个ledger可以被删除
Pulsar使用Bookeeper的原因
- 使pulsar能够利用独立的ledgers日志
- 它为处理顺序消息提供了非常有效的存储
- 保证了多系统挂掉时Ledgers的读取一致性
- 提供不同的Bookies之间均匀的IO分布
- 它在容量和吞吐量方面都具有水平伸缩性。能够通过增加bookies立即增加容量到集群中,并提升吞吐量
- Bookies被设计成可以承载数千的并发读写的ledgers,且读写IO分离。 使用多个磁盘设备(一个用于日志,另一个用于一般存储)),这样Bookies可以将读操作的影响和对于写操作的延迟分隔开
4. Pulsar代理
Pulsar客户端和Pulsar集群交互的一种方式就是直连Pulsar brokers。有时这种直连既不可行也不可取,因为客户端并不知道broker的地址
Pulsar proxy为所有的broker提供了一个网关, 如果选择运行了Pulsar Proxy,所有的客户都会通过这个代理而不是直接与brokers通信