这是我参与「第五届青训营 」伴学笔记创作活动的第 32 天
BMQ
BMQ简介
兼容Kafka协议,存算分离,云原生消息队列
BMQ架构图
运维操作对比
HDFS写文件流程
之前知道了同一个副本是由多个segment组成,那BMQ对于单个文件的写入机制是怎么样的?
首先客户端写入前会选择一定数量的DataNode,这个数量是副本数,然后将一个文件写入到这三个节点上,切换到下一个segment之后,又会重新选择三个节点进行写入。这样一来,对于单个副本的所有segment来讲,会随机分配到分布式文件的整个集群中
BMQ文件结构
对于Kafka分片数据的写入,是通过先在Leader上面写好文件,然后同步到Follwer上,所以对于同一个副本的所有segment都在同一台机器上面。就会存在之前我们所说到的单分片过大导致不均衡的问题,但在BMQ集群中,因为对于单个副本来讲,是随机分配到不同的节点上面的,因此不会存在Kafka的负载不均衡
Broker-Partition状态机
对于写入的逻辑来讲,还有一个状态机的机制,用来保证不会同时出现同一个分片在两个Broker上同时启动的情况,另外也能保证一个分片的正常运行。首先,Controller做好分片的分配之后,如果在该Broker分配到了Broker,首先会start这个分片,然后进入Recover状态,这个状态主要有两个目的,获取分片写入权利,也就是说,对于hdfs来讲,只会允许我一个分片进行写入,只有拿到这个权利的分片我才能写入,第二个目的是如果上次分片是异常中断的,没有进行save checkpoint,这里会重新进行一次save checkpoint,然后就进入了正常的写流程状态,创建文件,写入数据,到一定大小之后又开始建立新的文件进行写入
Broker写文件流程
数据校验:CRC,参数是否合法,
校验完成后,会把数据放到buffer中,通过一个异步的Write Thread线程将数据最终写入到底层的存储系统当中
这里需要注意的是,对于业务的写入来说,可以配置返回方式,可以在写完缓存之后直接返回,另外也可以数据真正写入存储系统后再返回,对于这两个来说,前者损失了数据的可靠性,提高了吞吐性能的优势,因为只写入内存是比较快的,但是如果下一次flush前发生宕机,这个时候数据可能丢失;后者的话,因为数据已经写入了存储系统,不需要担心数据丢失,但相对吞吐就小一些
对于Thread具体逻辑,首先会将Buffer中的数据取出来,调用底层写入逻辑,在一定的时间周期上去flush,flush完成后开始建立Index,也就是Offset和timestamp对于消息具体位置的映射关系
Index建立好之后,会save一次checkpoint,也就表示,checkpoint后的数据是可以被消费的,
最后当文件到达一定大小之后,需要建立一个新的segment文件来进行写入
Broker写文件Failover
之前说过,建立一个新的文件,会随机挑选与副本数量相当的数据节点进行写入,那如果此时我们挑选的一个节点出现了问题,导致不能正常写了,如何处理?是需要等着这个节点进行恢复吗?但不知道什么时候恢复,这样我们可以重新找正常的节点创建新的文件进行写入,也就保证了我们的写入可用性
Proxy
读
首先Consumer发送了一个Fetch Request,然后会有一个wait流程,想象一个Topic,如果一直没有数据写入,那么,此时Consumer就会一直发送Fetch Request,如果Consumer数量过多,BMQ的server端是扛不住这个请求的,因此,我们设置了一个等待机制,如果没有fetch到指定大小的数据,那么Proxy会等待一定的时间,再返回给用户侧,这样也就降低了fetch的请求IO次数,经过wait流程后,我们会到Cache里面去找到是否有我们想要的数据,如果没有,再去存储系统当中找,首先会Open这个文件,然后通过Index找到数据的具体位置,从这个位置开始读数据
多机房部署
对于一个高可用的服务,除了防止单机故障所带来的意外,也要防止机房故障所带来的影响,比如机房断电,机房网络故障等等。