这是我参与「第五届青训营 」伴学笔记创作活动的第 23 天
本篇文章归档于 “第五届字节跳动青训营”,主要是为了完成和记录掘金的 “伴学笔记创作活动” 活动,如果你对我的其他文章感兴趣,可以去我的 专栏 中逛逛看有没有你想要的东西。
- 第 1 篇 - Kitex 口水话
- 第 2 篇 - Hertz 口水话
- 第 3 篇 - 微服务口水话
- 第 4 篇 - Kafka 口水话
- 第 5 篇 - BMQ 口水话
- 第 6 篇 - RecketMQ 口水话
- 第 7 篇 - 数据库口水话
- 第 8 篇 - RDBMS 口水话
- 第 9 篇 - TOS 口水话
- 第 10 篇 - tinyTikTok 环境配置
- 第 11 篇 - tinyTikTok 规范设计
- 第 12 篇 - tinyTikTok 项目管理
- 第 13 篇 - tinyTikTok 认证授权
- 第 14 篇 - tinyTikTok 服务功能
- 第 15 篇 - tinyTikTok 测试分析
- 第 16 篇 - tinyTikTok 项目总结
放在前面的话
BMQ,我猜全称是 ByteDance Message Queue,因为百度也有一个同缩写的消息队列,或许全名是 Baidu Message Queue。
Anyway,把它看作 Pulsar 的变体就好,估计都是差不多的。给个 Pulsar 的架构图,指路 官网:(实在找不到 BMQ 的官方文档,估计是内部公开(
BMQ 的架构模型
BMQ 兼容 Kafka 协议,支持存算分离,支持云原生消息队列,相对于 Pulsar:
- 新增 Proxy 层作为代理;
- Coordinator 和 Controller 可以独立部署;
- 底层新增 HDFS 用于存算分离。
因为 Proxy 和 Broker 是无状态的,因此,相对于 Kafka 来说,BMQ 的运维成本很低,能在秒级内操作。
BMQ 读写流程
BMQ 的文件写入有两个策略:
- 单个文件写入:选择 N 个副本数量的 DataNode 写入(如果有 3 个 Partition,则总共需要写 3N 个 DataNode),使单个副本随机分布在不同节点上(每次写入 3 个 DataNode,相比于 Kafka,这样能够保障负载均衡);
- Partition 状态机:保证任意 Partition 上只能存活一个 Broker。获得写入权限的 Broker 还会进行 save checkpoint,以免上一个分片是异常中断的。
如果 DataNode 挂了或者其他原因导致写操作失败,其实重新找正常节点写入就能保证可用性,因为不知道具体要恢复什么。
BMQ 的具体写入过程:
- CRC 数据校验参数是否合法;
- 校验完成后,会把数据放入 Buffer 中;
- 通过一个异步的 Write 线程将数据最终写入到底层的存储系统。
Write 线程具体写入的流程:
- 首先会将 Buffer 中的数据取出来;
- 调用底层写入逻辑,在一定的时间周期上 flush;
- 建立 Index,也就是 Offset 和 Timestamp 对于消息具体位置的映射关系;
- 进行 save checkpoint,意味着 checkpoint 后的数据是可以被消费;
- 当文件到达一定大小之后,需要建立一个新的 Segment 文件来写入。
当然,Proxy 还能为 fetch request 设置一个窗口,降低 IO,以及尝试击中缓存和多机部署。
放到最后的话
可以发现 BMQ 有很多设计巧妙的地方,可惜的是没有官方文档(