3.Rocket主从同步配置与刷盘策略

766 阅读5分钟

4.0 Rocket主从配置同步详解

brokerRole

SYNC_MASTER

如果是同步模式,master和slave之间的数据同步要求较为严格,保证尽量不丢消息,性能会有损耗。

生产消息会调用方法:org.apache.rocketmq.store.CommitLog#putMessage

可以看到,如果是同步主从模式,消息发送者将消息刷写到磁盘后,需要继续等待新数据被传输到从服务器,从服务器数据的复制是在另外一个线程HAConnection中去拉取,所以消息发送者在这里需要等待数据传输的结果。该功能由GroupTransferService实现。

ASYNC_MASTER

如果是异步模式,master和slave之间的数据同步要求较为宽松,极端情况下可能会丢消息,但是性能较好。

主从同步由异步的方法完成,大致步骤如下:

Master端:

监听端口 org.apache.rocketmq.store.ha.HAService.AcceptSocketService#beginAccept

建立连接 org.apache.rocketmq.store.ha.HAService.AcceptSocketService#run

读取slave上报的maxOffset org.apache.rocketmq.store.ha.HAConnection.ReadSocketService#run

传输数据给slave org.apache.rocketmq.store.ha.HAConnection.WriteSocketService#run

Slave端:

连接master org.apache.rocketmq.store.ha.HAService.HAClient#connectMaster

定时报告maxOffset给master org.apache.rocketmq.store.ha.HAService.HAClient#run

接收master传输来的数据 org.apache.rocketmq.store.ha.HAService.HAClient#processReadEvent

原文链接:blog.csdn.net/sinat_14840…

flushDiskType

生产者将消息发送给Broker,Broker将消息写入CommitLog,每个CommitLog最多为1G,写满后,重新建一个 每个Topic可以配置多个MessageQueue,每个MessageQueue都对应一系列的ConsumeQueue文件,ConsumeQueue文件中记录的是CommitLog消息的offset偏移量。

SYNC_FLUSH

同步刷盘是指broker收到消息后,必须强制将消息刷入磁盘,才返回ack给producer;

同步刷盘模式,当消息来了之后,尽可能快地从内存持久化到磁盘上,保证尽量不丢消息,性能会有损耗

ASYNC_FLUSH

异步刷盘模式,消息到了内存之后,不急于马上落盘,极端情况可能会丢消息,但是性能较好。

异步刷盘是指broker收到消息后,将消息写入os pagecache后就返回ack给producer。同步刷盘消息写入性能低,但是可以保证消息不丢失;异步刷盘消息写入吞吐量高,但是消息可能会丢失。 CommitLog采用磁盘顺序写+OS PageCache写入+异步刷盘的方式达到近似内存的写入性能。

配置1

之前我搭建的broker的配置中,配置的是同步复制和同步刷盘:

brokerRole=SYNC_MASTER

flushDiskType=SYNC_FLUSH

修改完之后,依次重启broker(注意时间重启多个broker之间要保留一定的间隔时间)

 1)异步刷盘方式:在返回写成功状态时,消息可能只是被写入了内存的PAGECACHE,写操作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘操作,快速写入

  2)同步刷盘方式:在返回写成功状态时,消息已经被写入磁盘。具体流程是,消息写入内存的PAGECACHE后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态

此处配置的是主从同步刷盘方式,保证主节点写入磁盘成功后,才向从节点写入,从节点使用的是异步写盘方式,从节点可能没有入盘,只是写入内存就返回,当内存里的消息量积累到一定程度时,统一触发写磁盘操作,快速写入。

配置2

实际应用中要结合业务场景,合理设置刷盘方式和主从复制方式,尤其是SYNC_FLUSH方式,由于频繁 的触发写磁盘动作,会明显降低性能。 通常情况下,应该把Master和Slave设置成ASYNC_FLUSH的刷盘方式, 主从之间配置成SYNC_MASTER的复制方式,这样即使有一台机器出故障,仍然可以保证数据不丢。

如何选择刷盘策略?

追求高性能,异步刷盘;追求数据的安全性,同步刷盘。

对于日志类型这种场景,可以允许数据的丢失,但是要求比较高的吞吐量,可以采用异步刷盘的方式。另外非核心的业务场景,不涉及重要核心数据变更的场景,也可以使用异步刷盘,比如订单支付成功,发送短信这种场景。

但是对于涉及到核心的数据变更的场景,就需要使用同步刷盘,比如订单支付成功后扣减库存。

问题答疑

1、Master Broker是如何将消息同步给Slave Broker的?

异步采取Pull模式拉取消息:RocketMQ的Master-Slave模式采取的是Slave不停的发送请求到Master Broker去拉取消息。

2、RocketMQ 实现读写分离了吗?

消费者在获取消息的时候,会先发送请求到Master Broker上面,请求获取一批消息,此时Master Broker是会返回一批消息给消费者的,然后Master Broker在返回消息给消费者系统的时候,会根据当时Master Broker的负载情况和Slave Broker的同步情况,向消费者系统建议下一次拉取消息的时候是从Master Broker上面拉取还是从Slave Broker上面拉取。

在写入消息的时候,通常来说肯定是选择Master Broker去写入的,但是在拉取消息的时候,有可能从Master Broker获取,也可能从Slave Broker去获取,一切都根据当时的情况来定。

3、如果Slave Broke挂掉了有什么影响?

所以如果Slave Broker挂了,那么此时无论消息写入还是消息拉取,还是可以继续从Master Broke去走,对整体运行不影响。只不过少了Slave Broker,会导致所有读写压力都集中在Master Broker上。

4、基于Dledger实现RocketMQ高可用自动切换

Dledger融入RocketMQ之后,可以让一个Master Broker对应多个Slave Broker,也就是一份数据对应多个副本,此时如果一旦Master Broker宕机,就可以在多个Slave里面通过Dledger技术和Raft协议算法进行leader选举,直接将一个Slave Broker选举为新的Master Broker,然后这个新的Master Broker就可以对外提供服务了。 整个过程也许只要10秒或者几十秒的时间就可以完成,这样的话,就可以实现Master Broker挂掉之后,自动从多个Slave Broker中选举出来一个新的Master Broker,继续对外服务,一切都是自动的。