我决定对服务器端备份压缩的性能进行更多研究,这将是 PostgreSQL 15 中的一项新功能,除非出于某种原因需要在发布时间之前恢复更改。我之前测试使用的网络链接 正如我所提到的,它相当慢,并且受到 VPN 链接和 SSH 隧道的阻碍。此外,我正在使用极易压缩的 pgbench 数据进行测试。此外,在我进行这些测试时,我们已经添加了对 LZ4 压缩的支持,但尚未添加对 Zstandard 压缩的支持。然而,现在我们不仅可以选择 Zstandard,还可以使用该库的多线程功能。因此,我想了解在更快的网络链接、更好的测试数据集以及我们现在可用的所有压缩算法的情况下,事情会如何进行。
为了弄清楚这一点,我下载了 https://wiki.postgresql.org/wiki/Sample_Databases 中提到的英国土地登记数据, 并将其加载到 PostgreSQL 数据库中,该数据库是根据主分支最近的一次提交构建的,它将最终成为v15。生成的数据库为 3.8GB。然后我尝试在这台机器和位于同一 EDB 内部子网上的另一台机器之间进行一些备份。两台机器都报告有 10 GB 以太网,iperf报告机器之间的带宽为 8.73 GB/s。
我尝试同时使用-Ft(tar 格式)和-Fp(纯格式)进行备份,在每种情况下都测试了各种形式的服务器端压缩。当以 tar 格式进行备份时,pg_basebackup基本上只是将服务器生成的文件写入磁盘。当它以纯格式获取时,pg_basebackup解压缩并提取存档。以下是结果:
Compression | Size -Ft (GB) | Time -Ft | Time -Fp |
none | 3.8 | 17.0 | 18.1 |
gzip | 1.5 | 234.9 | 233.1 |
lz4 | 2.0 | 31.5 | 35.1 |
zstd | 1.3 | 56.1 | 59.1 |
zstd:workers=2 | 1.3 | 26.4 | 29.5 |
zstd:workers=4 | 1.3 | 15.0 | 21.8 |
zstd:workers=6 | 1.3 | 11.5 | 23.0 |
zstd:workers=8 | 1.3 | 9.9 | 22.9 |
zstd:workers=12 | 1.3 | 10.3 | 20.3 |
zstd:workers=16 | 1.3 | 10.0 | 20.5 |
zstd:workers=20 | 1.3 | 10.2 | 20.3 |
zstd:workers=24 | 1.3 | 10.1 | 21.0 |
在这里,以及在我运行的所有其他测试中,gzip 压缩——当前 PostgreSQL 版本支持的唯一类型,而且仅在客户端——是突出的失败者。它的速度非常慢。其他的选择都是有竞争力的,看情况。LZ4 的压缩效果不如 gzip,但它是最快的单线程算法。单线程 Zstandard 比 gzip 压缩得更好更快,但不如单线程 LZ4 快。如果你有空闲的 CPU 资源,你可以在 Zstandard 压缩下投入 8 个左右的核心,并获得更好的压缩率和最快的时间。事实上,当使用 tar 格式时,并行 Zstandard 压缩比根本不压缩备份快 40%。
如果这些机器之间的网络连接足够慢,则执行备份的时间将由备份大小决定,就像我之前的帖子中那样,数据库压缩了大约 8.9 倍,而备份速度提高了大约 8.9 倍。 8.9. 在这里,使用更真实的数据集,即使使用 Zstandard,压缩率也只有大约 2.9 倍,因此如果网络速度慢到成为瓶颈,我认为使用 Zstandard 会给我们带来大约 2.9 倍的性能提升。然而,在这里,网络速度足够快,不是问题,但压缩 - 当使用 tar 格式时 - 仍然提供大约 1.7 倍的加速。这是为什么?
基本上,收益归因于 pg_basebackup 需要做更少的工作。当备份大小从 3.8GB 下降到 1.3GB 时,pg_basebackup 需要从网络接收的数据减少 2.5 GB,需要写出到磁盘的数据减少 2.5 GB。网络足够快,传输 2.5 GB 数据的成本不是真正的问题,但内核仍然必须将从网络接收到的所有数据复制到 PostgreSQL 的地址空间,然后它必须转身从PostgreSQL 的地址空间进入内核缓冲区缓存,以便它可以写出到磁盘,最后数据必须实际写入磁盘。额外的复制和实际的磁盘写入都是昂贵的。
请注意,在纯格式中,与未压缩的情况相比,我们看不到任何性能提升;事实上,即使是并行 Zstandard 也显示出轻微的回归,而其他压缩方法更糟。因为我们现在必须解压缩和提取档案,所以 pg_basebackup 最终不得不写入完整的 3.8GB,无论传输中的数据使用何种压缩方法。我们仍然受益于需要在服务器端向网络写入更少的数据以及在客户端从网络读取更少的数据,但是在快速的网络连接上,这并不足以弥补必须这样做的成本在服务器端压缩整个输入,然后在客户端解压缩所有内容。
我认为用更大的数据集来测试它是如何工作的会很有趣,这样我们就可以使本地磁盘饱和更长的时间,也许还可以使用高度不可压缩的数据集。关于我们如何能够提高 pg_basebackup 的效率,我也有一些想法。但是,总的来说,我发现这些结果非常令人鼓舞。我不认为用户在服务器上有足够的空闲 CPU 容量来使用并行 Zstandard 压缩是不寻常的情况,如果数据集是合理可压缩的,那么这样做的好处可能是显着的。
原文标题:Parallel Server-Side Backup Compression
原文作者:Robert Haas
原文链接:http://rhaas.blogspot.com/2022/05/parallel-server-side-backup-compression.html