数据转发流程

如果vnode A是master, vnode B是slave, vnode A能接受客户端的写请求,而vnode B不能。当vnode A收到写的请求后,遵循下面的流程:

replica-forward.png

  1. 应用对写请求做基本的合法性检查,通过,则给改请求包打上一个版本号(version, 单调递增)
  2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
  3. 应用调用API syncForwardToPeer,如多vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。
  4. vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理
  5. vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。
  6. 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。
  7. 如果quorum大于1,vnode A需要等待vnode B或其他副本对Forward消息的确认。
  8. 如果quorum大于1,vnode A收到quorum-1条确认消息后,调用回调函数confirmForward,通知应用写入成功。
  9. 如果quorum为1,上述6,7,8步不会发生。
  10. 如果要等待slave的确认,master会启动2秒的定时器(可配置),如果超时,则认为失败。

对于回复确认,sync模块提供的是异步回调函数,因此APP在调用syncForwardToPeer之后,无需等待,可以处理下一个操作。在Master与Slave的TCP连接管道里,可能有多个Forward消息,这些消息是严格按照应用提供的顺序排好的。对于Forward Response也是一样,TCP管道里存在多个,但都是排序好的。这个顺序,SYNC模块并没有做特别的事情,是由APP单线程顺序写来保证的(TDengine里每个vnode的写数据,都是单线程)。