PostgreSQL技术问答06 - pgbench
本文是《PostgreSQL技术问答》系列文章中的一篇。关于这个系列的由来,可以参阅开篇文章:
文章的编号只是一个标识,在系列中没有明确的逻辑顺序和意义。读者进行阅读时,不用太关注这个方面。
本文笔者想要来讨论一下在PostgreSQL中的官方提供的数据库系统性能测试和评估工具-pgbench。
什么是pgbench
pgbench一个用于在PostgreSQL数据库上运行基准测试的简单程序,它是一个官方的命令行工具。
默认情况下,它基于TPC-B标准测试程序。即它可能在多个并发的数据库会话中,重复执行相同的SQL命令序列,然后计算平均事务率(每秒事务数)作为测试结果。标准默认的每个测试事务都包括五个 SELECT、UPDATE 和 INSERT 命令。当然,可以编写自己的事务脚本文件,可以轻松地测试任意的事务或者操作执行情况。
我们可以将pgbench用于:
- 测试连接池性能和延迟
- 测试基础的事务处理能力
- 测试并发连接数量
- 测试特定的查询和数据操作性能
关于pgbench的使用,其实有很多相关的技术细节,在PostgreSQL的技术文档中,有一个专门的章节进行说明:
www.postgresql.org/docs/15/pgb…
如何使用pgbench
安装
pgbench并不是PostgreSQL客户端的一部分。所以并不能像psql一样安装。而是需要单独安装,或者作为Postgre Contribute的选项进行安装。笔者查看了一下,pgbench是作为server的一部分,这个设计比较奇怪,这样在客户端上的安全并不是非常方便。建议可以考虑和psql一样,或者专门设计一个客户端工具包。
默认情况下,在服务器上安装Postgres数据库的时候,就带有了pgbench程序了,这是最简单的方式。
如果需要在独立的客户端上安装pgbench,可能需要安装contrib包:
$ sudo apt-get install postgresql-contrib
在Windows下,好像在PG安装程序中,和其他一些客户端工具放在一起,作为一个“Command Line Tools” 的安装选项来提供的(下图)。笔者觉得这个安排和规划比较好。
安装完成后,就可以执行pgbench命令,来进行测试以及相关的操作了。一般用法是:
pgbench [OPTION]... [DBNAME]
- OPTION 是命令选项和参数
- DBNAME 可以指定的数据库实例
完整的帮助信息可以使用 pgbench --help 获取(很多选项)。
连接
pgbench作为一个客户端工具,它需要连接到实际的Postgres数据库服务来使用。它的连接方式非常像psql工具。就是指定一些和连接相关的选项包括:
- -h:指定主机
- -p:指定端口
- -U:指定用户名
也可以向内置psql工具一样,在服务器上,切换到postgres用户账号,不指定连接参数,来连接本地的PG数据库进行测试。
初始化
在正式开始测试之前,需要先进行一些数据和结构的准备,这时需要配合使用 -i 选项如下:
pgbench -i -s 20
dropping old tables...
creating tables...
generating data (client-side)...
2000000 of 2000000 tuples (100%) done (elapsed 4.11 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done in 6.23 s (drop tables 0.01 s, create tables 0.01 s, client-side generate 4.16 s, vacuum 0.31 s, primary keys 1.74 s).
这里除了 -i 是初始化指令之外,还可以需要使用 -s 指定比例因子。原则上这个数值应当和后续测试使用的并发用户数量(-c)一致或者更大一点。
pgbench使用TPC-B标准,它会在系统中创建pgbench_accounts, pgbench_branches, pgbench_history, and pgbench_tellers 四个数据表,如果这些表已经存在,它也会销毁后重新创建。初始化的时候,可以不指定所要测试的数据库实例。笔者理解它会使用默认的数据库实例(postgres)。但可能需要注意,如果使用业务数据库进行测试,表面和上面不应当有冲突。
理论上而言,它们都是相同的数据库系统,所以从性能指标上来看,应该是一致的。可能有的差别在于,如果测试的数据库实例,使用了不同的表空间、文件系统和磁盘配置,可能选择具体的数据库就有不同的影响了。所以在这种情况下,应该选择具体的数据库实例。
如何开展测试
在正常初始化之后,就可以执行测试命令,来对数据库进行一个简单的性能评估和测试,示例如下:
pgbench -c 50 -t 200
pgbench (15.3 (Debian 15.3-1.pgdg110+1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 50
number of threads: 1
maximum number of tries: 1
number of transactions per client: 200
number of transactions actually processed: 10000/10000
number of failed transactions: 0 (0.000%)
latency average = 76.365 ms
initial connection time = 173.354 ms
tps = 654.746054 (without initial connection time)
和测试相关的一些选项包括:
- -c:指定并发连接数量。
- -t: 指定每个客户端连接要执行的事务数量
- -q:安静模式,只显示测试结果
- -v:详细模式,显示更多信息
- -T: 指定测试持续时间(秒),但不能和 -t 同时使用
测试一般会进行的非常快,然后会生成一个简单的报告,通过解读报告内容,我们就可以大致对当前这个数据库的性能进行一个基本的评估了。
如何解读评估测试结果
评估测试的报告内容,已经在前面测试执行过程中有所展示,这里就以这个内容作为参考,简单分析一下其中的要点。
- 测试用的事务类型
pgbench默认执行的测试类型是TPC-B。这是事务处理性能理事会 (Transaction Processing Performance Council,TPC)组织发布的一套性能测试标准之一,用于测试数据库系统在处理简单的银行转账业务交易时的性能表现。
TPC-B模拟了一个银行的业务场景,其中包括多个分行、多个客户和多个账户。测试中的业务交易主要包括两种标准操作:转账(Transfer,将一笔金额从一个账户转移到另一个账户)和新建账户(New-Account,为一个客户新建一个账户)。TPC-B测试中会使用多个并发的客户端程序对数据库系统进行测试,模拟多个用户同时进行业务交易的场景,并且统计统计数据库系统处理业务交易的吞吐量(tpm-B,每分钟处理的业务交易数)、响应时间、CPU 利用率等指标,以此来评估数据库软硬件系统的性能表现。
一般而言,TPC-B测试是一套相对简单的性能测试标准,主要用于测试数据库系统在处理简单的业务交易时的性能表现。而在实际的生产环境中,数据库系统可能需要处理更加复杂的业务场景和交易类型,因此我们一般只是将TPC-B作为一个数据库系统的软硬件性能的基线标准和参考。
- 执行事务总数
本测试中,我们使用50个并发模拟客户端,每个客户端执行200个事务操作。所有事务都成功正常处理。这个数值应当和应用的操作场景预估相匹配。
- 延迟和连接时间
系统的平均延迟为76ms,可以认为它作为Web应用后端,每次进行事务操作需要的时间。这个性能一般,理想情况下,我们希望在Web应用端,常规小数据库接口操作,数据库阶段的处理50ms以下。
系统初始连接时间为173ms,基本上也是如果不使用连接池,每次创建新连接使用的时间,这个指标是比较差的,应该主要和网络以及数据库的性能相关。这个指标也告诉我们,数据库连接是非常昂贵的,需要使用连接池来提升应用连接和数据操作的性能。
- TPS,每秒事务数
这是最重要和核心的指标。就是基于TPC-B的标准,每秒能够完成的事务操作数量,越大越好,表示数据库系统能够处理的能力越强。
笔者测试的系统上,这个数值是655。这只是一个2个CPU、内存4G、混合HD和SSD的PVE虚拟机,是非常普通和常规的配置。
TCP-B典型的事务操作是怎样的
在PostgreSQL技术文档中,对这一问题进行了简单的描述。下面就是一个典型的测试事务所进行的操作:
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;
可以看到,一个典型的事务过程,涉及了多个步骤包括插入、查询、更新等等,并且涉及多个数据表。从而尽量来模拟一个真实通用的应用场景。
最佳实践?
PG技术文档的pgbench章节,还有一个最佳实践的部分,可以参考一下。下面是Mistral翻译并经过笔者补充和改进的内容。
如果使用不当,使用pgbench产生没有任何意义的结果非常容易。所以,我们期望提供一些指导方针,来帮助获得更有参考意义的结果。
首先,永远不要相信仅运行几秒钟的测试。应当使用 -t 或 -T 选项使运行时间至少持续几分钟,以消除噪声。在某些情况下,您可能需要几个小时才能获得可重复的数字。尝试几次测试运行,以确定您的数字是否可重复。
对于默认的类TPC-B的测试方案,初始化缩放因子 (-s) 应至少与您想要测试的最大客户端数 (-c) 一样大;否则,您将主要测量更新争用。pgbench_branches 表中仅有 -s 行,每个事务都希望更新其中的一行,因此 -c 值超过 -s 肯定会导致许多事务被阻塞,等待其他事务。
默认的测试场景对表从初始化以来经过的时间也很敏感:死亡行和表中的死亡空间的累积会改变结果。为了理解结果,您必须跟踪总更新次数以及发生 vaccum 的时间。如果启用了autovacuum,它可能会导致测量性能的不可预测变化。
pgbench 的一个限制是,当尝试测试大量客户端会话时,它本身可能会成为瓶颈。这可以通过在数据库服务器不同的机器上运行 pgbench 来缓解,但是网络延迟必须很低。甚至可能在几台客户端机器上并行运行几个 pgbench 实例,对同一台数据库服务器进行测试。
有什么扩展的测试和应用方式
除了标准默认的TPC-B测试方式之外,还可以通过一些调整和扩展的测试方法,来进一步评估数据库系统对于Web应用的适应性。
- 使用不同的并发连接数量和持续时间来测试不同的场景
pgbench的测试可以使用不同的测试参数,主要调整项目就是客户端数量,持续时间和测试项目数量(事务数量)。客户端数量可以用于测试不同的并发负载对于数据库的影响,而持续时间主要是测试数据库的稳定性和在稳定状态下的持续性能。调整这些参数,可以更客观的评估数据库在不同负载下的性能和稳定性,并且找到这个数据库系统的能力边界。
- 使用不同的SQL语句来测试不同的负载
pgbench支持自定义测试事务脚本,用户可以编写脚本对特性的业务操作进行性能测试,来获取更有针对性的性能指标和评估结果。更加贴近实际应用需求和状态。
- 通过测试,来比较不同数据库配置产生的影响
这是数据库优化的一部分。对于不同配置、不同数据集、不同软硬件环境的数据库系统,通过调整配置方式,可以对数据库的运行进行优化。但是优化必须有一个评估测试机制,pgbench的测试结果和报告,就可以作为这个优化的性能基线和基础。
- 持续跟踪性能基线
可以通过定期执行pgbench,来为数据库系统建立一个持续性的性能基线。当数据库系统性能基线变更比较大的时候,就需要注意数据库的负载和性能的变化情况,及时做出调整,解决性能和故障隐患。
小结
本文探讨了一个PostgreSQL的数据库性能评估和测试工具-pgbench。包括其基本原理、安装和配置方式、使用方式和相关参数,以及扩展应用等相关的内容。
笔者认为如果作为一个系统运维人员,应该熟悉并使用该工具,持续的评估和监控数据库系统的基本性能和状态,来更好的支持上面的各种应用系统。
转载自:https://juejin.cn/post/7371378982278905910