这周GitHub网站发生了两次重大的不可访问事故,以及若干小时的服务降级。GitHub运维团队特地发了一篇Blog来总结整个事件的过程。
事故的主要原因可以归结为:
1. 数据库的Active角色在不应该发生failover切换时,进行了切换。 First, several failovers of the 'active' database role happened when they shouldn't have.
2. 数据库集群发生了脑裂,导致集群管理软件(Pacemaker+HeartBeat)做了错误的操作。Second, a cluster partition occurred that resulted in incorrect actions being performed by our cluster management software.
3. 前两点中提到的Failover切换,造成了比预计情况更恶劣的性能问题。Finally, the failovers triggered by these first two events impacted performance and availability more than they should have
基于这三点总结就抛出了三个问题:
1. 现有的HA软件是否可靠,可信?是否在正确的时候做了正确的判断和操作?
2. 没有集中管理机的HA架构(即内部投票)是否可靠?
3. HA的Failover过程是否要考虑数据预热?
以下是对于这三个问题的一些分析和个人看法:
问题一:现有的HA软件是否可靠,可信?是否在正确的时候做了正确的判断和操作?
GitHub团队认为:The automated failover of our main production database could be described as the root cause of both of these downtime events.
而对于这个问题,我的想法和 Xaprd的观点 一致:事故的关键在于现有的HA软件都没法照顾到所有可能发生的情况,以至于在某些情况下的行为是不可预测的,或者非我们所想的。
因此一味的将切换操作置成手工模式,虽然避免了风险,但显然没有很好的使用HA软件所提供的service。
个人想法是,对于一些原因明确且有明确cookbook的事故,可以让HA去完成failover。而对于那些需要人工介入分析故障原因的事故,做手工切换,如果github遇到的timeout等。
当然这个只是理想情况,目前真正能够通过配置case决策的HA软件还并不存在。
因此,保守原则还是一个比较推荐的办法,即:HA部署完成后先切入手工模式,前几次failover通过阅读报错日志后手工处理。在几次production实践之后再认为此HA架构是可信的,并切入自动模式。
问题二: 没有集中管理机的HA架构(即内部投票)是否可靠?
从目前的流行程度来看,MMM,MHA这些使用Manager管理模式的架构,已经逐渐替代 Heartbeat + LVS/ Pacemaker 等投票模式的架构。
其主要原因就是在没有仲裁机的情况下,发生网络partition会造成脑裂,从而导致active角色的互相争抢,最后使整个cluster瘫痪。
Github再次用血的教训告诉我们脑裂是无仲裁架构的致命缺陷。
问题三:HA的Failover过程是否要考虑数据预热?
这个问题显然是引起本次问题的关键:没有预热的切换才是万恶之源。脑裂只是连锁反应而已。
而貌似整个社区的blog中对于这个问题的讨论却是少之又少,也许是重视程度不够?
会造成切换后压力剧增可能的情况,我总结为以下三种:
1. stand-by-master完全作为冗余,BufferPool 基本没有热点数据
2. stand-by-master提供read-only服务,但read-only 和 acitve master 的请求业务类型不同,导致热点数据不同
3. 原本active的MySQL宕机后重新回归,此时重启后的MySQL是处于完全Cold 状态
但目前众多HA软件中都没有考虑预热的因素,毕竟所有的failover都希望尽快的将业务转移至stand-by master,而预热则需要尽可能多的时间来获取业务的请求。
也许这是一个无解命题?
updated @2012-09-27
附上两个相关讨论的URL:
不可能存在完美的MySQL automatic failover方案 http://openlife.cc/blogs/2012/september/failover-evil
http://www.hastexo.com/blogs/florian/2012/09/26/pacemaker-and-recent-github-service-interruption