GitHub 跑了 1200 多台 MySQL 主机,如何实现无缝升级到 8.0 版本?

news2024/12/30 1:51:14

文章目录

  • 翻译概述
  • 前言
  • 升级的动机
  • GitHub 的 MySQL 基础设施
  • 准备旅程
  • 准备基础设施以进行升级
  • 确保应用程序兼容性
  • 沟通和透明度
  • 升级计划
    • 第 1 步:滚动副本升级
    • 步骤 2:更新复制拓扑
    • 步骤 3:将 MySQL 8.0 主机提升为主主机
    • 步骤 4:升级面向内部的实例类型
    • 步骤 5:清理
  • 回滚能力
  • 挑战
    • Vitess
    • 复制延迟
    • 查询可以通过 CI,但在生产中会失败
  • 经验教训和收获
  • 结论
  • 原文地址
  • 个人简介

翻译概述

  • GitHub 团队近日分享了他们将 GitHub.com 的底层数据库无缝升级到 MySQL 8.0 的经验,我们来看看他们是如何完成了这一壮举。

前言

  • 15 年前,GitHub 最初是一个带有单个 MySQL 数据库的 Ruby on Rails 应用程序。从那时起,GitHub 不断发展其 MySQL 架构,以满足平台的扩展和弹性需求,包括构建高可用性、实现测试自动化和数据分区。如今,MySQL 仍然是 GitHub 基础设施和我们选择的关系数据库的核心部分。
  • 这是我们如何将 1200 多台 MySQL 主机升级到 8.0 的故事。在不影响我们的服务级别目标 (SLO) 的情况下升级机群绝非易事 - 规划、测试和升级本身花费了一年多的时间,并且需要 GitHub 内多个团队的协作。

升级的动机

  • 为什么要升级到MySQL 8.0?随着MySQL 5.7 的生命周期即将结束,我们将我们的机群升级到了下一个主要版本 MySQL 8.0。我们还希望使用能够获得最新安全补丁、错误修复和性能增强的 MySQL 版本。我们还想测试 8.0 中的一些新功能并从中受益,包括即时 DDL、不可见索引和压缩 bin 日志等。

GitHub 的 MySQL 基础设施

在我们深入了解如何进行升级之前,让我们先从 10,000 英尺的高度看一下我们的 MySQL 基础设施:

  • 我们的机群设施由 1200 多台主机组成。它是我们数据中心中的 Azure 虚拟机和裸机主机的组合。
  • 我们存储超过 300 TB 的数据,并在 50 多个数据库集群中每秒处理 550 万次查询。
  • 每个集群都配置为具有主加副本集群设置的高可用性。
  • 我们的数据是分区的。我们利用水平和垂直分片来扩展 MySQL 集群。我们有 MySQL 集群来存储特定产品领域的数据。我们还为大域区域提供了水平分片的Vitess集群,这些区域的增长超出了单主 MySQL 集群的规模。
  • 我们拥有一个庞大的工具生态系统,包括 Percona Toolkit、gh-ost、orchestrator、freno和用于操作车队的内部自动化。

所有这些总结起来就是一个多样化且复杂的部署,需要在维护我们的 SLO 的同时进行升级。

准备旅程

作为 GitHub 的主要数据存储,我们对可用性保持高标准。由于我们的机群规模和 MySQL 基础设施的重要性,我们对升级过程提出了一些要求:

  • 我们必须能够升级每个 MySQL 数据库,同时遵守我们的服务级别目标 (SLO) 和服务级别协议 (SLA)。
  • 我们无法解释测试和验证阶段的所有故障模式。因此,为了保持在 SLO 范围内,我们需要能够回滚到 MySQL 5.7 的先前版本而不中断服务。
  • 我们的 MySQL 队列中的工作负载非常多样化。为了降低风险,我们需要自动升级每个数据库集群并安排其他重大更改。这意味着升级过程将是一个漫长的过程。因此,我们从一开始就知道我们需要能够维持运行混合版本环境。

升级准备工作于 2022 年 7 月开始,即使在升级单个生产数据库之前,我们也需要实现几个里程碑。

准备基础设施以进行升级

  • 我们需要为 MySQL 8.0 确定适当的默认值并执行一些基准性能基准测试。由于我们需要操作两个版本的 MySQL,因此我们的工具和自动化需要能够处理混合版本,并了解 5.7 和 8.0 之间新的、不同的或已弃用的语法。

确保应用程序兼容性

  • 我们将 MySQL 8.0 添加到了所有使用 MySQL 的应用程序的持续集成 (CI) 中。我们在 CI 中并行运行 MySQL 5.7 和 8.0,以确保在长时间的升级过程中不会出现回归。我们检测到 CI 中的各种错误和不兼容性,帮助我们删除任何不受支持的配置或功能,并转义任何新的保留关键字。
  • 为了帮助应用程序开发人员过渡到 MySQL 8.0,我们还启用了一个选项,可以在 GitHub Codespaces 中选择 MySQL 8.0 预构建容器进行调试,并提供 MySQL 8.0 开发集群以进行额外的预生产测试。

沟通和透明度

  • 我们使用 GitHub Projects 创建滚动日历来在内部沟通和跟踪我们的升级计划。我们创建了问题模板来跟踪应用程序团队和数据库团队的清单以协调升级。

用于跟踪 MySQL 8.0 升级计划的项目板

升级计划

  • 为了满足我们的可用性标准,我们采取了逐步升级策略,允许在整个过程中进行检查点和回滚。

第 1 步:滚动副本升级

  • 我们首先升级单个副本并在其仍处于离线状态时进行监控,以确保基本功能稳定。然后,我们启用生产流量并继续监控查询延迟、系统指标和应用程序指标。我们逐渐将8.0副本上线,直到升级整个数据中心,然后迭代其他数据中心。我们在线保留了足够的 5.7 副本以便回滚,但我们禁用了生产流量以开始通过 8.0 服务器提供所有读取流量。

副本升级策略涉及在每个数据中心 (DC) 逐步推出

步骤 2:更新复制拓扑

  • 一旦所有只读流量都通过 8.0 副本提供服务,我们就调整了复制拓扑,如下所示:
8.0 主候选配置为直接在当前 5.7 主候选下复制。
在该 8.0 副本的下游创建了两个复制链:
* 一组仅 5.7 个副本(不提供流量,但已准备好以防回滚)。
* 一组仅 8.0 副本(服务流量)。
拓扑仅在很短的时间内(最多几小时)处于这种状态,直到我们进入下一步。

为了方便升级,拓扑已更新为具有两个复制链

步骤 3:将 MySQL 8.0 主机提升为主主机

  • 我们选择不在主数据库主机上进行直接升级。相反,我们将通过使用Orchestrator执行的优雅故障转移将 MySQL 8.0 副本提升为主副本。此时,复制拓扑由一个 8.0 主数据库和两个附加到其上的复制链组成:一组用于回滚的脱机 5.7 副本和一组服务 8.0 副本。
  • Orchestrator 还配置为将 5.7 主机列入黑名单作为潜在的故障转移候选者,以防止在发生计划外故障转移时意外回滚。

主要故障转移和完成数据库 MySQL 8.0 升级的其他步骤

步骤 4:升级面向内部的实例类型

  • 我们还有用于备份或非生产工作负载的辅助服务器。这些随后被升级以保持一致性。

步骤 5:清理

  • 一旦我们确认集群不需要回滚并成功升级到8.0,我们就删除了5.7服务器。验证包括至少一个完整的 24 小时流量周期,以确保在高峰流量期间不会出现问题。

回滚能力

  • 确保升级策略安全的核心部分是保持回滚到 MySQL 5.7 之前版本的能力。对于只读副本,我们确保有足够的 5.7 副本保持在线状态来服务生产流量负载,如果 8.0 副本性能不佳,则通过禁用它们来启动回滚。对于主服务器,为了在不丢失数据或不中断服务的情况下回滚,我们需要能够在 8.0 和 5.7 之间维持向后数据复制。

  • MySQL 支持从一个版本到下一个更高版本的复制,但不明确支持相反的操作(MySQL 复制兼容性)。当我们在临时集群上测试将 8.0 主机升级为主主机时,我们发现所有 5.7 副本上的复制都中断了。我们需要克服几个问题:

    • 1、在 MySQL 8.0 中,utf8mb4是默认字符集,并使用更现代的utf8mb4_0900_ai_ci排序规则作为默认值。MySQL 5.7 之前的版本支持utf8mb4_unicode_520_ci排序规则,但不支持最新版本的 Unicode utf8mb4_0900_ai_ci。
    • 2、MySQL 8.0引入了管理权限的角色,但 MySQL 5.7 中不存在此功能。当 8.0 实例提升为集群中的主实例时,我们遇到了问题。我们的配置管理正在扩展某些权限集以包含角色语句并执行它们,这破坏了 5.7 副本中的下游复制。我们通过在升级窗口期间临时调整受影响用户的定义权限来解决此问题。
  • 为了解决字符排序规则不兼容的问题,我们必须将默认字符编码设置为utf8并将排序规则设置为utf8_unicode_ci。

  • 对于 GitHub.com 整体,我们的 Rails 配置确保了字符排序规则的一致性,并使数据库的客户端配置标准化变得更加容易。因此,我们非常有信心能够为最关键的应用程序维持向后复制。

挑战

  • 在我们的测试、准备和升级过程中,我们遇到了一些技术挑战。

Vitess

  • 我们使用 Vitess 来水平分片关系数据。在大多数情况下,升级我们的 Vitess 集群与升级 MySQL 集群没有太大区别。我们已经在 CI 中运行 Vitess,因此我们能够验证查询兼容性。在我们的分片集群升级策略中,我们一次升级一个分片。VTgate(Vitess 代理层)通告 MySQL 的版本,某些客户端行为取决于此版本信息。例如,一个应用程序使用的 Java 客户端禁用了 5.7 服务器的查询缓存,因为查询缓存在 8.0 中被删除,因此它会为它们生成阻塞错误。因此,一旦单个 MySQL 主机针对给定的键空间进行了升级,我们就必须确保我们还更新了 VTgate 设置以宣传 8.0。

复制延迟

  • 我们使用只读副本来扩展读取可用性。GitHub.com 需要低复制延迟才能提供最新数据。
  • 在我们测试的早期,我们在 MySQL 中遇到了一个复制错误,该错误已在 8.0.28 上修补:

bug

  • 我们碰巧满足了解决此错误的所有标准:
    • 我们使用是replica_preserve_commit_order因为我们使用基于 GTID 的复制。
    • 我们的许多集群,当然还有所有最关键的集群,在很长一段时间内都承受着密集的负载。我们的大多数集群的写入量都很大。
  • 由于这个错误已经在上游修复,我们只需要确保部署高于 8.0.28 的 MySQL 版本即可。
  • 我们还观察到,导致复制延迟的大量写入在 MySQL 8.0 中更加严重。这使得我们避免大量写入变得更加重要。在 GitHub,我们使用freno根据复制延迟来限制写入工作负载。

查询可以通过 CI,但在生产中会失败

  • 我们知道我们不可避免地会在生产环境中第一次遇到问题,因此我们采取了逐步升级副本的策略。我们遇到过通过 CI 但在生产环境中遇到实际工作负载时会失败的查询。最值得注意的是,我们遇到了一个问题,即带有大WHERE IN子句的查询会导致 MySQL 崩溃。我们有WHERE IN包含数万个值的大型查询。在这些情况下,我们需要在继续升级过程之前重写查询。查询采样有助于跟踪和检测这些问题。在 GitHub,我们使用Solarwinds DPM (VividCortex)(一种 SaaS 数据库性能监视器)来实现查询可观察性。

经验教训和收获

  • 从测试、性能调整到解决已发现的问题,整个升级过程花费了一年多的时间,并涉及来自 GitHub 多个团队的工程师。我们将整个集群升级到 MySQL 8.0,包括临时集群、支持 GitHub.com 的生产集群以及支持内部工具的实例。此次升级凸显了我们的可观察性平台、测试计划和回滚能力的重要性。测试和逐步推出策略使我们能够及早发现问题并减少主要升级遇到新故障模式的可能性。
  • 虽然有逐步推出的策略,但我们仍然需要能够在每一步进行回滚,并且需要可观察性来识别信号以指示何时需要回滚。启用回滚最具挑战性的方面是保持从新的 8.0 主副本到 5.7 副本的向后复制。我们了解到,Trilogy 客户端库中的一致性使我们在连接行为方面具有更高的可预测性,并使我们确信来自主要 Rails 整体的连接不会破坏向后复制。
  • 然而,对于我们的一些 MySQL 集群来说,这些集群具有来自不同框架/语言的多个不同客户端的连接,我们发现向后复制在几个小时内就中断了,这缩短了回滚的机会窗口。幸运的是,这些情况很少,而且我们没有遇到在需要回滚之前复制中断的情况。但对我们来说,这是一个教训,即了解已知且易于理解的客户端连接配置是有好处的。它强调了制定指导方针和框架以确保此类配置的一致性的价值。
  • 之前对数据进行分区的努力得到了回报——它使我们能够针对不同的数据域进行更有针对性的升级。这很重要,因为一个失败的查询会阻止整个集群的升级,并且对不同的工作负载进行分区允许我们进行零碎升级并减少在此过程中遇到的未知风险的影响范围。这里的权衡是,这也意味着我们的 MySQL 机群已经增长。
  • 上次 GitHub 升级 MySQL 版本时,我们有 5 个数据库集群,现在我们有 50 多个集群。为了成功升级,我们必须投资于可观察性、工具和管理车队的流程。

结论

  • MySQL 升级只是我们必须执行的一种日常维护 - 对于我们在机群上运行的任何软件来说,拥有一个升级路径至关重要。作为升级项目的一部分,我们开发了新的流程和操作能力来成功完成MySQL版本升级。然而,我们在升级过程中仍然有太多需要手动干预的步骤,我们希望减少完成未来 MySQL 升级所需的工作量和时间。
  • 我们预计,随着 GitHub.com 的发展,我们的集群将继续增长,并且我们的目标是进一步分区数据,这将随着时间的推移增加 MySQL 集群的数量。构建操作任务的自动化和自我修复功能可以帮助我们在未来扩展 MySQL 操作。我们相信,投资于可靠的车队管理和自动化将使我们能够扩展 github 并跟上所需的维护,从而提供更具可预测性和弹性的系统。
  • 该项目的经验教训为我们的 MySQL 自动化奠定了基础,并将为未来更高效地进行升级铺平道路,但仍保持相同水平的维护和安全。

原文地址

  • 2023-12-07-upgrading-github-com-to-mysql-8-0

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。

🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。

💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1302665.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】地址空间

本片博客将重点回答三个问题 什么是地址空间? 地址空间是如何设计的? 为什么要有地址空间? 程序地址空间排布图 在32位下,一个进程的地址空间,取值范围是0x0000 0000~ 0xFFFF FFFF 回答三个问题之前我们先来证明地址空…

openlayers-19-分屏对比

分屏对比实现很简单&#xff0c;定义两个map对象&#xff0c;然后让这两个map对象共用一个view即可。 代码如下&#xff1a; <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd…

Linux上编译和测试V8引擎源码

介绍 V8引擎是一款高性能的JavaScript引擎&#xff0c;广泛应用于Chrome浏览器和Node.js等项目中。在本篇博客中&#xff0c;我们将介绍如何在Linux系统上使用depot_tools工具编译和测试V8引擎源码。 步骤一&#xff1a;安装depot_tools depot_tools是一个用于Chromium开发…

【深度学习】强化学习(五)深度强化学习

文章目录 一、强化学习问题1、交互的对象2、强化学习的基本要素3、策略&#xff08;Policy&#xff09;4、马尔可夫决策过程5、强化学习的目标函数6、值函数7、深度强化学习1. 背景与动机2. 关键要素3. 成功案例4. 挑战和未来展望5. 核心概念和方法总结 一、强化学习问题 强化学…

微服务网关组件Gateway实战

1. 需求背景 在微服务架构中&#xff0c;通常一个系统会被拆分为多个微服务&#xff0c;面对这么多微服务客户端应该如何去调用呢&#xff1f;如果根据每个微服务的地址发起调用&#xff0c;存在如下问题&#xff1a; 客户端多次请求不同的微服务&#xff0c;会增加客户端代码…

【LLM】大模型之RLHF和替代方法(DPO、RAILF、ReST等)

note SFT使用交叉熵损失函数&#xff0c;目标是调整参数使模型输出与标准答案一致&#xff0c;不能从整体把控output质量&#xff0c;RLHF&#xff08;分为奖励模型训练、近端策略优化两个步骤&#xff09;则是将output作为一个整体考虑&#xff0c;优化目标是使模型生成高质量…

如何在Linux本地部署openGauss开源数据管理系统并结合内网穿透公网访问

文章目录 前言1. Linux 安装 openGauss2. Linux 安装cpolar3. 创建openGauss主节点端口号公网地址4. 远程连接openGauss5. 固定连接TCP公网地址6. 固定地址连接测试 前言 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行。openGauss内核深度融合…

恢复Django 项目

随笔记录 目录 1. 重建Mysql DB 2. 启动Django 项目 2.1 确保你的系统上已安装pip工具。你可以使用以下命令来检查pip是否已安装 2.2 安装Packages 2.2.1 安装Django 2.2.2 安装pymysql 2.2.3 安装 kafka 2.2.4 安装 requests 2.2.5 安装simplepro 2.2.6 安装libjp…

作为一个产品经理带你了解Axure的安装和基本使用

1.Axure的简介 Axure是一种强大的原型设计工具&#xff0c;它允许用户创建交互式的、高保真度的原型&#xff0c;以及进行用户体验设计和界面设计。Axure可以帮助设计师和产品经理快速创建和共享原型&#xff0c;以便团队成员之间进行沟通和反馈。Axure提供了丰富的交互组件和功…

体系化学习运筹学基础算法的实践和总结

文章目录 引言目标设计目标实践文章汇总经验总结一则预告 引言 眨眼间已经12月了&#xff0c;眼看着2023年马上要过完了。 女朋友最近总说&#xff0c;工作以后感觉时间过的好快。事实上&#xff0c;我也是这么认为的。年纪越大&#xff0c;越会担心35岁危机的降临。所以&…

Rocket MQ 架构介绍

文章目录 为什么选择Rocket MQ基本概念优点缺点架构图编程模型发送者发送消息固定步骤消费者消费消息固定步骤 为什么选择Rocket MQ Rocket MQ是阿帕奇顶级的开源项目&#xff0c;由阿里开发并开源。它的研发背景是Active MQ与Kafka不能很好的解决当时的业务场景。官网上是这么…

【rabbitMQ】Exchanges交换机

上一篇&#xff1a;springboot整合rabbitMQ模拟简单收发消息 https://blog.csdn.net/m0_67930426/article/details/134904766 本篇代码基于上一篇继续写 目录 Fanout 交换机 1. add queue 2. add Exchange 3.绑定队列 Direct 交换机 1. add queue 2. add Exchange 3.…

求职智能分析系统

本项目是一个基于Flask轻量级框架的计算机就业数据可视化分析平台。 采用echarts和ajax等技术进行数据展示和用户交互。

Mybatis是如何进行分页的?

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

【Linux】gdb-调试代码的工具

目录 一、概述 1.1 gdb是什么 1.2 为什么要使用gdb 二、gdb的简单使用 2.1 安装gdb 2.2 软件的debug版本和release版本 2.3 使用gdb 在之前的学习中&#xff0c;我们已经能够用vim编写和gcc/g编译代码了&#xff0c;下面来学习如何调试代码。 一、概述 1.1 gdb是什么 …

扩展学习|商业智能和分析:从大数据到大影响

文献来源&#xff1a;Chen H, Chiang R H L, Storey V C. Business intelligence and analytics: From big data to big impact[J]. MIS quarterly, 2012: 1165-1188. 下载链接&#xff1a;https://pan.baidu.com/s/1JoHcTbwdc1TPGnwXsL4kIA 提取码&#xff1a;a8uy 在不同的组…

【USRP】LFTX / LFRX

LFTX/LFRX 设备概述 LFTX 子板利用两个高速运算放大器来允许 0-30 MHz 的传输。该板仅接受实模式信号。LFTX 非常适合 HF 频段的应用&#xff0c;或使用外部前端来上变频和放大中间信号的应用。LFTX 的输出可以独立处理&#xff0c;也可以作为单个 I/Q 对进行处理。 主要特征…

基于SpringBoot+Vue会员制医疗预约服务管理信息系统(Java毕业设计)

点击咨询源码 大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的…

vue零基础

vue 与其他框架的对比 框架设计模式数据绑定灵活度文件模式复杂性学习曲线生态VueMVVM双向灵活单文件小缓完善ReactMVC单向较灵活all in js大陡丰富AngularMVC双向固定多文件较大较陡&#xff08;Typescript&#xff09;独立 更多对比细节&#xff1a;vue 官网&#xff1a;ht…

【人工智能 | 知识表示方法】状态空间法 语义网络,良好的知识表示是解题的关键!(笔记总结系列)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…