如何测量网络对PostgreSQL性能的影响
2023-07-22 19:50 abce 阅读(216) 评论(0) 编辑 收藏 举报在PostgreSQL数据库和应用服务器之间,通常会有许多基础设施层。最常见的有连接池、负载均衡器、路由器、防火墙等。我们经常会忘记或想当然地认为网络hop以及其对整体性能造成的额外开销。但在很多情况下,这可能会导致严重的性能损失和整体吞吐量下降。
如何检测和测量影响
目前还没有一种简单的机制来测量网络开销的影响。但是,通过对pg_stat_activity中的wait_events进行仔细分析,可以尽可能准确地了解情况。因此,我们应该对等待事件进行采样。有很多方法可以对等待事件进行采样,包括使用扩展。但我更倾向于不在用户环境中安装特殊工具或扩展来进行等待事件采样。
在Percona技术支持部门,使用pg_gather作为收集和研究等待事件的方法,因为它是一个独立的SQL脚本,不需要在数据库系统上安装任何东西。它的设计也非常轻量级。每个会话将收集2,000个样本。
pg_gather分析报告可显示与每个会话相关的等待事件和其他信息。
本中将只讨论和强调其中的部分等待事件,同时介绍不同类型的工作负载以及网络性能在等待事件中的表现。
案例1:检索大量记录的查询
让我们考虑一下pg_dump在不同机器上进行逻辑备份的情况。如果网络速度较快,我们可能会看到CPU的大量利用率和等待事件的"DataFileRead"。
当然,这里还有"ClientWrite"事件,即与向客户端(pg_dump)写入数据相关的等待事件。如果客户端是像psql这样的轻量级工具,而且网络速度非常快,那么"ClientWrite "甚至会变得不可见。
不过,让我们看看如果网络速度慢,等待事件会是什么样子。

在这些情况下,大量的"ClientWrite"足以发现问题。
案例2:批量数据加载
这与前一种情况正好相反。PostgreSQL对批量数据的写入操作需要做更多的工作。下面是从真正的快速/低延迟网络中捕获的等待事件。
显然,PostgreSQL进程要在"DataFileExtend"、"WALWrite"和"WALSync"中花费时间。现在,如果网络速度变慢,随着性能瓶颈的出现,我们看到的许多等待事件可能会变得不可见。
以下是通过较慢的网络进行相同批量数据加载时发生的等待事件。
可以看到,"ClientRead "已成为主要的等待事件。这意味着服务器会话正在花费更多时间从客户端读取数据。
在许多系统中,这种变化可能并不显著,但总体而言,"ClientRead"已变得更加突出。
案例3:对事务的影响
有人可能会问,对事务的影响有什么特别之处?在OLTP工作负载中,语句可能既简单又小,不会造成任何可观察到的网络影响。
但是,服务器与客户端之间的来回通信会导致语句与最终提交或回滚之间出现不必要的延迟。这里,我指的是每条语句之间的延迟/间隙。
以下是使用pgbench在高速网络下微事务的等待事件。

在这种情况下,"ClientRead"成为最大的等待事件。
你可能会问,显示的"Net/Delay*"是什么?新版pg_gather(第 21 版)提供了额外的分析,可以评估事务块之外的延迟。
案例4:连接的使用
随着网络延迟的增加,客户端连接将无法充分利用服务器会话。服务器会话必须等待"ClientRead"/"ClientWrite"或空闲。无论哪种情况,都会严重影响系统的吞吐量。
在一个事务中,延迟会被捕获为"ClientRead",但两个事务之间的延迟不会被捕获,因为会话会暂时变得"空闲"。新版的pg_gather会估算服务器切换成空闲状态浪费的时间或"Net/Delay*"浪费的时间。这可能是由于网络延迟或应用程序响应不佳造成的。从数据库方面来看,很难区分它们。但"Net/Delay*"可以很好地说明服务器浪费了多少时间。
如果可以在应用服务器上安装PostgreSQL客户端工具,就可以轻松模拟负载,研究网络延迟和应用响应延迟,并与实际数据进行比较。
当客户端和服务器之间存在大量来回通信时,延迟/延时就会变得更加明显。这可以通过创建单个语句文件来轻松测试。
1 | echo "SELECT 1" > query.sql |
它可以通过 TCP 连接对远程数据库执行指定的秒数。
1 | $ pgbench -h 10.197.42.1 -T 20 -f query.sql |
在我的服务器之间的快速网络上,可以得到以下单个会话的TPS结果。
1 2 3 4 | … latency average = 0.030 ms initial connection time = 5.882 ms tps = 32882.734311 (without initial connection time ) |
但pg_gather的等待事件分析告诉我,更多的时间花在了"Net/Delay*"上。
这是说的通的,因为"SELECT 1 "在服务器上并没有太多工作要做,而这个工作负载就是来回发送通信。
使用本地Unix套接字连接后,单个会话吞吐量增加了一倍多!
latency average = 0.013 ms
initial connection time = 1.498 ms
tps = 75972.733205 (without initial connection time)
但对等待事件的分析表明,客户端与服务器之间的通信仍是耗时的主要部分。
这种高度交互的工作负载可以从服务器端编程(存储过程/函数)甚至扩展中受益。有趣的是,当使用Unix套接字连接时,CPU占用率与TPS相比比例较小;这是需要注意的重要一点。"客户端读取"(ClientRead)增加是因为客户端传输的数据增多。
在这种情况下,如果网络速度变慢,"Net/Delay*"也会增加,CPU使用率和TPS会下降,因为会话在处理两条语句之间会会有更多时间无所事事。
由于这种特殊的工作负载没有事务,发送到服务器的数据较少,"ClientRead"可能会下降到一个不易察觉的水平,就像我们看到的那样。
总结
来自pg_stat_activity的"等待事件"信息可以告诉我们有关性能和网络堵塞的许多细节。不只是事件总数,两个等待事件之间的gap和等待事件模式也有很多信息可以挖掘。正确收集和分析数据。能从PostgreSQL的角度讲述它是如何使用网络的。
更重要的是,分析不受数据库托管或操作系统级工具的影响。实现这一目标不需要任何复杂的工具或框架。像这样的独立SQL脚本可以方便地发现问题和瓶颈。尽管这篇博文针对的是网络,但等待事件分析可以通用于许多情况。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2022-07-22 【PostgreSQL]PostgreSQL数据库层限流脚本
2016-07-22 Oracle官方文档在线查看
2016-07-22 Real-Time SQL Monitoring
2015-07-22 11G新特性 -- ASM的兼容性
2015-07-22 11G新特性 -- variable size extents