数据转发流程
如果vnode A是master, vnode B是slave, vnode A能接受客户端的写请求,而vnode B不能。当vnode A收到写的请求后,遵循下面的流程:
- 应用对写请求做基本的合法性检查,通过,则给改请求包打上一个版本号(version, 单调递增)
- 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
- 应用调用API syncForwardToPeer,如多vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。
- vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理
- vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。
- 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。
- 如果quorum大于1,vnode A需要等待vnode B或其他副本对Forward消息的确认。
- 如果quorum大于1,vnode A收到quorum-1条确认消息后,调用回调函数confirmForward,通知应用写入成功。
- 如果quorum为1,上述6,7,8步不会发生。
- 如果要等待slave的确认,master会启动2秒的定时器(可配置),如果超时,则认为失败。
对于回复确认,sync模块提供的是异步回调函数,因此APP在调用syncForwardToPeer之后,无需等待,可以处理下一个操作。在Master与Slave的TCP连接管道里,可能有多个Forward消息,这些消息是严格按照应用提供的顺序排好的。对于Forward Response也是一样,TCP管道里存在多个,但都是排序好的。这个顺序,SYNC模块并没有做特别的事情,是由APP单线程顺序写来保证的(TDengine里每个vnode的写数据,都是单线程)。