架构概览
在最高配置下,pulsar服务应该由一个或多个pulsar集群组成。
一个pulsar集群可以包括如下组件
- 一个或多个broker。broker会将生产者 的消息分派给消费者。与pulsar配置存储通信来协调各种任务。将消息 存储在 BookKeeper实例中 (也可以叫bookie)。并且依赖zk集群执行一些特定的任务
- 一个BookKeeper集群,由多个bookies组成。可以持久化消息(企业级分布式存储 )
- 一个zk集群。存储一些元数据 信息,在机pulsar集群中处理一些协调任务
在更高级的部署形式中,ZK还负责跨集群的协调任务,例如异地灾备
Brokers
puslar消息brokers就是 一个无状态组件。主要负责运行如下两个组件。
- 一个HTTP服务器。提供pulsar消息生产处理的一系列Rest api。
- 一个分发器,可以作为一个异步TCP服务器,采用二进制协议传输所有数据
处于性能考虑,消息通常从管理的ledger缓存中获取来分发。除非backlog(消息积压部分)超过了缓存限制,那么就会从bookKeeper中去读取
最后,为了支持全局主题的异地赋值。broker管理了一些复制器来跟踪本地区域发布的entry。然后推送到远端区域
clusters
一个pulsar服务可以由多个puslar 集群组成。一个集群由如下组成
- 一个或多个pulsar brokers
- 一个zk集群
- 一个bookie集群用于持久化消息 。
集群可以进行异地数据复制,可以参考指南 clusters
元数据存储
pulsar元数据存储维护了所有pulsar集群的元数据,例如topic,sschema,broker加载数据,等等
pulsar使用zk来进行元数据存储,集群配置,和协调管理 。可以将一个zk集群用于pulsar元数据和BookKeeper元数据存储。
pulsar当然也支持一些别的元数据存储后端服务,例如etcd 和 rocksDB(只支持standalone)。
对于一个pulsar服务来说
- 对于租户,命名空间,其他实体的存储配置是需要全局性存储的
- 每个集群都有自己本地的zk。用于存储自己该puslar集群特定的元数据,例如bk ledger元数据等。(一些不需要全局存储的数据)
configuration store
configuration store 是一个ZK的Quornums机制(分布式协议),用于配置相关的任务 ,维护了pulsar实例的所有配置。例如集群,租户,命名空间,分区主题相关配置 。同时可以在pulsar实例下跨多个集群共享配置。
持久化存储
pulsar提供了可靠消息传递,如果消息成功抵达broker,将会被传递到预期的目标。这种可靠的消息传递机制,需要存储未ACK的数据直到消息被消费者ACK。这种消息机制被 成为持久化消息传递。在pulsar中所有消息 的N个副本都存储在磁盘上并同步。
apache bookKeeper
apache bookKeeper是pulsar采用的持久化 消息方案。BookKeeper是一个分布式WAL(日志预写)系统。有如下优势
- 可以让pulsar处理多个独立的日志,成为ledgers。随着时间推移,topics下会有多个ledgers
- 为处理entry replication的顺序数据提供高效的存储
- 保证故障时的读取一致性
- 提供分布式I/O
- 存储容量和吞吐都可以水平扩展,只需要向集群添加更多的bookie
- bookie设计旨在于处理数千个ledgers并发读写。通过多个磁盘设备(一个用于日志(写日志之类的s),一个用于一般存储 )。bookies可以将读取操作的影响和写入操作的延迟隔离开来。
除了消息存储外,puslar数据游标也存储到bookKeeper中 。游标是消费者订阅的位置。BookKeeper使得pulsar可以以扩展的方式存储消费者消费的位置
broker和bookie关系
Ledgers
一个Ledger 就是一个只能追加的数据结构,同时有一个写入器被分配给了多个bookKeeper存储节点。Ledger条目可以被复制到多个bookies。 ledgers用于如下简单的语义
- 一个broker可以创建一个ledger,追加条目给ledger和关闭ledger
- ledger被关闭后,只能以只读模式打开
- 当ledger中 的数据条目不再被需要了,那么整个ledger可以被删除 。
ledger可以理解成一个日志账目,里面存储一个个日志条目。是一些日志的集合
ledger 读一致性
Bookkeeper的主要优势在于保证故障时的读一致性。由于一个ledger只能由一个单独的进程写入,那么对于ledger中 数据的添加就是非常高效的。发生故障后,ledger会进行恢复,恢复到最后提交的日志条目。恢复完后,所有ledger的读者都保证看到的是相同的内容
managed ledgers
bk的ledger提供了 一种日志抽象。因此在这之上又延申了一个叫managed ledger的东西。这个玩意就是topic的存储层。一个managed ledger代表了一个消息流的抽象,其中包含一个末尾追加的writer和多个消费者游标
在内部,一个managed ledgers使用了多个bk ledger来存储数据。原因如下:
- 如果出现错误,那么ledger会变成只读,那么就需要一个新的ledger
- 当所有游标消费完一个ledger的数据,ledger会被删除。这周期性的需要滚动ledger(提供新的,或者刷旧的?)
日志存储
在bk中,journal文件包含BookKeeper 事务日子。在对ledger更新前,对应bookie需要确保该该leger相关的更新事务已经被持久化。当一个journal文件超过journalMaxSizeMB
,就会新建一个
分层存储
pulsar分层存储 功能允许将旧的积压数据从BookKeeper移动到长期且更便宜的存储 。同时仍然允许被消费。新数据可以从内存返回。老数据就只能读数据盘
分层存储工作方式
pulsar的消息由managed ledger管理。managed ledger管理了一系列segment。pulsar只能在最后的segment追加日志。 所有之前的segments都是封闭的。
分层存储机制如下:
- 分层存储offloading机制 利用了架构上的优势。当需要offloading的 时候,日志的各个段都可以被复制到分层存储。写入分层存储的日志 所有段(除了当前段)都可以被offload
- 写入bk的数据默认复制三分给物理机器。当一个段被密封在 bk中,就是不可变的(ledger的特性,一旦关闭,就只能可读)。那么就可以复制到长期存储中。
- 在卸载ledger到长期存储前,需要为云存储服务配置存储,凭证等等
- pulsar采用 分段上传数据。上传期间brokers可能会挂掉。可以为长期存储设置生命周期规则,使得不完整的分段直接过期删除
- 在ledgers传到 长期存储后,这些长期存储里的ledgers也是可以被访问的
Pulsar proxy
pulsar broker的代理。如果采用pulsar proxy的部署方式 ,所有连接流量都会过这个代理