每秒最多 6.5 万个事务,我们的 PostgreSQL 12 迁移之路

点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

每日英文

The road ahead is still a long way, you may cry, but must go on, must not stop .Those who can't lose will never win either.

前面的路还很远,你可能会哭,但是一定要走下去,一定不能停。输不起的人,往往就是赢不了。

每日掏心话

觉得人的脆弱和坚强都超乎自己的想象。有时,我可能脆弱得一句话就泪流满面,有时,也发现自己咬着牙走了很长的路。

责编:乐乐 | 来自:架构头条

编程技术圈(ID:study_tech)第 1144 次推文 图源:百度

往日回顾:可怕!19款国产手机无一幸免:15分钟破解人脸识别,打印眼镜让刷脸形同虚设

     

   正文   

作者 | Tommy Li

策划 | 蔡芳芳

2020 年 11 月,我们开始了一次大规模的迁移,将 PostgreSQL 集群从 9.6 版本升级到 12.4 版本。在这篇文章中,我将概要地介绍下我们在 Coffee Meets Bagel 采用的架构,带你看一下我们在累计停机时间不到 30 分钟的情况下完成升级所采取的步骤,并分享一些经验教训。

本文最初发布于 Coffee Meets Bagel 工程博客,经原作者授权由 InfoQ 中文站翻译并分享。

1架构

你可能不了解 Coffee Meets Bagel,我们是一个精心策划的约会应用。每天中午,约会者都会收到一定数量的高质量候选人。我们的负载模式具有非常好的可预见性。在撰写这篇文章的前一周,我们的平均交易数徘徊在每秒 3 万笔左右,而在更大的市场中,我们的最高交易数是每秒 6.5 万笔。

在升级之前,我们在 AWS i3.8xlarge 实例上运行了 6 个 Postgres 服务器。其中包扩一个主节点,三个服务于只读 Web 流量的副本(通过 HAProxy 实现负载均衡),一个专用于异步工作线程的服务器,还有一个用于 ETL 和 BI 的服务器。

我们使用 Postgres 内置的流复制来保证副本集群是最新的。

2升级原因

在过去的几年里,在很大程度上,我们忽略了数据层,因此它们已经有点老迈了。特别是我们的主服务器已经积攒了很多问题——它在线已经有大约 3 年半的时间了,各种系统库和服务都打过补丁。

我提供给 r/uptimeporn 的数据

因此,它有许多让我们紧张的稀奇古怪的问题:新服务拒绝在 systemd 中运行(我们最后在一个 screen 会话中运行了一个 datadog 代理),有时当 CPU 使用率超过 50%,对 SSH 就完全无响应了(同时继续服务于查询)。

此外,我们的磁盘使用开始变得不稳定。正如我前面提到的,我们在 EC2 i3.8xlarge 实例上运行 Postgres,该实例带有 7.6TB 的 NVMe 存储。和 EBS 不同,它不能动态调整大小,所以有多大就是多大,而且磁盘的 75% 已经填满。为了支持未来的增长,我们必须升级实例大小。

3我们的需求

  1. 最小化停机时间——我们的目标是累计停机时间 4 小时,包括升级过程中的错误所导致的意外停机。

  2. 在新实例上构建一个新的数据库集群,以取代我们当前老化的服务器集群。

  3. 升级到 i3.16xlarge 实例,留下增长空间。

我们知道三种 Postgres 升级方法:典型的备份和还原过程、pg_upgrade 和逻辑复制。

我们很快就放弃了备份和还原方法,因为我们的数据集有 5.7TB,需要花费的时间太长了。pg_upgrade 虽然快,但它是就地升级,不满足条件 2 和 3。所以,我们下一步是进行逻辑复制。

过程关于 pglogology 的安装和使用,已经有很多资料,所以我就不重复了,下面这些链接我认为非常有帮助:

https://www.depesz.com/2016/11/08/major-version-upgrading-with-minimal-downtime/

https://info.crunchydata.com/blog/upgrading-postgresql-from-9.4-to-10.3-with-pglogical

http://thedumbtechguy.blogspot.com/2017/04/demystifying-pglogical-tutorial.html

我们创建了一个 Postgres 12 服务器,它将成为我们新的主服务器,并使用 pglogical 来同步所有数据。一旦它复制完旧数据并开始复制传入的更改,我们就在它后面添加流副本。当我们每准备好一个新的流副本,就把它添加到 HAProxy 中,同时删除一个旧的 9.6 副本。我们就这样一直做,直到除了主服务器之外的所有 Postgres 9.6 服务器都已退出,此时,我们的状态如下:

在这种状态下,我们就会安排一个维护窗口来执行故障切换。同样,关于这个过程,网上有很好的文档,所以这里我只粗略地描述一下我们所做的事情:

在公众号顶级架构师后台回复“架构整洁”,获取一份惊喜礼包。

  1. 将站点置于维护模式

  2. 将主数据库的 DNS 切换到新主机的 IP

  3. 强制同步所有主键序列

  4. 在旧的主数据库上手动运行 checkpoint

  5. 执行一些数据验证,测试下新的主数据库

  6. 将站点恢复到正常运行状态

总之,对于我们来说,这个过程很顺利。虽然这是一次规模比较大的基础设施迁移,但我们没有遇到任何意外的停机或者错误。

4经验教训

虽然这个项目取得了很大的成功,但我们也遇到了一些问题。最可怕的是差点搞挂我们的 Postgres 9.6 Primary…

教训 1:同步缓慢会很危险

首先是一些关于 pglogical 的背景信息:pglogical 的工作方式是,提供方数据库(在本例中是我们的旧 9.6 Primary)上的发送方进程将解码预写日志,提取逻辑更改,并将它们发送到订阅方数据库。

如果订阅方速度慢了,那么提供方的 WAL 段就会开始累积,这样,当订阅方赶上时就不会丢失任何数据。

当你向副本流添加表时,pglogical 首先需要同步表数据。这是使用 Postgres 的 COPY 命令完成的。然后,在提供方数据库上 WAL 段将开始累积,这样,在 COPY 开始后提交的更改可以在初始同步完成后传输到订阅方,确保数据不会丢失。

也就是说,在实践中,如果你正在一个写入 / 更新频繁的系统中同步一个较大的表,那么你需要密切关注磁盘使用情况。我们第一次尝试同步最大的表(4TB)时,初始 COPY 语句运行了一天多,在此期间,我们在提供方节点上累积了大约 1TB 的 WAL。

你可能还记得,我们在前面提到过,我们的旧数据库服务器只剩下大约 2TB 的空闲磁盘空间。从用户数据库的磁盘使用情况来看,只有约四分之一的表复制了,我们认定,我们将无法在磁盘空间耗尽之前完成,因此我们迅速取消了同步过程。

在初始同步期间,旧主数据库上的可用磁盘空间

然后,我们对订阅方数据库做了以下更改,以加快同步:

  • 删除需要同步的表上的所有索引

  • 关闭 fsync

  • 将 max_wal_size 设为 50GB

  • 将 checkpoint_timeout 设为 1h

这四个更改显著提高了订阅方数据库摄取数据的速度,我们在第二次尝试时用不到 8 小时就完成了表的同步。

教训 2: 每个更新都被记录为冲突

当 pglologic 断定发生了冲突时,它会发出一条日志消息,比如“CONFLICT: remote UPDATE on relation PUBLIC.foo. Resolution: apply_remote”。

然而,我们观察到,订阅方处理的每个更新都会被记录为冲突。仅经过几个小时的复制,订阅方数据库就已经写入了 1GB 的冲突日志。

我们在 postgresql.conf 文件中加入 pglogical.conflict_log_level = DEBUG 将其关闭。

原文链接:

https://tech.coffeemeetsbagel.com/our-journey-to-postgresql-12-3d6ee15d305a

PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!

欢迎加入后端架构师交流群,在后台回复“学习”即可。

猜你还想看

阿里、腾讯、百度、华为、京东最新面试题汇集

如何完成一次快速的查询

陆家嘴一程序员加班吐血,吐完继续加班。。

我终于决定要放弃okhttp、httpClient,选择了这个牛逼的神仙工具!贼爽

BAT等大厂Java面试经验总结

别找了,想获取 Java大厂面试题学习资料

扫下方二维码回复「手册」就好了



嘿,你在看吗

  • 0
    点赞
  • 0
    收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值