使用SysBench测试PostgreSQL并发访问性能

本文使用SysBench测试PostgreSQL服务在不同并发线程数下的性能表现。

一、环境信息

被测服务器(192.168.132.167):

  • 4核8线程,32GB,1TB 7200转机械硬盘
  • CentOS 7.9
  • PostgreSQL 9.6.2

测试客户端(192.168.130.152):

  • 4核8线程,32GB,2TB 7200转机械硬盘
  • CentOS 7.9
  • SysBench 1.0.17

网络:

  • 千兆以太局域网

二、测试综合性能

为了测试不同参数下数据库的性能表现,我们通常会将测试过程写成shell脚本循环执行。由于性能测试的时间可能很长,我们用tee命令将每次测试的结果保存到文件以免丢失数据。

我们用下面的脚本测试在不同线程数下的综合性能(oltp_read_write)。

#!/bin/sh
pg_host=192.168.132.167
pg_port=5432
pg_user=sbtest
pg_password=password
pg_db=sbtest

for ((threads=5; threads<=160; threads=threads+5));do
    sysbench oltp_read_write \
    --pgsql-host=$pg_host --pgsql-port=$pg_port \
    --pgsql-user=$pg_user --pgsql-password=$pg_password \
    --pgsql-db=$pg_db \
    --table_size=100000 --tables=12 \
    prepare

    sysbench oltp_read_write \
    --pgsql-host=$pg_host --pgsql-port=$pg_port \
    --pgsql-user=$pg_user --pgsql-password=$pg_password \
    --pgsql-db=$pg_db \
    --report-interval=5 \
    --table_size=100000 --tables=12 \
    --threads=$threads \
    --time=30 \
    run | tee -a result.txt 2>&1

    sysbench oltp_read_write \
    --pgsql-host=$pg_host --pgsql-port=$pg_port \
    --pgsql-user=$pg_user --pgsql-password=$pg_password \
    --pgsql-db=$pg_db \
    --tables=12 \
    cleanup
done

上面测试脚本的结果保存在result.txt文件里,使用下面的命令可以获取到所需的数据项,方便粘贴到excel表格里画图:

获取平均QPS值(考虑到超过100000的情况因此用两个cut实现):
cat result.txt |grep queries:|cut -c 40-57|cut -d '(' -f 2
获取平均Latency值:
cat result_read.txt |grep avg:|cut -c 48-65

为减小误差,我们把测试脚本执行了2次,将每次得到的各线程数下的QPS数值画成一条曲线并叠加,得到下面的统计图,其中横轴是并发线程数,纵轴是QPS均值:

file

测试结果里各个线程数下TPS数值与QPS都十分接近20:1的关系,所以这里不单独画图展示TPS了。

从图中可以看出,两次测试结果比较接近,随着线程数增加QPS指标也同步增加,在120线程左右达到峰值。

两次测试的平均请求延迟(latency,毫秒)统计如下图所示,其中横轴仍然是并发线程数,纵轴是延迟时间:

file

延迟基本与线程数正相关,并且在140线程以上斜率有所增加。

三、测试只读性能

我们使用sysbench oltp_read_only命令测试纯读取场景下,不同线程数的QPS表现:

#!/bin/sh
pg_host=192.168.132.167
pg_port=5432
pg_user=sbtest
pg_password=password
pg_db=sbtest

sysbench oltp_read_only \
--db-driver=pgsql \
--pgsql-host=$pg_host --pgsql-port=$pg_port \
--pgsql-user=$pg_user --pgsql-password=$pg_password \
--pgsql-db=$pg_db \
--table_size=100000 \
--tables=12 \
prepare

for ((threads=5; threads<=120; threads=threads+5));do
    sysbench oltp_read_only \
    --db-driver=pgsql \
    --report-interval=5 \
    --table-size=100000 \
    --tables=12 \
    --threads=$threads \
    --time=30 \
    --pgsql-host=$pg_host --pgsql-port=$pg_port \
    --pgsql-user=$pg_user --pgsql-password=$pg_password \
    --pgsql-db=$pg_db \
    run | tee -a result.txt 2>&1
done

sysbench oltp_read_only \
--db-driver=pgsql \
--pgsql-host=$pg_host --pgsql-port=$pg_port \
--pgsql-user=$pg_user --pgsql-password=$pg_password \
--pgsql-db=$pg_db \
--tables=12 \
cleanup

为减小误差,我们把测试脚本执行了2次,将每次得到的各线程数下的QPS数值画成一条曲线并叠加,得到下面的统计图,其中横轴是并发线程数,纵轴是QPS均值:

file

测试结果里各个线程数下,TPS数值与QPS都十分接近16:1的关系,所以这里不单独画图展示TPS了。

从图中可以看出,两次测试结果比较接近,都是在50个并发线程时达到QPS峰值(大约35000请求/秒)。

两次测试的平均请求延迟(latency,毫秒)统计如下图所示,其中横轴仍然是并发线程数,纵轴是延迟时间:

file

从图中可以看出,两次测试结果比较接近,随着线程数量的增加,平均延迟是单调上升的,即使在并发50个线程QPS已经达到峰值后,平均延迟也是上涨的。因此从这两项测试结果来看,在50线程以上继续增加线程数量是没有意义的。