[博客翻译]MySQL在优步


原文地址:https://www.uber.com/blog/mysql-at-uber/?uclick_id=8d2a6f71-8db1-4c60-b724-fc9bd70cd9fd


在Uber,MySQL®数据库群集是数据基础设施的核心,支持着平台各种关键操作。Uber运行着一个庞大的MySQL群集,包含超过2300个独立的集群。构建一个能够管理如此大规模群集的控制平面,同时确保零停机时间和无数据丢失,这是行业中最具挑战性的问题之一。

提升可用性

在过去几年中,我们致力于将MySQL群集的可用性从99.9%提升到99.99%,通过多种优化和对控制平面的重新架构实现了这一目标。这是我们关于Uber MySQL部署和操作多部分博客系列的第一篇文章。本文将讨论Uber的MySQL群集架构、控制平面操作以及过去几年中在MySQL控制平面层面上的一些改进。

架构概览

Uber的MySQL群集由多个集群组成,每个集群有众多节点。主要有两种流程:数据流,客户端/服务与MySQL集群交互;控制流,管理集群生命周期。

对于数据流,托管在Kubernetes®上的无状态服务通过标准客户端连接到其MySQL集群。每个服务器都有一个反向代理,它根据角色(主/副本/批处理)存储MySQL节点的路由映射。这使得客户端能够根据要执行的查询,使用JDBC™协议发现并连接到适当的集群。

控制流负责管理集群和节点的供应、维护和退役,同时确保安全态势并与Uber生态系统集成。

MySQL群集的主要组件如图1所示:

  • 控制平面
  • 数据平面
  • 发现平面
  • 可观察性
  • 数据变更捕获和数据仓库摄取
  • 备份/恢复

图1:MySQL控制平面的解剖

控制平面

MySQL控制平面是一个基于状态的系统,由多个组件/服务和存储组成。核心技术管理者负责协调其他控制平面组件。其中一个关键职责是发布集群的目标状态或所需状态到Odin,这是Uber内部用于有状态技术的状态无关管理平台,还管理节点放置。管理者发布目标状态到Odin。目标状态包括关键配置,例如资源配置文件、节点数、角色(主/跟随者)、应在数据节点上运行的侧容器、服务器设置(如二进制日志格式、SQL模式)等。控制平面确保实际的MySQL集群或节点始终收敛到任何阶段定义的所需状态。

另一个关键技术管理者的角色是允许通过工作流更改系统状态。工作流是由Cadence支持的容错长期运行过程。一些工作流的例子包括在现有集群上添加新节点、在集群上执行主故障转移、应用某些MySQL变量到节点、更改MySQL副本的复制主节点等。技术管理者的其他关键功能如下:

  • 集群管理:处理创建、更新和删除集群的操作。
  • 主故障转移:更改集群的主节点。
  • 节点生命周期管理:通过添加、替换和删除MySQL服务器节点来管理节点生命周期。
  • 平衡放置:为Odin的放置引擎提供信号,以确保在所有部署Uber基础设施的地理区域中平衡放置服务器节点。这保证了对硬件故障甚至数据中心宕机的弹性。
  • 数据库操作:管理特定于数据库的操作,如系统变量设置、复制设置和扩展操作。

传统上,MySQL控制平面与底层基础设施过程紧密耦合。随着MySQL群集的增长,这导致基础设施放置操作被MySQL故障阻止。MySQL团队花费大量时间调试这些问题。这种耦合影响了60多个工作流的操作可靠性,包括主故障转移、节点替换等。此外,MySQL依赖基于Git的配置存储系统来管理集群状态,这并不是为此类用例优化的解决方案。这一切提出了可靠性和可扩展性问题,需要对整个控制平面进行重新架构。

控制器

作为控制平面重新设计的一部分,我们在MySQL控制平面中引入了一个名为控制器的组件。控制器充当所有MySQL集群的外部观察者,从数据库和其他控制平面组件收集信号。控制器包含一个规则评估器,监控这些信号并在任何集群中违反任何定义的规则时采取行动。控制器的关键角色之一是监控MySQL实例中主节点的健康状况,并在当前主节点出现问题时自动触发主故障转移。此外,控制器还确保在组复制设置中属于共识组的部分建立集群平衡。

关键流程的编排

与控制平面交互的主要机制是通过工作流。工作流是异步的、事件驱动的过程,定义为一系列步骤来编排复杂的长期任务。MySQL控制平面使用Cadence™来支持这些工作流,提供持久性、容错性和可扩展性。图2显示了MySQL控制平面中的典型工作流。

图2:优雅的主故障转移工作流

此次重新设计已彻底改革了所有控制平面操作。下一节将审查几个关键流程的编排。

主故障转移

在Uber,我们有一个单主多副本设置。写入由主节点处理,并通过标准MySQL二进制日志复制到副本。

图3:单主多副本设置

主故障转移是一个自动化过程,将集群的主节点从一个主机更改为另一个。由于只有一个主节点,保持其健康和运行对于保证高写入可用性和最小化停机时间至关重要。这些主故障转移工作流被用作组件的缓解措施,这些组件持续监控主节点的健康状况并在出现任何降级时执行故障转移。

根据现有主节点的健康状况,我们执行两种类型的故障转移:优雅型和紧急型。

优雅型升级是在当前主节点的一般维护活动期间需要的,例如当现有主节点所在的主机需要修复时。它们涉及选择一个新的主候选节点,然后优雅地将写负载从旧的主节点转移到新的主节点。优雅故障转移假设现有的主节点可用且健康。这适用于异步和半同步复制设置。还有涉及组复制的另一部署步骤,但不在本文讨论范围内。

优雅故障转移执行以下步骤:

  • 将当前主节点置于只读模式。
  • 停止当前主节点上的流量。
  • 选择一个新的主节点(主选举)。默认情况下,工作流从同一个数据中心选择主选举。还会考虑副本节点的复制延迟,优先选择具有最先进二进制日志位置的节点。
  • 获取前一个主节点的二进制日志位置,并等待这些事务在主选举中应用。
  • 启用新主节点的写入。

如果现有主节点不可用(由于数据中心区域故障或网络隔离),MySQL执行紧急故障转移。它执行与优雅升级相同的步骤,唯一的例外是它不会依赖当前主节点将所有数据复制到新的主节点,因为当前主节点被认为无法访问。

我们向下游服务保证99.99%的可用性,而主故障转移是我们实现此SLA的关键过程。

节点替换

在控制平面中替换节点涉及到在不影响该MySQL数据库用户的情况下,将MySQL节点(及其所有数据)从一个主机移动到另一个主机。

Uber的硬件基础设施分布在多个云提供商和本地数据中心,包括数十万台机器和其他硬件和网络组件。节点替换在MySQL控制平面中至关重要,可以保护群集免受此庞大规模基础设施的中断,并保持群集敏捷。节点替换工作流是一种维护活动,会在受影响主机上关闭节点,并在不同的主机上创建一个具有类似资源和地理位置的相同节点,整个过程对数据库用户完全透明,他们甚至不会意识到这个移动。

虽然看似简单的数据移动操作,节点替换也有一些细微之处:

  • 硬件配置:新节点必须与被替换的节点具有相同的硬件配置。这意味着它必须具有相同数量的CPU核心、磁盘和内存空间、端口等。
  • 共置:新节点必须放置在具有与所替代节点相同容错级别的主机上,以确保相同的网络延迟。客户只关心查询延迟保持一致,无论节点的位置如何。
  • 依赖关系:如果当前节点是拓扑中其他节点的复制父节点,则其子节点必须指向新的替换节点或连接到集群中的另一个节点。
  • 主提升:如果要替换的节点是集群的主节点,在其退役或退出流量之前,必须触发优雅的主提升以将写入职责转移到不同的主节点。

节点替换内部由两个独立的操作组成:节点添加和节点删除。

节点添加是引导过程,包括放置和数据预配。放置包括找到节点的位置。这涉及识别包含新节点所需资源的主机。数据同步包括在识别的节点上安装MySQL进程,然后从现有节点之一(最好是主节点)启动数据传输到新节点。节点添加过程旨在支持并行添加多个节点,这对灾难恢复场景特别有用。

节点删除是优雅地