分布式架构
Broker(服务端)设计
1)无状态
2)高性能
负载均衡实现
订阅的实现方式
一、分布式架构
四个角色:producer, broker, consumer, zookeeper
broker: 即server。存放消息的服务器
broker: shared nothing
producer向某个topic发布消息,consumer订阅某个topic的消息
二、Zookeeper
1、分布式数据管理与协调系统
配置管理/集群管理/分布式锁/。。。
类似文件系统树状结构来存储数据
2、在qbus系统中,zookeeper用来管理
所有broker的信息
所有topic的meta信息
所有consumer信息
消息的消费状态
三、Broker
1、传统Broker的实现需要维护
每条消息消费状态
Consumer的信息
每条消息消费完后删除
2、QbusBroker特点——无状态
接收producer发来的消息,持久化存储,接收consumer的请求
以topic来进行消息管理,每个topic包含多个part(ition)
一个Topic即一个队列,存储同类型的消息
多partition用来增加consumer的并发度
3、Broker中消息存储结构
Partition中的消息如何删除?
每个partition对应一个逻辑log,由多个segment组成
segment以第一条消息在这个partition中offset为文件名
新的消息追加到最后一个segment文件末尾
offset即为消息id,由id可直接定位到消息的存储位置
定期以Segment为单位删除消息
4、broker的高性能
顺序读写磁盘效率很高
顺序读/写速度> 300MB/s
写消息Append代价为O(1)
从指定位置offset读消息代价O(1)
性能与消息总量无关
zero-copy
支持消息批量处理
支持压缩
5、zero-copy
传统读-发送步骤
read(fileDesc, buf, len);
send(socket, buf, len);
代价
2次拷贝
2次系统调用
zero-copy技术
sendfile(intout_fd, intin_fd, off_t*offset, size_tcount);
代价
1次拷贝
1次系统调用
比read-send方式节省60 -70%时间
四、Producer
发送方式
layer-4 load balancing ——完全随机选择broker与partition
zookeeper-based load balancing ——指定发送到broker-partition
五、Consumer
M个partition如何被N个consumer消费?
如何保证每条消息消费仅消费一次?
Broker变动
Consumer变动
Consumer负载均衡
1)每个分区只能被一个消费者消费
2)多余的消费者不参与消费
3)当分区数目(n)大于消费者数目(m)的时候,则有n%m个消费者需要额外承担1/n的消费任务。
4)n足够大的时候,仍然可以认为负载平均分配
Consumer消费过程
每个partition消费到的位置(offset)保存在zookeeper上
每条消息的消费状态由partition的offset来决定
实现订阅方式
一种消息有多个业务逻辑来消费多次怎么办?
使用Group
每个消费组在zookeeper上有自己独立的一份partition消费的offsets
设计理念
将broker逻辑适当转移到consumer,使broker非常简单高效