趣谈RocketMQ

125 阅读5分钟

broker-工人

NameServer-宿舍

Topic-商店

queue-货架

producer-生产者

consumer-消费者

基本概念

broker就相当于工人,存储着消费者组的信息,负责搬运生产者的东西也就是message(都有唯一标识),message又会组成topic(商店) ,topic中还有货架(queue)负责存放商品并且拿给消费者消费,NameServer则是宿舍,工人不仅在宿舍进行身份注册而且每隔一段时间需要发送健康状况给宿舍,当然的,生产者和消费者由于工作量小,只用在宿舍进行注册而不用发送健康状况,工人里面也有组长,并且分为许多个组。生产者和消费者可以通过宿舍查询工人们的信息以便完成工作

路由注册

但是跟zk,kafka不同的是该宿舍是傻的,也就是说它十分被动,它会在内部维护工人的信息,但是全程由工人负责维护(万恶的资本主义)虽然构建很简单,但是要是新增宿舍的话,需要让工人自己跑到宿舍进行注册而不能想上面2个那样不用工人跑一趟

心跳检测

工人会发送自己的id,地址,名字,组名给宿舍,宿舍接收到的话,会更新这个工人的存活情况

路由剔除

宿舍对每个工人都有个计时器,用来存放工人的最近发送消息的时间,要是超出了一段时间,就判断该工人已经死亡

路由发现

当商品发生变更时,宿舍还是不会进行更改,这需要生产者和消费者手动去获取商品变更信息

客户端NameServer选择策略

生产者和消费者在创建时就得加上宿舍的地址,那么有这么多宿舍,与哪个相连呢?会产生随机数并与宿舍数量取模,进行连接,如果失败,则会逐个去连接其他宿舍

工作流程

温馨提示:每个工人可能管理着不同商店的不同货架

  1. 建造宿舍,等待工人,生产者,消费者
  2. 招聘工人,工人会与宿舍进行长连接,并每30s发生健康状况
  3. 在生产产品前,可以先建造该产品的商店,当然需要指定这些商店有哪些工人可以进入,自然的也会将商店与工人的联系写入宿舍,不过也可以在商品创建时自动创建商店
  4. 生产者生产产品前还需要与宿舍保持长连接,并且从宿舍拿到商品货架上与工人所在地址的映射关系(路由信息),根据布吉岛神魔算法选择一个货架,并且与负责该货架的工人进行长连接从而可以与他进行沟通,每隔30s从宿舍更新当前的路由信息
  5. 消费者与生产者类似,不过消费者更有人情味,消费者每隔30s会询问工人是否死亡

Topic的创造模式

手动创建商店时,有两种模式:

  1. 集群模式:该模式下创建的商店在该集群中,所有工人管理的货架是相同的
  2. Broker模式:该模式下创建的商店在该集群中,所有工人管理的货架可以不相同

自动创建商店时,默认采用Broker模式,会为每个Broker默认创建4个Queue。

读写队列

读写队列其实是一样的,也就是说会创建多的一方,比如说4个读队列,8个写队列,那就会创建8个队列,其中消费者只能读前四个,而生产者能写8个

但是不一样的读队列和写队列其实是会产生问题的,也就是有些消息根本就没办法读

设计的目的是为了,方便Topic的Queue的缩容。

原来创建的Topic中包含16个Queue,如何能够使其Queue缩容为8个,还不会丢失消息?可以动态修改写队列数量为8,读队列数量不变。此时新的消息只能写入到前8个队列,而消费都消费的却是16个队列中的数据。当发现后8个Queue中的消息消费完毕后,就可以再将读队列数量动态设置为8。整个缩容过程,没有丢失任何消息。

perm用于设置对当前创建Topic的操作权限:2表示只写,4表示只读,6表示读写。

Broker集群模式

单master

只有一个broker,自己开店

多master

有多个master,多人合伙开店

优点:配置简单,一个工人不见了也不影响,在磁盘配置为RAID10时,即使机器宕机,异步刷盘会丢失少量消息,同步刷盘一条都不会丢,性能最高

缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅(不可消费), 消息实时性会受到影响。

多Master多Slave模式-异步复制

有多个master,并且他们手下还有多个slave,即master负责处理消息的读写请求,而slave仅负责消息的备份与master宕机后的角色切换。

采用异步复制策略,也就是说消息写入master后,便立即返回确认消息给生产者,之后才进行slave的备份

特点:master宕机后,slave会马上上位,当然了,在这期间会遗漏一些消息

多Master多Slave模式-同步双写

master和slave都写入数据后才返回ACK

优点:消息的安全性更高不存在消息丢失

缺点:Master宕机后slave无法进行主备切换

最佳实践

一般为Master配置RAID10磁盘阵列,然后再为其配置一个Slave,即利用了RAID10磁盘阵列的高效、安全性,又解决了可能会影响订阅的问题。