解剖“全球最大男性交友网站”,GitHub十五年数据库架构演进

本文主要是介绍解剖“全球最大男性交友网站”,GitHub十五年数据库架构演进,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数据库编程大赛:一条SQL计算扑克牌24点

近期,GitHub全面升级到了MySQL 8.0。ITPUB特别邀请了NineData创始人、资深技术专家叶正盛老师,为大家解析GitHub历年数据库架构的发展历程,以及大型网站何时进行分库分表的改造。

图片

Hello,各位朋友!今天,我们一起来回顾GitHub,这个被程序员亲切地戏称为“全球最大的男性交友网站”的平台,在过去十五年的数据库架构演进历程。

GitHub自2008年上线以来,已经演变成全球最大的开源软件托管平台。在这里,约有1亿名程序员在这里贡献代码、交流思想。这背后,GitHub根据业务发展需求完成了数据库架构的多次升级,让我们一探究竟。尤其是大家比较关注的大型网站何时做分库分表的改造。

图片

2008年:单机的简约之始

图片

最初,GitHub非常简单,仅仅使用了一个单机的MySQL 5.0数据库。应用开发语言是Ruby on Rails,这个也是当时非常流行的开发语言和框架。

2009年:迈向主备架构

单机的数据库肯定是不合格的,可靠性风险太高,到了2009年,随着业务发展,GitHub迈向MySQL的主备架构,并采用了基于数据块同步的DRBD软件来执行主备复制,硬件上则是两台配备了8核32G内存和15,000转的SAS机械硬盘的服务器。

图片

2013年:性能提升与IDC搬迁

2011到2012年,GitHub将MySQL升级至5.1。

2013年,为了进一步增强数据库性能,GitHub执行了一次IDC搬迁,数据库硬件也得到了显著升级,尤其是采用了SSD固态硬盘和万兆网卡,这使得性能提升了一倍以上。期间,GitHub还进行了一次在线迁移,并宣布整个停机时间仅为13分钟,显示出了其在数据库管理上的高效能力。

细节上,GitHub通过进行大量历史数据清理,不仅节省了空间,并且提升了缓存的命中率。

这次升级后,GitHub的网页加载时间加快了一倍以上。

图片

2015-2016年:MySQL5.6/5.7

到了2015年初,GitHub进一步迈向MySQL 5.6,并在2016年升级至5.7。由于5.6到5.7都属于小版本升级,所以操作过程比较简单。根据业务拆分了很多集群,中间使用了ProxySQL代理服务,整体都是读写分离的技术架构。

图片

发布GHOST,创新地解决MySQLDDL锁表难题

MySQL表结构的变更往往会带来锁表问题。之前,通常使用Trigger(触发器)方案来解决。当时我在阿里巴巴集团工作时,对这个问题也非常关注,我们内部开发了一个名为MyDDL的软件。虽然我们考虑过通过解析binlog来减少服务器的影响,但由于技术难度,这个想法并未去实践。

2016年,GitHub推出了基于解析Binlog的GHOST(GitHub Online Schema Transformer)工具,实现了在线DDL的功能。这一解决方案现在在业界颇受欢迎,并且已经开源到了社区。

图片

重磅:分库分表架构升级

到了2019年,根据GitHub的公开数据,数据库每秒有95万次请求,其中主库请求5万次/秒,从库达到90万次/秒,这是一个典型的“读多写少”的负载。随着业务不断增长,单纯的主备架构已无法满足需求。GitHub开始做分库分表的数据库架构升级,GitHub选择了海外流行的Vitess,一款YouTube内部使用并后来开源到社区的分库分表中间件,相当于分布式的数据库方案,为业务的持续快速发展提供了强有力的支持。

图片

图片

2020年,GitHub进一步升级了他们的缓存解决方案,将Redis缓存替换为分布式版本,并完全替换了原有的Memcached。

重大的跨版本升级:MySQL5.7至8.0

进入2023年,GitHub将MySQL的5.7版本全面升级至8.0版本。这次大版本跨越,非常复杂,官方博客中有非常详细的介绍。他们不仅要做到在线升级,还要制定相应的回滚方案,并设置了MySQL5.7到8.0,以及8.0回退到5.7的复制链路,以确保万无一失。

图片

图片

GitHub这套方案非常复杂,主要是为了确保能够实现在线升级,如果升级失败,还可以回滚到老MySQL5.7,官方透露中间也踩了很多坑,这个需要非常资深的DBA团队才能完成。

我本人在数据迁移这个领域工作了很多年,开发了NineData产品,可以帮助客户做在线的数据复制、数据库迁移升级、ETL等能力,NineData做在线数据迁移的原理是通过解析Log实现,同时支持双向复制,这样可以做到如果升级失败,还能一键完成数据回滚。

图片

现如今,GitHub的总数据量约为300TB,使用了1200台数据库服务器,包括IDC主机和Azure云主机,反映了其云上和云下混合云架构的特点。

启发与总结

GitHub的数据库演进历程给我们丰富的启发:在业务初期,数据库架构尽量保持简洁,MySQL+Redis的数据库加缓存结构能够支撑到100万QPS左右,期间可以使用缓存、数据库读写分离、历史数据归档、业务垂直拆分、硬件升级等方案让数据库架构尽量保持简单。在按业务垂直拆分后,当超过了单机负载,就需要采取分库分表解决方案,这个升级会比较复杂,需要做好充分的业务改造预估以及SQL逻辑和性能的测试。GitHub选择的Vitess的分库分表中间件,国内也有很多解决方案,如PolarDB-X、TDSQL、SharedingSphere、TiDB和OceanBase等等,都是相对成熟的选择。

图片

GitHub的发展历程不仅是互联网数据库技术演进的缩影,也是对那些面临数据库扩容、分库分表等挑战的公司的一个借鉴。希望这里的分享能给您带来些许启示。如果您觉得有所帮助,请不吝分享给您的同事和朋友。

作者介绍

叶正盛

玖章算术CEO,NineData创始人

资深数据库专家,原阿里云数据库产品管理与解决方案部负责人,阿里巴巴去 IOE、异地多活、云计算多次技术变革核心成员,带领团队研发了阿里云数据传输DTS、数据管理DMS、数据库备份DBS、数据库自治DAS等产品。

这篇关于解剖“全球最大男性交友网站”,GitHub十五年数据库架构演进的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/535559

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

mysql数据库分区的使用

《mysql数据库分区的使用》MySQL分区技术通过将大表分割成多个较小片段,提高查询性能、管理效率和数据存储效率,本文就来介绍一下mysql数据库分区的使用,感兴趣的可以了解一下... 目录【一】分区的基本概念【1】物理存储与逻辑分割【2】查询性能提升【3】数据管理与维护【4】扩展性与并行处理【二】分区的

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

Oracle数据库使用 listagg去重删除重复数据的方法汇总

《Oracle数据库使用listagg去重删除重复数据的方法汇总》文章介绍了在Oracle数据库中使用LISTAGG和XMLAGG函数进行字符串聚合并去重的方法,包括去重聚合、使用XML解析和CLO... 目录案例表第一种:使用wm_concat() + distinct去重聚合第二种:使用listagg,

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

详谈redis跟数据库的数据同步问题

《详谈redis跟数据库的数据同步问题》文章讨论了在Redis和数据库数据一致性问题上的解决方案,主要比较了先更新Redis缓存再更新数据库和先更新数据库再更新Redis缓存两种方案,文章指出,删除R... 目录一、Redis 数据库数据一致性的解决方案1.1、更新Redis缓存、删除Redis缓存的区别二

oracle数据库索引失效的问题及解决

《oracle数据库索引失效的问题及解决》本文总结了在Oracle数据库中索引失效的一些常见场景,包括使用isnull、isnotnull、!=、、、函数处理、like前置%查询以及范围索引和等值索引... 目录oracle数据库索引失效问题场景环境索引失效情况及验证结论一结论二结论三结论四结论五总结ora

C#实现文件读写到SQLite数据库

《C#实现文件读写到SQLite数据库》这篇文章主要为大家详细介绍了使用C#将文件读写到SQLite数据库的几种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录1. 使用 BLOB 存储文件2. 存储文件路径3. 分块存储文件《文件读写到SQLite数据库China编程的方法》博客中,介绍了文

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发