一段时间,等待传输结果,返回给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