RocketMQ 逻辑队列

本篇文章还未写完…
当前,MessageQueue 和 Broker 耦合在一起,意味着 Broker 数量变化之后,消息队列的数量也会发生变化,这会造成所有的队列都需要一个重新平衡的过程,这个过程可能需要数分钟才能恢复。增加逻辑队列之后,Broker 数量的变化不会影响逻辑队列数量的变化,二者可以独立变化。

架构设计

brokerNameMessageQueueLogicalQueue
broker100
broker111
broker202
broker213

假设当前一个 LogicalQueue 从 broker1 迁移到了 broker2,我们迁移的仅仅是映射关系,而非实际的数据,所以 broker1 依然能够正常消费 LogicalQueue-0 这个逻辑队列里面的数据,但是我们会将这个队列的状态置位只读,故这个队列不能再写入消息:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100(0-100)ReadOnly
broker111Normal
broker202Normal
broker213Normal
broker220(101-)Normal

当 broker1 从 commit log 和 consume queue 中清除了所有数据后,QueueStatus 变为 Expired(不可读也不可写):

brokerNameMessageQueueLogicalQueueQueueStatus
broker100(-)Expired
broker111Normal
broker202Normal
broker213Normal
broker220(101-)Normal

如果这个 LogicQueue 再次迁移回 broker1,它会重用这个过期的 MessageQueue:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100(201-)Normal
broker111Normal
broker202Normal
broker213Normal
broker220(101-200)ReadOnly

如果这个 LogicQueue 再次迁移回 broker1 的时候,当前没有过期的 MessageQueue,它会创建一个新的 MessageQueue:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100(0-100)ReadOnly
broker111Normal
broker120(201-)Normal
broker202Normal
broker213Normal
broker220(101-200)ReadOnly

如果 broker2 下线了,那么上面的所有的 LogicQueue 都应该进行迁移:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100Normal
broker111Normal
broker122(101-)Normal
broker133(101-)Normal
broker202(0-100)ReadOnly
broker213(0-100)ReadOnly

当 broker2 上面的所有数据包括 commit log 和 consume queue 被消费完后,那么 broker2 可以被移除掉了:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100Normal
broker111Normal
broker122(101-)Normal
broker133(101-)Normal

当部署了新的 broker 后,我们可以使用命令来迁移一些 LogicQueue 到这个 broker 上,来分担一些流量:

brokerNameMessageQueueLogicalQueueQueueStatus
broker100Normal
broker111Normal
broker122(101-200)ReadOnly
broker133(101-200)ReadOnly
broker302(201-)Normal
broker313(201-)Normal

实现

public class LogicalQueuesInfo extends HashMap<Integer, List<LogicalQueueRouteData>> {
}
/**
 * logical queue offset -> message queue offset mapping
 */
public class LogicalQueueRouteData implements Comparable<LogicalQueueRouteData> {
    
    private volatile int logicalQueueIndex = -1; /* -1 means not set */
    private volatile long logicalQueueDelta = -1; /* inclusive, -1 means not set, occurred in writeOnly state */

    private MessageQueue messageQueue;

    private volatile MessageQueueRouteState state = MessageQueueRouteState.Normal;

    private volatile long offsetDelta = 0; // valid when Normal/WriteOnly/ReadOnly
    private volatile long offsetMax = -1; // exclusive, valid when ReadOnly

}

话题路由信息 TopicRouteData 中增加了和逻辑队列相关的信息:

public class TopicRouteData extends RemotingSerializable {

	private LogicalQueuesInfo logicalQueuesInfo;

}

在构造器中,logicQueueIdx 封装为了一个 brokerName 是 logical_queue_broker,同时 queueId 是 logicQueueIdx 的 MessageQueue:

public class SendResultForLogicalQueue extends SendResult {

	public SendResultForLogicalQueue(SendResult sendResult, int logicalQueueIdx) {
        super(sendResult.getSendStatus(), sendResult.getMsgId(), sendResult.getOffsetMsgId(),
            	new MessageQueue(sendResult.getMessageQueue().getTopic(), MixAll.LOGICAL_QUEUE_MOCK_BROKER_NAME, logicalQueueIdx),
            	sendResult.getQueueOffset());
        // ...
    }

}
public class PullResultWithLogicalQueues extends PullResultExt {
}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值