翻译自《Under the hood: MySQL Pool Scanner (MPS)》
Facebook有世界上最大的Mysql数据库集群。这个集群由数以千计的服务通过位于两大洲的各种数据中心组成。
操作一个如此规模的集群只需一个小团队。自动化能完成几乎所有常见的MySQL数据库管理员(DBA)需要的操作。因此这个集群几乎可以自己独立运行。其中一个核心的自动化组件是一个称之为MPS的系统,“MySQL Pool Scanner”的缩写。
MPS是一个复杂的状态机,大多由Python编写。它能替代一个DBA执行很多日常任务并且使我们能批量执行操作很少或根本没有人工干预。
单个数据库节点的详细观察
成千上万的服务器中的每一个,我们都能存储固定数量的MySQL实例。一个实例是一个独立的MySQL进程,监听在一个分离的端口,通过它自己的数据设置。为了简单起见,我们假设在图表和例子中每个服务器恰好是两个实例。
整个数据集被分割为成千上万的碎片,每个实例拥有一组这样的碎片,每个都在它自己的数据库模式中。一个Facebook用户的概况被创建时,它会被分配给一个碎片。每个碎片拥有成千上万用户的关系。
通过一个简单的数据库服务器图就很容易解释:
每个实例都有几个数据拷贝在不同服务器的其它实例上,别切他们通常在不同的数据中心。这样做主要是为了两个目标:
- 高可用性——如果一个服务宕机,我们会有有效地数据在别的地方继续服务。
- 性能——不同的地理区域都有自己的副本 ,以便本地服务读取。
我们通过简单的MySQL主/备复制的方式实现这一目标。每个实例是一个拷贝集合的一部分。一个拷贝集合包括一个主和多个备。所有到拷贝集合的写都必须发生在主库。备库订阅这些写的事件流,而且这些时间会在备库尽可能快的重演。当主库和备库有几乎相同的数据,读取可以发生在拷贝机和的任意一个实例上。
这一个简单的拷贝集合的图,每个服务主机只有一个实例,其它实例是空的(我们称之为备件):
实例的服务器本质上是一个容器,所以事实上事情会更复杂。
打个比方,单个服务器管理一个主实例可能也会托管其它主库的一个备份实例,类似这样:
MPS依赖于两个重要的“构件”操作:
1. 创建一拷贝/放置一个服务器
第一个构件是一个创建一个实例拷贝到不同主机的操作。我们使用一个Xtrabackup的修改版本执行复制操作。替代是相同的操作,只要我们在复制成功完成后删除实例。
首先,系统分配一个新的备用实例。我们选择一个备库或主库然后拷贝它的数据到新分批的备用实例。这个图展示了一个替换操作,当复制完成,实例将会被移除。
2. 升级一个主实例
第二个构件是在一个拷贝集合里把一个不同的实例升级到主实例。
在升级期间,我们选择一个升级目标,停止对拷贝集合的写,更改备库的主从关系到新主库,然后恢复写。在图中,我们展示一个删除操作,老主库在升级成功完成后被丢弃。为了简单起见,下列的拷贝集合中只有三个实例。
这两个操作(通常在大多运行MySQL的公司都需要复杂的流程)能被完全自动化,MPS每天能快速和安全地运行它们成百上千次,没有任何人工干预。
主机管理和状态
我们已经得到了基本的方法,我们能利用这些构件更深入地抽象概念。
MPS有一个保存实时声明和所有元数据库主机,以及当前和过去的MPS复制操作的仓库。这个注册表由数据库服务器本身管理,因此数据库集群的扩容和MPS不需要复杂的应用服务器设置。MPS自己事实上是无状态的,运行在自己的主机池中,别切依赖于库声明的管理。声明分别被并行处理。
当服务器在数据中心醒来(打个比方,一个新架构被连接和配置),它会每几分钟开始运行一个本地的客户端。这个客户端会执行以下步骤。
1. 收集自身数据。(我在哪里?我有什么硬件?我运行在哪个版本的软件上?)
2. 分类主机的问题。(我能在一个活动的集群上苏醒么?我的磁盘是否正常?我的闪存卡是否健康?)
3. 确认服务器被注册,并且包含最新中央存储库中的元数据。
4. 在第一次运行,如果没有这个服务器的当前记录,服务器上的实例处于初始“reimage(重装)”状态。这就是MPS上新服务开始的地方。
5. 所以每隔几分钟,每个健康服务检查他的中心仓库并且更新它是怎么做的,允许数据使用和系统健康保持同步。
目前的最小MPS管理单元是个实例。每个实例能在各种状态。重要的几个状态如下。
- 生产:实例服务生产流量。
- 备件:实例可以被拷贝或者被分配给一些别的任务。
- 备用分配:实例已经被选择为一个拷贝目标,并且拷贝正在执行。
- 备用释放:临时的状态,实例已经被从生产删除,等待筛选和清理。没有实例会在这里超过几分钟。
- 排出:实例未被使用,再被测试,数据中心维护,等等。操作员被请求介入的一系列状态。
- 重装:服务和所有实例位于此状态意味着在重装或者在被修理。在这个状态的服务被称之为Windwx的co-system切换和管理,这在以前的帖子中讨论过。
一个实例可能通过MPS执行一个动作而造成在两个状态之间移动,或者是操作员介入。这个状态图展示了主要状态和可能的动作,一个实例可能在它们直接年改变状态。
上图描述仅仅是MPS中实例可能执行的轨迹的一个小子集。这个状态改变的描述通过简单的复制和维护运作。实例还有很多其它原因的状态改变,以及硬编码所有选项和检查会使得软件维护困难和复杂。碰到“问题”,是MPS的另一个基本状态。
“问题”是一个连接到实例的属性。如果主机上所有实例有这个问题,我们认为这是服务器本身的问题。另一个思考问题的方式就像标签。MPS咨询一个决策矩阵,它能帮助它决策一个实例的特定问题。它是基于一个元组之间的映射:(状态,问题)-(行为,状态)。
这里有一些例子帮助理解:
- (产品,低空间)-(替换,备用释放):替换一个生产状态下空间有限的实例,把它移动到一个不同的服务器。
- (备用释放,老内核)-(移动,重装):如果一个实例发生移动到这个状态,它就没有生产数据在那里,因此为何不重装它?
- (产品,master-in-fallback-location)-(升级,产品):我们应该升级这个主库实例到正确的位置,然后把实例留在产品状态。
MPS中的各种状态和问题让我们床在一个灵活和可维护的设施来管理一个服务器的生命周期。
常见的故障解决和维护操作的例子。
在一个大数据中心,每天会有数十个甚至上百个服务器问题。这里有一些常见的例子,MPS能处理常见的日常故障而不用人工干预。
- 损坏的备库实例被检测和损坏,直到在后台被取代。
- 损坏的主库实例被降级,这样健康的副本就可以在后台代替他们兄弟。
- 服务器上的实力可能由于增长而空间耗尽被移动到未充分利用的服务器。
成千上万的服务器,站点维护任务,比如升级新内核,更改分区大小,或者升级固件控制器变得非常复杂。这同样适用于局部操作,比如一动一些货架或为工程团队分配测试服务器。下面是一些常见的维护操作,操作员可以通过简单的命令让MPS执行。
- 排出任意数量的数据库机架来维护和把他们移出产品。大多数这样的操作会在不到24小时内完成。
- 重装成千上万的机器(比如执行内核升级)在一个指定的并发。MPS会替代每个机器并且把它们发送到Windex。
- 分配任意数量的备件用于新项目或测试。需要200台服务运行测试?没问题。
- 创建一个新数据中心里的全部Facebook数据集合的拷贝。在指定的并发——比如在new Lulea建立我们的新数据中心。
通过MPS自动化常规任务让我们更好地扩展我们管理的服务器数量,并且解放MySQL操作组去做更多令人兴奋的挑战。
作者:Shlomo Priymak 是一个MySQL数据库工程师,在MySQL操作组。
转载请注明:旅途@KryptosX » 【翻译】揭秘:MySQL Pool Scanner(MPS)