最近开发的同事反馈了一个问题,说有一台北京节点的MySQL数据库数据延迟太大,想让我们帮忙看看怎么解决。
这个问题一下子让我想起了之前“水深火热”的日子,因为这是一套MySQL级联复制的环境。这么做的目的也是为了能够方便数据查询和统计任务,看起来虽好,但是老是有一些不可控因素。
北美使用AWS在北美,都是实时的业务数据,考虑了灾备和读写分离使用了一主一从的架构,新加坡节点2是一个中继节点,也使用了AWS,可以看到新加坡节点是北美节点的从库,但是北京的主库。 北京节点是一个IDC设备。就这样一个级联复制的环境就跑起来了。
由于新加坡的节点网络延迟太大,而且很不稳定,之前的一部分业务最后就索性迁移到香港的云服务上了。剩下的这部分业务稳定运行了一段时间,但是最近经常发现数据延迟很大,这个问题又提上了日程。
我们经过讨论,开发同事建议,索性直接连北美节点吧,我这边简单做了测试,网速其实还是要好一点。所以改进后的架构如下:
但是这里就面临一个问题,怎么去无缝的把节点的数据顺利切换过去。发现这个问题变得有些纠结了,因为新加坡的节点目前和北京节点是有延迟,直接切换过去肯定不行,而且偏移量在不同的节点都有不小的差别。怎么调和呢。
每当到这个时候我就想起了MySQL非常经典的架构图。
碰到实际的问题再来看的时候发现有很多地方就需要加深理解了。
单纯使用偏移量,我和同事在纸上分析和讨论,感谢总是有一些不确定的地方。这让我就非常怀念起了5.6推出的GTID,这个特性在这个问题前真是太有用了。GTID的统一格式是由source_id加transaction_id构成。这个source_id就是UUID,是一个唯一性标示,在读写分离,一主多从的环境,还有当下的级联复制的环境中尤其有用,因为是全局事务的概念,所以不会出现重复的情况,这一点和Oracle里物理一致性的SCN很有相似的味道。
在这个问题中,如果能够启用GTID,那么北美节点的UUID在北京节点还是一个唯一性的标示,能够正确的标识和应用事务信息。
但是当前的环境是5.5版本,很遗憾使用不了,那么一种折中的办法就是停止新加坡的节点,然后让北京节点去追平数据,然后以这个为基准,让北京节点继续从北美的slave节点继续抓取增量的数据变化。
整个过程就会使用change master的方式来完成了。