那么这个验证机制如何实施呢?方案是,在一次查询请求里,通过异步线程,比较 SqlServer 和 MySQL 的查询结果是否一致,如果不一致,记日志,再人工检查不一致的原因,直到彻底解决不一致的问题后,再逐步灰度流量。
首先,在一个夜黑风高的深夜,流量最小的时候,完成 SqlServer 到 MySQL 数据库的全量数据同步。
接着,开启双写,此时,如果有用户注册,就会实时双写到两个数据库。那么,在全量同步和实时双写开启之间,两个数据库还相差这段时间的数据,所以需要再次增量同步,把数据补充完整,以防数据的不一致。
剩下的时间,就是各种日志监控,看双写是否有问题,看数据比对是否一致等等。
这段时间是耗时最长的,也是最容易发生问题的,如果有的问题比较严重,导致数据不一致了,就需要从头再来,再次基于 SqlServer 全量构建 MySQL 数据库,然后重新灰度流量。
直到最后,100% 的流量全部灰度到 MySQL,此时就大功告成了,下线灰度逻辑,所有读写都切到 MySQL 集群。
| MySQL 和 ES 主备集群方案
做到这一步,感觉会员主库应该没问题了,可 dal 组件的一次严重故障改变了我们的想法。
那次故障很恐怖,公司很多应用连接不上数据库了,创单量直线往下掉,这让我们意识到,即使数据库是好的,但 dal 组件异常,依然能让会员系统挂掉。
所以,我们再次异构了会员主库的数据源,双写数据到 ES,如下所示:如果 dal 组件故障或 MySQL 数据库挂了,可以把读写切到 ES,等 MySQL 恢复了,再把数据同步到 MySQL,最后把读写再切回到 MySQL 数据库。

会员系统不仅仅要保证系统的稳定和高可用,数据的精准和正确也同样重要。
举个例子,一个分布式并发故障,导致一名用户的 APP 账户绑定了别人的微信小程序账户,这将会带来非常恶劣的影响。
首先,一旦这两个账号绑定了,那么这两个用户下的酒店、机票、火车票订单是互相可以看到的。
你想想,别人能看到你订的酒店订单,你火不火,会不会投诉?除了能看到别人的订单,你还能操作订单。
例如,一个用户在 APP 的订单中心,看到了别人订的机票订单,他觉得不是自己的订单,就把订单取消了。
这将会带来非常严重的客诉,大家知道,机票退订费用是挺高的,这不仅影响了该用户的正常出行,还导致了比较大的经济损失,非常糟糕。
针对这些异常会员账号,我们进行了详细的梳理,通过非常复杂烧脑的逻辑识别出这些账号,并对会员接口进行了深度优化治理,在代码逻辑层堵住了相关漏洞,完成了异常会员的治理工作。