Pulsar架构
架构设计
主要由三部分组成:
- Broker集群:一个或多个Broker节点,负责接收生产者发送的消息,将消息转发给BookKeeper存储,以及将消息投递给消费者,完成负载均衡、Schema校验、Ledger自动更新、ACK管理等
- BookKeeper集群:一个或多个Bookie节点组成,负责消息持久化存储
- Zookeeper集群:负责元数据存储和节点监控
和Kafka相比优缺点
- 缺点:
- 增加网络传输性能损耗
- 架构方案比较复杂
- 优点:
- 计算层和存储层可以独立扩容,不需要进行数据迁移
- 对于弹性容器云平台非常友好
计算层
- Zookeeper存储Broker管理的元数据(租户、命名空间、主题等)
- 主题和Broker绑定,该主题的所有生产者会和这个Broker绑定(非分区主题)
- 每个消费者绑定一个订阅组
存储层
- 利用BookKeeper存储数据
- Ledger:一组数据的集合,有3个关键配置
- EnsembleSize:每个Ledger选择EnsembleSize个节点,会将该Ledger的数据分散存储到这几个节点中
- WriteQuorumSize:每个写入操作会同时发送到EnsembleSize中的WriteQuorumSize个节点中(并行写提升效率)
- AckQuorumSize:当BookKeeper生产者收到AckQuorumSize个节点返回写入成功的响应后,认为消息写入成功(可以保证BookKeeper的数据安全)
- BookKeeper实现WAL机制,设计了Journal日志,Bookie节点收到写入请求,会将数据写入Journal日志(顺序写入,性能非常高,建议使用独立的磁盘存放Journal文件,保证读写分离),然后立即返回写入成功的响应,这些数据存储到Journal日志后,BookKeeper将这些数据异步写入Ledger(支持不同的写入机制),默认使用DbLedgerStorage,定义了数据写入缓冲区,先将数据写入缓冲区,Bookie会启动一个异步线程,将缓冲区内容定时写入Ledger文件
- 缓存隔离:不同于Kafka使用PageCache作为磁盘读写的缓冲区,Pulsar使用Java进程的内存缓冲区
- 原因:PageCache在同时进行追尾读和追赶读时,历史数据和最新数据会争夺PageCache空间,造成读写响应不及时
- Pulsar定义了多个数据缓冲区,将最新数据和历史数据划分到不同的缓冲区,避免该问题
- Broker数据缓冲区:缓存Broker中最新写入的数据,追尾读可以直接从该缓冲区读数据,读取失败再通过Bookie读取历史消息
- Bookie写入缓冲区:缓存Bookie中写入的数据,读取数据时也会从该缓冲区读取数据
- Bookie读取缓冲区:追赶读从磁盘中读取历史数据时,会预先读取一部分数据存储在该缓冲区
- 使用Java缓冲区的另一个好处:方便修改缓冲区大小,缺点是可能造成数据的重复缓存
系统伸缩
- Broker扩容只需要将原来的Broker部分主题转交给新的节点即可,以bundle为单位迁移主题,不需要数据迁移
- Bookie扩容,只需要将Bookie节点添加到集群中,Broker回将新的数据写入新的Bookie节点,不需要数据迁移