从 MySQL+MMM 到 MariaDB+Galera Cluster : 一个高可用性系统改造
很少有事情比推出高可用性(HA)系统之后便经常看到的系统崩溃更糟糕。对于我们这个Rails运行机的团队来说,这个失效的HA系统是MySQL多主复制管理器(MMM)。 我们已经找寻MMM的替代品有一段时间了,几个月之前,我们转换到了MariaDB + Galera Cluster以寻求高可用的Mysql。 MMM怎么了,Galera Cluster又有什么特别之处呢?继续阅读! |
! |
MySQL多主机复制 (MMM)基本被打破MySQL MMM 是如何工作的:一台安装了MySQL MMM的服务器每十秒种(默认间隔)轮询一次MySQL节点, 来检查其状态。仅其中的一台服务器接收到写入器角色 - 其他的可以拥有阅读器角色。 MMM 维护了一个虚拟IP,这个IP指向拥有写入器角色的节点。 问题在于轮询:如果MySQL每十分钟轮询,那么如果写入器节点在检查的间歇出现故障怎么办?如果你设置了HA你可能正处理着许多事务 - 在MMM检测到写入器节点不正常之前,可能已经有成千上万的事务失败了。更糟糕的是,如果存在一种内部问题:复制失败在先,事务失败在后,那么你要把写入器角色转到其他节点上吗?但是其他节点不一定符合原始的写入器节点。 |
减少轮询间隔到1秒也不能修正这个问题-大型数据库可能在每秒内运行许多事务。 因此轮询是根本问题,而且超出了根本问题范围。无法控制的MySQL MMM经常产生难以恢复的问题。Baron Swartz在Percona的MySQL大神上对MMM的缺陷有如下描述: 简要地来说,MMM产生的宕机时间比它要防止的宕机时间更长。因此它是一个低可靠性的工具,不是高可靠性的工具。它可以让你连续几天以7X24小时的工作方式从宕机的机器里提取数据,并放回到服务器上,这只会导致系统真正的非常严重的一塌糊涂。因此,MMM赋予词语"cluset-f__k"新的意义。尽管MMM存在缺陷,然而它至少是对MySQL进行高可靠性的一次突破。然而时间改变了一切。甚至MySQL MMM的创建者也说到了要更改的时候了。Baron有关MMM的博客日志有Alexey's的如下评论: 我是MMM的最初的作者,我完全同意你的意见。每次我试图给集群添加HA的时候,我都会想起MMM,而且需要亲自去尝试,因为我只是不确定这个工具的我所做的配置。而且市场上没有其他软件可以可靠地做这项工作。 |
那么,为什么Galera是最好的MySQL HA解决方案呢?我们的Galera Cluster设置仍然使用轮询来做健康检测——这比MMM好在哪里呢? 答案在于主从复制怎样是运作的。对于标准版的MySQL,对master的写操作被记录于一个二进制的日志。Slave会在之后复制二进制日志中的查询。查询在写服务器上运行与在其它节点上运行时刻之间,总是会有一个延迟。它是异步的。 MySQL异步复制有下面的问题:
对于Galera,事务是在它们被提交之前被所有节点确认。如果一个事务在一个节点失败了,那个节点将立刻从群集中移除。换句话说,Galera主从复制是同步的。你 永远也不会丢失事务——没有延迟 (而且Galera的 基于行的复制大约要快5倍速)。 |
Galera集群是局内人MySQL MMM 是一个局外者—— 对于服务器上实际在发生的事情它是“哑的”。它只做一种检测,而且那就是它所知道的全部该如何反应的事情。 Galera集群是一个“局内人”,因此对每个节点的内部状态要更机灵,并且不需要人工干预就可以做正确的事情(例如,一个节点同步或未同步,成为一个donor(节点处于为新节点准备或传输集群全量数据状态,对客户端不可用),等等——全部都是自动的)。 |
当写入节点失败的时候会发生什么呢?由于用一个Galera集群可以写进任意节点,我们还是选择尽量减少潜在的死锁和只在一个节点写入。为此,我们使用HAProxy:我们拥有一个前端供“写入者”节点,另一个前端供读出以供所有节点实现余额查询。“写入者”通过单个节点发送请求,而其他的节点作为备份。 如果HAProxy检测到“写入者”节点不正常,它立即提拔备份节点中的一个作为“写入者”。MySQL的MMM在这种情况下通常会关掉所有节点之间的通话——HAProxy不会如此。当“写入者”后台更新的时候,我们可能会丢失一部分请求,但它不会导致不一致的数据集通过服务器,这比瘫痪更糟糕。 我们不会自动修复失败的节点,不过这没有关系。我主要关注点是确保一个正常的节点在执行写入,HAProxy是做这个的。 |
修复失效的节点(并让它作为一个新的节点处于在线状态)当一个节点在标准的MySQL复制的时候失效,你将在再次进行复制的时候把大量的负载集中在一台服务器上(这台服务器不仅仅要进行读和写,而且还要承接来自innodbbackupex的负载)。 使用Galera,你可以让其中一个节点离线(因此你至少需要三个节点)。这时这个节点就成为供给者节点-对它的写操作将被阻塞。这个节点就通过rsync传输自身的数据给失效的节点(或者新的节点)。然后,供给者节点和失效节点通过辅助队列运行查询而与其他节点保持同步。 一旦这两个节点回归到同步状态,HAProxy将自动的标记它们为启动状态,然后把它们添回道前端。 |
Galera集群也支持普通的MySQL,因此我们为什么不切换到MariaDB?切换到MariaDB的理由既有技术原因也有政治原因:
|
|
我们会再做一次?绝对地。我们没有看到有什么原因不切换到 MariaDB 和 Galera Cluster。 监控 Galera Cluster
监控 Galera 的一件伟大的事情是它是分层的 - 我们可以很容易地监视栈的每一部分。我们使用 Scout 来监视,那意味着我们仅仅需要去使用下列插件:
TL;DR直到最近, MySQL MMM 是添加高可用性到 MySQL 的最好的(但坏了的)途径。Galera Cluster 最终为 MySQL 增加了真实的高可用性,主要多亏同步复制。 |