写点什么

数据库连接从 15000 降到 100 以下:DigitalOcean 如何解决技术债

  • 2020-03-14
  • 本文字数:3226 字

    阅读完需:约 11 分钟

数据库连接从15000降到100以下:DigitalOcean如何解决技术债

本文最初发布于 DigitalOcean 官方博客,经原作者授权由 InfoQ 中文站翻译并分享。


最近,一位新员工在午餐时问我:“DigitalOcean 的技术债务是什么情况?”


听到这个问题时,我忍不住笑了。软件工程师询问一家公司的技术债务就相当于询问其信用评分。这是他们衡量一家公司过去的遗留问题以及他们所要背负的包袱的方法。DigitalOcean 对技术包袱并不陌生。


作为云提供商,我们管理着自己的服务器和硬件,我们面临着许多其他初创公司在这个云计算的新时代尚未遇到的复杂性。这些艰难的情况最终迫使我们不得不早做权衡。任何快速成长的公司都知道,你早期做出的技术决定往往会在以后影响到你。


盯着桌子对面的新员工,我深吸了一口气,然后开始说。“让我告诉你,我们有 15000 个与数据库的直接连接……”



我给这位新员工讲的故事是 DigitalOcean 迄今为止最大的技术重组。这是整个公司多年来的努力,教会了我们很多东西。我希望,讲述这个故事可以帮助未来的 DigitalOcean 开发者——或任何发现自己陷入棘手的技术债务问题的开发者。

故事缘起

DigitalOcean 从一开始就痴迷于简单性。这是我们的核心价值观之一:力求简单而优雅的解决方案。这不仅适用于我们的产品,也适用于我们的技术决策。这一点在我们最初的系统设计中最为明显。


与 GitHub、Shopify 和 Airbnb 一样,DigitalOcean 也是在 2011 年从一个 Rails 应用程序开始的。我们内部称为 Cloud 的 Rails 应用程序管理着 UI 和公共 API 中的所有用户交互。Rails 服务有两个 Perl 编写的辅助服务:调度器和 DOBE(DigitalOcean 的后端)。调度器将调度并分配 Droplet 给管理程序,而 DOBE 负责创建实际的 Droplet 虚拟机。Cloud 和调度器作为独立的服务运行,而 DOBE 则运行在 fleet 中的每台服务器上。


无论是 Cloud、调度器,还是 DOBE,彼此之间都不能直接对话。他们通过 MySQL 数据库通信。这个数据库有两个作用:存储数据和代理通信。这三个服务都使用单个数据库表作为消息队列来传递信息。


每当用户新建一个 Droplet 时,Cloud 就会向队列插入一个新的事件记录。调度器每秒一次不断地在数据库中轮询新的 Droplet 事件,并将它们的创建工作安排给一个可用的管理程序。最后,每个 DOBE 实例将等待新调度的 Droplet 创建并完成任务。为了能检测到所有新的更改,这些服务器都需要在数据库中轮询表中的新记录。



虽然在系统设计方面,无限循环和让每个服务器直接连接到数据库可能比较低级,但它很简单,而且很有效——特别是在人手短缺的技术团队面临紧迫的期限和快速增长的用户群时。


四年来,数据库消息队列一直是 DigitalOcean 技术的支柱。在此期间,我们采用了微服务体系结构,用 gRPC 代替 HTTPS 进行内部通信,并取消了 Perl,代之以 Golang 作为后端服务。然而,所有的方法都指向 MySQL 数据库。


值得注意的是,不能仅仅因为某些东西是“遗产”就认为它功能不完善,应该被取代。Bloomberg 和 IBM 都有用 Fortran 和 COBOL 编写的遗留服务,这些服务产生的收入超过整个公司。另一方面,每个系统都有一个扩展限制。我们就要达到这个限制了。


从 2012 年到 2016 年,DigitalOcean 的用户流量增长超过了 1000%。我们在目录中添加了更多的产品,在基础设施中添加了更多的服务。这增加了数据库消息队列上进入的事件。对 Droplet 需求增加意味着调度器要加班加点地把它们分配到服务器上。不幸的是,对于调度器,可用服务器的数量不是静态的。



为了满足 Droplet 需求的不断增长,我们不断地增加服务器来处理流量。每个新的管理程序都意味着一个新的数据库持久连接。截至 2016 年初,该数据库拥有超过 1.5 万个直接连接,每一个连接每 1 到 5 秒就查询一次新事件。如果这还不够糟糕的话,每个管理程序用来获取新 Droplet 事件的 SQL 查询也变得越来越复杂。它已经变成了一个巨人,有 150 多行,18 张表关联在一起。令人印象深刻的是,它不稳定,而且很难维持。


不出所料,正是在这个时期,问题开始显现。单点故障和成千上万的依赖关系攫取了共享资源,不可避免地导致了一段时间的混乱。表锁和查询积压会导致停机和性能下降。


由于系统的紧耦合,我们没能找到一个清晰简单的解决方案来解决这个问题。Cloud、调度器和 DOBE 都是瓶颈。如果只修补其中一两个组件,就会将负载转移到其余的瓶颈组件上。因此,经过深思熟虑,工程师们想出了一个三管齐下的方案来解决这个问题:


  1. 减少数据库上直接连接的数量;

  2. 重构调度器的排名算法,改进可用性;

  3. 移除数据库的消息队列职责。

开始重构

为了解决数据库依赖,DigitalOcean 的工程师创建了事件路由器。事件路由器充当区域代理,代表每个数据中心中的每个 DOBE 实例轮询数据库。这样,就只有少数代理在做查询,而不是数以千计的服务器。每个事件路由器代理将获取特定区域中的所有活动事件,并将每个事件委派给适当的管理程序。事件路由器还将庞大的轮询查询拆分成更小、更容易维护的轮询查询。



当事件路由器上线后,数据库连接的数量从 15000 个减少到不足 100 个。


接下来,工程师们把目光投向了下一个目标:调度器。如前所述,调度器是一个 Perl 脚本,它决定哪个管理程序将托管一个创建好的 Droplet。它使用一系列查询来对服务器进行排序。每当用户创建一个 Droplet 时,调度器就用最好的机器更新表行。


虽然听起来很简单,但该调度器有一些缺陷。它的逻辑很复杂,很难处理。它是单线程的,在流量高峰期间性能会受影响。最后,该调度器只有一个实例,却必须为整个 fleet 服务。这是一个不可避免的瓶颈。为了解决这些问题,工程团队创建了调度器 V2。


更新后的调度器彻底修改了排名系统。它不从数据库中查询服务器指标,而是从管理程序中聚合它们,并将它们存储在自己的数据库中。此外,调度器团队使用并发和复制保证新服务的负载性能。


事件路由器和调度器 V2 取得了许多了不起的成果,消除了当时的许多架构缺陷。尽管如此,还是有一个明显的障碍。到 2017 年初,集中式 MySQL 消息队列仍然在使用——甚至还很频繁。它每天处理 40 万条新记录,每秒更新 20 次。


遗憾的是,移除数据库消息队列并不容易。第一步是避免服务直接访问它。数据库需要一个抽象层。它还需要一个 API 来聚合请求并代它执行查询。任何服务想要创建一个新事件,都需要通过 API 来实现。于是,Harpoon 诞生了。


不过,为事件队列构建接口这部分比较容易。事实证明,从其他团队那里获得支持更加困难。与 Harpoon 集成意味着团队将不得不放弃他们的数据库访问,重写他们的部分代码库,并最终改变他们一直以来做事的方式。这可不是件容易的事。


Harpoon 的工程师们逐个团队、逐个服务地将整个代码库迁移到他们的新平台上。这花了差不多一年的时间,但到 2017 年底,Harpoon 成为数据库消息队列的唯一发布者。


现在真正的工作开始了。对事件系统的完全控制意味着 Harpoon 可以自由地重新设计 Droplet 工作流了。


Harpoon 的第一个任务是将消息队列职责从数据库提取到自身。为此,Harpoon 创建了自己的内部消息队列,由 RabbitMQ 和异步 worker 组成。当 Harpoon 在一侧把新事件推入队列时,worker 在另一侧拉取它们。由于 RabbitMQ 取代了数据库队列,worker 可以方便地直接与调度器和事件路由器交互。因此,调度器 V2 和事件路由器不是通过轮询从数据库获取新变化,而是由 Harpoon 直接将更新推送给它们。截止到 2019 年本文撰写时,这就是 Droplet 事件架构所处的位置。


一路向前

在过去的 7 年里,DigitalOcean 已经从一家小型创业公司成长为今天这样的成熟的云提供商。与其他转型中的科技公司一样,DigitalOcean 会定期处理遗留代码和技术债务。无论是拆分单体应用、创建多区域服务,还是消除单点故障,我们 DigitalOcean 的工程师们始终致力于打造优雅而简单的解决方案。


这就是我们的基础设施如何随着用户群的发展而扩展的故事,希望你觉得这是个有趣而又有启发性的故事。我很乐意在下面的评论中看到你的想法!


原文链接:


From 15,000 database connections to under 100: DigitalOcean’s tale of tech debt


2020-03-14 10:002482

评论

发布
暂无评论
发现更多内容

高效、透明-企事业数字化的采购管理系统(源程序源代码)

金陵老街

超越内存限制:深入探索内存池的工作原理与实现

华为云开发者联盟

软件开发 存储 华为云 华为云开发者联盟 企业号9月PK榜

世界500强都摒弃使用FTP的真实原因

镭速

ftp传输 FTP替代 FTP替代方案

一站式运营营销平台

Quincy

运营 用户增长技术 营销数字化 用户留存 `后端

华为云智能化组装式交付方案 ——金融级PaaS业务洞察及Web3实践的卓越贡献

云计算 软件开发 华为云

Databend 开源周报第112期

Databend

苹果mac桌面管理软件都有哪些?

南屿

Mac桌面管理工具 苹果电脑必备软件 Mac破解软件

在Mac上,按Command-X键无法剪切怎么办?

南屿

Mac右键助手 Command-X键无法剪切 Mac常见问题

Mate60上的这个视频APP,追剧可太香了

最新动态

融云 CallPlus + X,通话场景一站式解决方案

融云 RongCloud

API 社交 融云 CallPlus SDK 通话

cad设计绘图 AutoCAD 2024中文最新「支持m芯片」

胖墩儿不胖y

Mac软件 CAD绘图 cad工具

小程序编译器性能优化之路

百度Geek说

小程序 性能优化 前端 企业号9月PK榜

软件物料清单管理 | 打开“应用软件盲盒”,预警“开源组件风险”

网安云

开源 网络安全 系统安全 开源软件 软件物料清单

算力百川汇蓝海,商海荡漾绘宏图

鲸品堂

算力 算力网络

轻量级业务福音!TDengine Cloud 在国轩高科储能项目中的应用

TDengine

tdengine 时序数据库 国产时序数据库

从研发域到量产域的自动驾驶工具链探索与实践

Baidu AICLOUD

自动驾驶 工具链 仿真

2023年信创云管平台选哪家?咨询电话多少?

行云管家

云计算 云服务 信创 国产化

Photoshop创成式AI不能用?Alpaca(羊驼)AI智能创成式填充插件

南屿

PS插件下载 Alpaca(羊驼)插件 AI创成式填充插件

企业如何寻找可替代serv-u的国产文件传输系统?

镭速

如何通过”系统设置”自定 苹果Mac?

南屿

自定义苹果Mac Mac电脑使用教程 苹果电脑使用

华为云API Explorer重磅推出API编排,开发者0代码高效构建工作流

华为云开发者联盟

软件开发 API 华为云 华为云开发者联盟 企业号9月PK榜

数据库连接从15000降到100以下:DigitalOcean如何解决技术债_数据库_Sunny Beatteay_InfoQ精选文章