很长时间以来 GitLab.com 使用了一个单个的 PostgreSQL 数据库服务器和一个用于灾难恢复的单个复制。在 GitLab.com 最初的几年,它工作的还是很好的,但是随着时间的推移,我们看到这种设置的很多问题,例如,数据库长久处于重压之下, CPU 使用率几乎所有时间都处于 70% 左右。

在我们使用 PostgreSQL 去跟踪这些问题时,使用了以下的四种技术:

1、优化你的应用程序代码,以使查询更加高效。

2、使用一个连接池去减少必需的数据库连接数量及相关的资源。

3、跨多个数据库服务器去平衡负载。

4、分片数据库。

连接池

在 PostgreSQL 中,一个连接是通过启动一个操作系统进程来处理的,这反过来又需要大量的资源,更多的连接(及这些进程)将使用你的数据库上的更多的资源。 PostgreSQL 也在 max_connections 设置中定义了一个强制的最大连接数量。一旦达到这个限制,PostgreSQL 将拒绝新的连接, 比如,下面的图表示的设置:

这里我们的客户端直接连接到 PostgreSQL,这样每个客户端请求一个连接。

通过连接池,我们可以有多个客户端侧的连接重复使用一个 PostgreSQL 连接。例如,没有连接池时,我们需要 100 个 PostgreSQL 连接去处理 100 个客户端连接;使用连接池后,我们仅需要 10 个,或者依据我们配置的 PostgreSQL 连接。这意味着我们的连接图表将变成下面看到的那样:

这里我们展示了一个示例,四个客户端连接到 pgbouncer,但不是使用了四个 PostgreSQL 连接,而是仅需要两个。

对于 PostgreSQL 有两个最常用的连接池:

pgpool 有一点特殊,因为它不仅仅是连接池:它有一个内置的查询缓存机制,可以跨多个数据库负载均衡、管理复制等等。另一个 pgbouncer 是很简单的:它就是一个连接池。

数据库负载均衡

数据库级的负载均衡一般是使用 PostgreSQL 的 “热备机hot-standby” 特性来实现的。 热备机是允许你去运行只读 SQL 查询的 PostgreSQL 副本,与不允许运行任何 SQL 查询的普通备用机standby相反。要使用负载均衡,你需要设置一个或多个热备服务器,并且以某些方式去平衡这些跨主机的只读查询,同时将其它操作发送到主服务器上。扩展这样的一个设置是很容易的:(如果需要的话)简单地增加多个热备机以增加只读流量。

这种方法的另一个好处是拥有一个更具弹性的数据库集群。即使主服务器出现问题,仅使用次级服务器也可以继续处理 Web 请求;当然,如果这些请求最终使用主服务器,你可能仍然会遇到错误。

然而,这种方法很难实现。例如,一旦它们包含写操作,事务显然需要在主服务器上运行。此外,在写操作完成之后,我们希望继续使用主服务器一会儿,因为在使用异步复制的时候,热备机服务器上可能还没有这些更改。

分片

分片是水平分割你的数据的行为。这意味着数据保存在特定的服务器上并且使用一个分片键检索。例如,你可以按项目分片数据并且使用项目 ID 做为分片键。当你的写负载很高时,分片数据库是很有用的(除了一个多主设置外,均衡写操作没有其它的简单方法),或者当你有大量的数据并且你不再使用传统方式保存它也是有用的(比如,你不能把它简单地全部放进一个单个磁盘中)。

不幸的是,设置分片数据库是一个任务量很大的过程,甚至,在我们使用诸如 Citus 的软件时也是这样。你不仅需要设置基础设施 (不同的复杂程序取决于是你运行在你自己的数据中心还是托管主机的解决方案),你还得需要调整你的应用程序中很大的一部分去支持分片。

GitLab 的连接池

对于连接池我们有两个主要的诉求:

1、它必须工作的很好(很显然这是必需的)。

2、它必须易于在我们的 Omnibus 包中运用,以便于我们的用户也可以从连接池中得到好处。

用下面两步去评估这两个解决方案(pgpool 和 pgbouncer):

1、执行各种技术测试(是否有效,配置是否容易,等等)。

2、找出使用这个解决方案的其它用户的经验,他们遇到了什么问题?怎么去解决的?等等。

pgpool 是我们考察的第一个解决方案,主要是因为它提供的很多特性看起来很有吸引力。我们其中的一些测试数据可以在 这里 找到。

最终,基于多个因素,我们决定不使用 pgpool 。例如, pgpool 不支持粘连接sticky connection。 当执行一个写入并(尝试)立即显示结果时,它会出现问题。想像一下,创建一个工单issue并立即重定向到这个页面, 没有想到会出现 HTTP 404,这是因为任何用于只读查询的服务器还没有收到数据。针对这种情况的一种解决办法是使用同步复制,但这会给表带来更多的其它问题,而我们希望避免这些问题。

另一个问题是, pgpool 的负载均衡逻辑与你的应用程序是不相干的,是通过解析 SQL 查询并将它们发送到正确的服务器。因为这发生在你的应用程序之外,你几乎无法控制查询运行在哪里。这实际上对某些人也可能是有好处的, 因为你不需要额外的应用程序逻辑。但是,它也妨碍了你在需要的情况下调整路由逻辑。

由于配置选项非常多,配置 pgpool 也是很困难的。或许促使我们最终决定不使用它的原因是我们从过去使用过它的那些人中得到的反馈。即使是在大多数的案例都不是很详细的情况下,我们收到的反馈对 pgpool 通常都持有负面的观点。虽然出现的报怨大多数都与早期版本的 pgpool 有关,但仍然让我们怀疑使用它是否是个正确的选择。

结合上面描述的问题和反馈,最终我们决定不使用 pgpool 而是使用 pgbouncer 。我们用 pgbouncer 执行了一套类似的测试,并且对它的结果是非常满意的。它非常容易配置(而且一开始不需要很多的配置),运用相对容易,仅专注于连接池(而且它真的很好),而且没有明显的负载开销(如果有的话)。也许我唯一的报怨是,pgbouncer 的网站有点难以导航。

使用 pgbouncer 后,通过使用事务池transaction pooling我们可以将活动的 PostgreSQL 连接数从几百个降到仅 10 - 20 个。我们选择事务池是因为 Rails 数据库连接是持久的。这个设置中,使用会话池session pooling不能让我们降低 PostgreSQL 连接数,从而受益(如果有的话)。通过使用事务池,我们可以调低 PostgreSQL 的 max_connections 的设置值,从 3000 (这个特定值的原因我们也不清楚) 到 300 。这样配置的 pgbouncer ,即使在尖峰时,我们也仅需要 200 个连接,这为我们提供了一些额外连接的空间,如 psql 控制台和维护任务。

对于使用事务池的负面影响方面,你不能使用预处理语句,因为 PREPARE 和 EXECUTE 命令也许最终在不同的连接中运行,从而产生错误的结果。 幸运的是,当我们禁用了预处理语句时,并没有测量到任何响应时间的增加,但是我们 确定 测量到在我们的数据库服务器上内存使用减少了大约 20 GB。

为确保我们的 web 请求和后台作业都有可用连接,我们设置了两个独立的池: 一个有 150 个连接的后台进程连接池,和一个有 50 个连接的 web 请求连接池。对于 web 连接需要的请求,我们很少超过 20 个,但是,对于后台进程,由于在 GitLab.com 上后台运行着大量的进程,我们的尖峰值可以很容易达到 100 个连接。

今天,我们提供 pgbouncer 作为 GitLab EE 高可用包的一部分。对于更多的信息,你可以参考 “Omnibus GitLab PostgreSQL High Availability”。

整合连接池和数据库负载均衡

整合连接池和数据库负载均衡可以让我们去大幅减少运行数据库集群所需要的资源和在分发到热备机上的负载。例如,以前我们的主服务器 CPU 使用率一直徘徊在 70%,现在它一般在 10% 到 20% 之间,而我们的两台热备机服务器则大部分时间在 20% 左右:

CPU Percentage

在这里, db3.cluster.gitlab.com 是我们的主服务器,而其它的两台是我们的次级服务器。

其它的负载相关的因素,如平均负载、磁盘使用、内存使用也大为改善。例如,主服务器现在的平均负载几乎不会超过 10,而不像以前它一直徘徊在 20 左右:

CPU Percentage

在业务繁忙期间,我们的次级服务器每秒事务数在 12000 左右(大约为每分钟 740000),而主服务器每秒事务数在 6000 左右(大约每分钟 340000):

Transactions Per Second

可惜的是,在部署 pgbouncer 和我们的数据库负载均衡器之前,我们没有关于事务速率的任何数据。

我们的 PostgreSQL 的最新统计数据的摘要可以在我们的 public Grafana dashboard 上找到。

我们的其中一些 pgbouncer 的设置如下:

设置值

default_pool_size

100

reserve_pool_size

5

reserve_pool_timeout

3

max_client_conn

2048

pool_mode

transaction

server_idle_timeout

30

除了前面所说的这些外,还有一些工作要作,比如: 部署服务发现(#2042), 持续改善如何检查次级服务器是否可用(#2866),和忽略落后于主服务器太多的次级服务器 (#2197)。

值得一提的是,到目前为止,我们还没有任何计划将我们的负载均衡解决方案,独立打包成一个你可以在 GitLab 之外使用的库,相反,我们的重点是为 GitLab EE 提供一个可靠的负载均衡解决方案。

如果你对它感兴趣,并喜欢使用数据库、改善应用程序性能、给 GitLab上增加数据库相关的特性(比如: 服务发现),你一定要去查看一下我们的 招聘职位 和  数据库专家手册 去获取更多信息。

gitlab-ee使用mysql_在 GitLab 我们是如何扩展数据库的相关推荐

  1. gitlab 删除分支_初识gitlab工作流

    git对我来说挺难理解的,平时遇到问题也是绕着走,倒也没啥大问题,但基于git软件的工作流却很重要,尤其对于一个组织来说. git工作流.github工作流.gitlab工作流都属于特性分支(feat ...

  2. Amazon EKS基于GitLab的CICD实践一 GitLab的部署和配置篇

    在容器化,微服务,基础设施即代码(IaC)以及DevOps的理念不断被大家所接受和理解,摆在大家面前的是如何在实际的工作中应用和实践这些理念. 本文将讨论基于GitLab来实现针对公有云基础设施(亚马 ...

  3. 【GitLab和Jira集成】GitLab中集成Jira

    GitLab和Jira集成 Gitlab官方文档 起因 GitLab配置 前提要求 配置过程 使用测试 提交代码自动在对应jira issue下评论 通过Gitlab查看Jira相关issue Git ...

  4. gitlab 吃内存。调整gitlab配置

    背景: 时间2022年11月,一台2核4g的阿里云服务安装了最新的gitlab,安装教程可以看之前的文章. 问题: 这台服务器只装了一个程序即gitlab,但是内存吃的所剩无几.看图说话 解决办法:无 ...

  5. 项目管理 之六 详解 Gitlab 本地部署全过程、Gitlab Pages、企业版 PATCH

    gitlab-ee 和 gitlab-ce   需要注意,Gitlab 分为 SaaS 和 Self-Managed 两种版本,其中,SaaS 即 gitlab.com 这个在线版本(这个其实就是官方 ...

  6. win10 修改gitlab账号_玩转gitlab + jenkins

    1.相关概念 互联网软件的开发和发布,已经形成了一套标准流程,假如把开发工作流程分为以下几个阶段:编码 --> 构建 --> 集成 --> 测试 --> 交付 --> 部 ...

  7. gitlab介绍、安装及gitlab CI、与jenkins的对比

    gitlab介绍.安装及gitlab CI.与jenkins的对比

  8. gitlab贡献率_如何为GitLab做贡献

    gitlab贡献率 我认为许多人都熟悉GitLab(公司或软件). 许多人可能没有意识到,GitLab还是一个开源社区,它始于我们的共同创始人Dmitriy Zaporozhet在2011年的第一次提 ...

  9. gitlab php自动化测试,自动化发布-GitLab WEB Hooks 配置

    钩子(hooks)Git是在特定事件发生之前或之后执行特定脚本代码功能(从概念上类比,就与监听事件.触发器之类的东西类似). Git Hooks就是那些在Git执行特定事件(如commit.push. ...

最新文章

  1. golang 项目的目录结构
  2. sdwan能取代mpls吗?—Vecloud
  3. Qt|C++工作笔记-QVector与Vector去重复的值
  4. tf.data.Dataset.zip()讲解 和 python自带的zip()的异同
  5. python刷屏代码_python 刷屏
  6. 双眼融合训练一个月_视觉融合功能改善恢复如何训练
  7. ImageMagick (Magick++ for C++) configuration in Visual Studio 2012
  8. 基于at89c51单片机的led数字倒计时器设计c语言,基于AT89C51单片机的LED数字倒计时器设计.docx...
  9. 两步彻底关闭Windows默认共享文件夹(含IPC$)
  10. ARM模拟器-skyeye(天目)的安装和使用!
  11. oracle 数据库如何建立索引 如何用索引?
  12. 【计算机毕业设计】248高校奖学金管理系统
  13. RISC-V技术杂谈
  14. Windows 事件日志分析管理
  15. Study-Python23-023递归:这帮小兔崽子
  16. Android实现豆瓣FM的首页效果
  17. QT+opencv实时显示视频
  18. 视频教程-C语言及程序设计提高视频精讲-C/C++
  19. python 输出纯音频_python处理音频文件(mp3)
  20. 【USACO】破碎的项链

热门文章

  1. HTML+CSS+JS实现 ❤️canvas 3D立体图片相册幻灯片❤️
  2. I/0口输入输出实验 学习IO口的位操作方法,分别选择P0、P1、P2、P3端口中的某一位,该位作为输出使用,连接一只发光二极管,控制器闪烁。
  3. Java字符串性能优化
  4. python相同怎么写_这两个index相同的dataframe我想把他们merge,怎么写?
  5. LDA(线性判别分析)详解 —— matlab
  6. mxnet深度学习(NDArray)
  7. 计算机在科技英语翻译中起的作用,浅谈科技英语翻译中英语词语的正确理解与表达...
  8. Ext4文件系统修复
  9. 浅谈数据库三大范式的理解
  10. 保存 laravel model 而不更新 timestamps 的方法