RocketMQ 笔记4 HA主从同步

broker主从同步包括同步双写 和 异步复制, 其实这两种都是使用相同的方式传输的,同步双写只是在主线程上阻塞了
一段时间,等待传输结果,返回给producer


master针对每一个slave之间会有一个长连接,都会保存已经传输的offset,启动一个线程commitlog最大offset大于已经传输的offset
时候,就会通过这个连接往slave写数据,格式为:thisOffset(8字节)+ size(4字节) + body


当slave收到消息时,根据规则取出消息内容,调用defaultMessageStore.appendToCommitLog写入文件,同时返回一个确认消息
reportSlaveMaxOffset,消息格式为:maxOffset(8字节),master收到后,会写入一个byteBufferRead中,更新slaveAckOffset,
唤醒同步方式阻塞的线程




1.相关的类
org.apache.rocketmq.store.ha.HAService  处理主从同步的类
org.apache.rocketmq.store.ha.HAService.AcceptSocketService    master启动的一个线程,启动一个ServerSocket,等待slave的连接
org.apache.rocketmq.store.ha.HAConnection  master服务收到slave连接请求建立的连接,内部又启动了两个线程处理读写,因为可能多个slave
所以可能有多个(HAService.List<HAConnection>)
org.apache.rocketmq.store.ha.HAService.HAClient  slave启动一个线程连接master服务器,收取消息写入文件,返回确认消息
org.apache.rocketmq.store.ha.HAService.GroupTransferService  同步双写的使用,不停检测是否写成功,唤醒阻塞线程




2.master端启动过程
org.apache.rocketmq.store.ha.HAService.AcceptSocketService.beginAccept()
新建serverSocketChannel  selector,注册OP_ACCEPT事件


org.apache.rocketmq.store.ha.HAService.AcceptSocketService.run() 处理连接事件
SocketChannel sc = ((ServerSocketChannel) k.channel()).accept(); 得到连接
HAConnection conn = new HAConnection(HAService.this, sc); 
新建了writeSocketService  readSocketService 各自新建了一个Selector,分别注册
OP_WRITE  OP_READ 事件


conn.start();
启动writeSocketService  readSocketService线程


HAService.this.addConnection(conn);


3.HAConnection传输过程
HAConnection属性
private volatile long slaveRequestOffset = -1;
private volatile long slaveAckOffset = -1;


ReadSocketService属性
private final ByteBuffer byteBufferRead = ByteBuffer.allocate(READ_MAX_BUFFER_SIZE);//写缓存
private int processPostion = 0;//写缓存当前处理的位置
private volatile long lastReadTimestamp = System.currentTimeMillis();//最后一次读时间戳


WriteSocketService属性
private final ByteBuffer byteBufferHeader = ByteBuffer.allocate(headerSize);//保存消息头
private long nextTransferFromWhere = -1;//下一次传输起始offset
private SelectMappedBufferResult selectMappedBufferResult;//保存需要传输的消息内容
private boolean lastWriteOver = true;//最后一次写是否结束
private long lastWriteTimestamp = System.currentTimeMillis();//最后一次写时间戳


WriteSocketService工作过程

org.apache.rocketmq.store.ha.HAConnection.WriteSocketService.run()

public void run() {
            HAConnection.log.info(this.getServiceName() + " service started");

            while (!this.isStopped()) {
                try {
                    this.selector.select(1000);

                    //slave启动时候会先上报当前salve的commitLog最大偏移
                    //这里应该是先等待上报
                    if (-1 == HAConnection.this.slaveRequestOffset) {
                        Thread.sleep(10);
                        continue;
                    }

                    //这里应该是刚启动时候的计算,假如slave为空,那么上报了0给slaveRequestOffset
                    //这个计算就有点不懂了,此时不是应该从0开始传输吗
                    if (-1 == this.nextTransferFromWhere) {
                        if (0
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值