GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇

自 2008 年成立以来,GitHub 的数据库系统经历了多次重大的演变,以适应不断增长的用户基础和不断变化的技术需求。GitHub 一直使用 MySQL 数据库,其中保存了除了 git 代码仓库以外的其他所有元数据,诸如用户,issue,PR, Gist 这些。在 2023 年结束之际,我们就一起来回顾一下这 15 年来 GitHub 数据库的演进之路。

起步 (2007 ~ 2009)

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第1张图片

第 1 个仓库诞生于 2007 年的 10 月 29 日,而第 1000 个则是在来年的 2 月 25 日。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第2张图片

GitHub 是一个 Rails 应用,这个主应用在内部叫做 Monolith,称呼也一直沿用至今。GitHub 一开始是跑在 Engine Yard 上的,从 Logo 上也可以看出 Engine Yard 和 Rails 社区的渊源。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第3张图片

不过因为 GitHub 的增长过快,以及商业化路线和 Engine Yard 初衷有偏离,所以 GitHub 很快又迁移到了 Rackspace。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第4张图片

Rackspace 是一个如今已经陌生的名字,但在 2009 年还是云服务的首选,上面是 GitHub 当时的评估。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第5张图片

这个阶段的数据库架构也比较简单,MySQL(这个时间点应该是 5.0 或者 5.1),一主一备,通过 DRBD 同步。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第6张图片

确定领域模型 (2010)

GitHub 在 2010 年,经过 2 年不断的打磨,终于发布了大家如今熟悉的 PR 工作流。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第7张图片

也是在同一时期,引入了 Organization 这个概念。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第8张图片

所以从领域模型来看,GitHub 从 2010 后就再也没有变过。

迁移数据中心以及第一次拆库 (2013)

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第9张图片

GitHub 把数据库迁移到了新的数据中心,升级了存储和网络。同时也把历史数据拆分到了单独的集群。立竿见影,页面加载速度大幅提升。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第10张图片

读写分离,大表变更,高可用 HA (2015 ~ 2019)

这个阶段围绕 MySQL 打造了一系列中间件。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第11张图片

引入 ProxySQL,做读写分离。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第12张图片

不满足已有的基于 trigger 的方案,GitHub 自研了 triggerless 的 gh-ost 来做大表无锁变更。如今被 GitHub 开源的 gh-ost 也是业界最主流的 MySQL 大表变更方案。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第13张图片

再结合自研的 Orchestrator + Consul + HAProxy 做了高可用 HA 方案。

虽然没有找到相关资料,但这个阶段 GitHub 至少把 MySQL 升级到了 5.6,因为 Orchestrator 需要依赖 5.6 引入的 GTID (global transaction identifier)。

另外在 2018 年,Microsoft 以 75 亿美元收购了 GitHub。

GitHub 联创/CEO Chris Wanstrath, Microsoft CEO Satya Nadella, 收购后 GitHub 第一任 CEO Nat Friedman

变更自动化 (2020)

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第14张图片

随着 GitHub 模块越来越多,处理数据库变更成为了数据库团队的瓶颈。于是他们通过 GitHub PR + GitHub Actions + skeema 做了一套自动化的方案,这套方案的亮点在于:

  1. Schema as code,用对待代码变更的方式对待数据库变更。开发只要定义最终期望的 schema,比如 CREATE TABLE 语句,然后通过 skeema 来自动计算出需要 ALTER TABLE 语句。
  2. 基于 GitHub 本身的 PR, Actions 能力构建工作流。

引入微服务,进一步拆库 (2019 ~ 2021)

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第15张图片

这时 Rails + MySQL 主集群 mysql1 的架构支撑了 GitHub 12 年的发展。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第16张图片

同时在外部用户和内部组织增长的背景下,GitHub 开始引入微服务,对系统进行模块化。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第17张图片

数据库层面做了几个事情,定义好服务和数据的归属关系,要获取归属于其他服务的数据,只能通过 API 的方式。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第18张图片

确立系统边界,用于做垂直分片 (Vertical Partitioning)。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第19张图片

同时也对一些表比如用户表引入水平分片 (Horizontal Sharding),提升隔离性,降低爆炸半径 (Blast Radius)。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第20张图片

也是在这个过程中,GitHub 引入了基于 MySQL 的分布式数据库集群方案 Vitess。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第21张图片

2019 项目启动时,单 mysql1 主集群承担 950,000 QPS。到 2021 年,拆分完的多个集群共同承担 1,200,000 QPS。同时每一个数据库节点的负载则下降了一半。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第22张图片

也是在 2021 年,GitHub 发布了 Copilot,开启了这一轮 AI 革命的序幕。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第23张图片

成长的烦恼 (2022)

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第24张图片

即使对 mysql1 主集群做了拆分,但依然跟不上 GitHub 的高速发展。比如在 2022 年 3 月份,就接连发生了 4 次数据库导致的故障,官方也不得不出面解释。故障频发一方面是负载增大,另一方面是为了应对负载,开始继续对 mysql1 做拆库。但在这个过程中,因为配置失误,又导致了故障。开着飞机换引擎风险是高,但 GitHub 也确实没有了当年可以停机升级数据库的奢侈了。

升级到 8.0 (2023)

随着 MySQL 5.7 EOL 的临近,GitHub 开始做 5.7 到 8.0 的迁移。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第25张图片

这时的 GitHub 已经达到了 1200+ 的 MySQL 节点。而 QPS 达到了 5,500,000,相比 21 年披露的 1,200,000,又翻了好几倍,足见 GitHub 发展的迅猛!

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第26张图片

鉴于 GitHub 的体量,以及 5.7 到 8.0 本身是一场大版本升级,所以 GitHub 设计了相当复杂的升级方案,主要是应对回滚。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第27张图片

引入微服务后,GitHub 应用有了不同的技术栈,但整体上 GitHub 还是以 Rails 为主,都用 Trilogy 连接数据库。这点保障了升级时的前后兼容性。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第28张图片

升级过程也吃到了之前拆库的红利。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第29张图片

不过另一方面之前引入的 Vitess 也造成了一些麻烦。

整体回顾

最后再来看一下当前 GitHub 的整体架构,通过网上拼凑的信息,大体如下

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第30张图片

GitHub 拆分了一些微服务,但核心仍然是 Monolith 这个 Rails 应用。最核心的数据库依然是 mysql1 的 MySQL 集群,由一主多备组成。有些业务域,垂直拆分出了单独的数据库集群,同时也引入 Vitess 做水平拆分。此外还有用于缓存的 Redis 和用于搜索的 ElasticSearch。

GitHub 的数据库演进分三条线:

  • 基础设施。迁移数据中心,升级 MySQL 版本。
  • 应用架构。读写分离,高可用,分库。
  • 数据库变更流程。大表变更,变更自动化。

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第31张图片

GitHub 在早年分享时就讲过自己的数据库故事挺无趣的,这么多年了,应用架构和数据模型都没怎么变,15 年前的 MySQL 集群也依然是今天的核心。
以上就是 GitHub 数据库 15 年的进化之路。最后再讲一个插曲

GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第32张图片
GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇_第33张图片

GitHub 联创 Chris 提到当年曾差点把 GitHub 从 MySQL 转到 Postgres,临门一脚卡在了重写一条 GROUP BY 语句上。

不过无论是选择 MySQL 还是 PG,GitHub 多半都能达到今天的高度。总之,我们应该采用无聊的技术去构建创新的产品,而不是倒过来。

GitHub 相关文章


更多资讯,请关注 Bytebase 公号:Bytebase

你可能感兴趣的:(GitHub 数据库 15 年进化史:幕后英雄如何成就 Copilot 传奇)