在主备有延迟情况下,如何进行主备切换?
一种可靠性优先。等备库的延迟降低 5s 内后,主库改为 readonly,备库延迟为 0 后,备库改为可写。存在一定时间的无可用性。
另一种可用性优先,直接切换。
除非丢失数据可通过 binlog 找到 + 短期不一致也可以接受,否则一般可靠性优先。

主备延迟下的主备切换策略

可靠性优先策略

双 M 结构下,从 A 主到 B 主切换的详细过程是这样的:

  1. 判断备库 B 现在的 seconds_behind_master,如果小于某个值(比如 5 秒)继续下一步,否则持续重试这一步;
  2. 把主库 A 改成只读状态,即把 readonly 设置为 true;
  3. 判断备库 B 的 seconds_behind_master 的值,直到这个值变成 0 为止;
  4. 把备库 B 改成可读写状态,也就是把 readonly 设置为 false;
  5. 把业务请求切到备库 B。

这个切换流程,一般是由专门的 HA 系统来完成的,我们暂时称之为可靠性优先流程。

这个流程下,整个系统会有一定的不可用时间。

可用性优先策略

如果强行把步骤 4、5 调整到最开始执行,也就是说不等主备数据同步,直接把连接切到备库 B,并且让备库 B 可以读写,那么系统几乎就没有不可用时间了。

这个切换流程,暂时称作可用性优先流程。这个切换流程的代价,就是可能出现数据不一致的情况。

什么情况下可用性优先级更高呢?

  • 有一个库的作用是记录操作日志。这时候,如果数据不一致可以通过 binlog 来修补,而这个短暂的不一致也不会引发业务问题。

  • 同时,业务系统依赖于这个日志写入逻辑,如果这个库不可写,会导致线上的业务操作无法执行。

这时候,你可能就需要选择先强行切换,事后再补数据的策略。当然,事后复盘的时候,我们想到了一个改进措施就是,让业务逻辑不要依赖于这类日志的写入。也就是说,日志写入这个逻辑模块应该可以降级,比如写到本地文件,或者写到另外一个临时库里面。这样的话,这种场景就又可以使用可靠性优先策略了。