PostgreSQL 主机性能测试方法 - 单机多实例

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
简介:

背景

业界有一些通用的数据库性能测试模型,可以用来测试硬件在不同测试模型下的性能表现。
参考
http://www.tpc.org/
https://github.com/oltpbenchmark/oltpbench
http://oltpbenchmark.com/

本文主要以PostgreSQL为例,向大家介绍一下,如何使用PostgreSQL来测试硬件的性能。

PostgreSQL 的功能非常的强大,所以可以适用于几乎所有的测试模型,同时用户还可以根据自己的应用场景设计测试模型。

一、机器部署

LVM部署

可选,如果你的主机有多个块设备,可以使用LVM的条带化,提高整体的吞吐和IOPS能力,当然你也可以使用多个表空间来利用不同的块设备。

举例

常用的配置,例如4个组,每个组为3块盘组成的RAID 5  
4 * (3 DISK RAID 5)   

lvcreate 参数举例

-i 4: 4 个组,所以条带宽度设置为4
-I 16: (3-1) * 8K   每个组3块盘,实际数据盘为2块,所以将条带大小设置为 2*8KB (8K指数据块的块大小,或者WAL的块大小)  

分区与对齐举例(假设为SSD,需要对齐)

parted -s /dev/sdb mklable gpt
parted -s /dev/sdc mklable gpt
parted -s /dev/sdd mklable gpt
parted -s /dev/sde mklable gpt
parted -s /dev/sdb mkpart primary 1MiB xxxxGB    # 对齐, 起步为条带大小的倍数 1MiB/16K 
parted -s /dev/sdc mkpart primary 1MiB xxxxGB
parted -s /dev/sdd mkpart primary 1MiB xxxxGB
parted -s /dev/sde mkpart primary 1MiB xxxxGB

逻辑卷

pvcreate /dev/sd[bcde]1
vgcreate -s 128MB vgdata01 /dev/sd[bcde]1
lvcreate -i 4 -I 16 -n lv01 -L 5T vgdata01
lvcreate -i 4 -I 16 -n lv02 -l 100%FREE vgdata01

创建文件系统(mkfs.ext4可以感知lvm条带配置,因此不需要设置mkfs.ext4的条带配置)

mkfs.ext4 /dev/mapper/vgdata01-lv01 -m 0 -O extent,uninit_bg -E lazy_itable_init=1 -T largefile -L lv01
mkfs.ext4 /dev/mapper/vgdata01-lv02 -m 0 -O extent,uninit_bg -E lazy_itable_init=1 -T largefile -L lv02
mkdir /u01
mkdir /u02
mount -o defaults,noatime,nodiratime,nodelalloc,barrier=0,data=writeback LABEL=lv01 /u01
mount -o defaults,noatime,nodiratime,nodelalloc,barrier=0,data=writeback LABEL=lv02 /u02

目录

mkdir -p /data01/digoal
mkdir -p /data02/digoal
chown digoal /data01/digoal
chown digoal /data02/digoal

io 调度 : SSD建议使用deadline 或 noop

echo deadline > /sys/block/sdb/queue/scheduler
echo deadline > /sys/block/sdc/queue/scheduler
echo deadline > /sys/block/sdd/queue/scheduler
echo deadline > /sys/block/sde/queue/scheduler

OS内核配置

配置举例,请根据环境调整
1. /etc/sysctl.conf

fs.aio-max-nr = 1048576
fs.file-max = 76724600
kernel.core_pattern= /data01/corefiles/core_%e_%u_%t_%s.%p
kernel.sem = 4096 2147483647 2147483646 512000
kernel.shmall = 107374182
kernel.shmmax = 274877906944
kernel.shmmni = 819200
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 262144  
net.core.rmem_max = 4194304     
net.core.wmem_default = 262144  
net.core.wmem_max = 4194304     
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_mem = 8388608 12582912 16777216
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syncookies = 1   
net.ipv4.tcp_timestamps = 1   
net.ipv4.tcp_tw_recycle = 0   
net.ipv4.tcp_tw_reuse = 1     
net.ipv4.tcp_max_tw_buckets = 262144
net.ipv4.tcp_rmem = 8192 87380 16777216
net.ipv4.tcp_wmem = 8192 65536 16777216
net.nf_conntrack_max = 1200000
net.netfilter.nf_conntrack_max = 1200000
vm.dirty_background_bytes = 409600000      
vm.dirty_expire_centisecs = 3000            
vm.dirty_ratio = 95                         
vm.dirty_writeback_centisecs = 100           
vm.extra_free_kbytes = 4096000
vm.min_free_kbytes = 2097152
vm.mmap_min_addr = 65536
vm.overcommit_memory = 0    
vm.overcommit_ratio = 90    
vm.swappiness = 0           
vm.zone_reclaim_mode = 0    
net.ipv4.ip_local_port_range = 40000 65535    

2. /etc/security/limits.conf

* soft    nofile  655360
* hard    nofile  655360
* soft    nproc   655360
* hard    nproc   655360
* soft    memlock unlimited
* hard    memlock unlimited
* soft    core    unlimited
* hard    core    unlimited

3. disable thp

cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag
cat /sys/kernel/mm/redhat_transparent_hugepage/enabled
cat /sys/kernel/mm/redhat_transparent_hugepage/defrag

[never]

4. io schedular

/boot/grub/grub.conf

title xxxxxxxxx
        root(0,0)  
        kernel /vmlinuz-............. numa=off elevator=deadline  

5. disable selinux

cat /etc/selinux/config

SELINUX=disabled
SELINUXTYPE=targeted

6. cgroup

yum install -y libcgroup

mkdir -p /cgroup/cpu
mkdir -p /cgroup/cpuacct
mkdir -p /cgroup/memory
mkdir -p /cgroup/blkio

mount -t cgroup -o cpu cpu /cgroup/cpu
mount -t cgroup -o cpuacct cpuacct /cgroup/cpuacct
mount -t cgroup -o memory memory /cgroup/memory
mount -t cgroup -o blkio blkio /cgroup/blkio

二、自定义测试模型

100个实例, 每个实例1亿记录 。

压测 insert on conflict update 。 (前期插入,后期全更新,对IO考验较大)

每个实例 2GB shared buffer 。

(使用CGROUP)

被测试机器部署

1. install postgresql 9.6

yum -y install rsync coreutils glib2 lrzsz sysstat e4fsprogs xfsprogs ntp readline-devel zlib zlib-devel openssl openssl-devel pam-devel libxml2-devel libxslt-devel python-devel tcl-devel gcc make smartmontools flex bison perl perl-devel perl-ExtUtils* OpenIPMI-tools openldap openldap-devel

tar -jxvf postgresql-9.6rc1.tar.bz2
cd postgresql-9.6rc1
./configure --prefix=/home/digoal/pgsql9.6rc1
make world -j 32
make install-world

2. 配置环境变量

$ vi ~/env.sh
export PS1="$USER@`/bin/hostname -s`-> "
export PGPORT=$1
export PGDATA=/data02/digoal/pg_root$PGPORT
export LANG=en_US.utf8
export PGHOME=/home/digoal/pgsql9.6rc1
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
export DATE=`date +"%Y%m%d%H%M"`
export PATH=$PGHOME/bin:$PATH:.
export MANPATH=$PGHOME/share/man:$MANPATH
export PGHOST=$PGDATA
export PGUSER=postgres
export PGDATABASE=postgres
alias rm='rm -i'
alias ll='ls -lh'
unalias vi

3. 初始化数据库集群脚本

$ vi ~/init.sh

for ((i=1921;i<1921+$1;i++))
do
  . ~/env.sh $i
  initdb -D $PGDATA -E UTF8 --locale=C -U postgres -X /data01/digoal/pg_xlog$i
  echo "local   all             all                                     trust" > $PGDATA/pg_hba.conf
  echo "host    all             all             127.0.0.1/32            trust" >> $PGDATA/pg_hba.conf
  echo "host    all             all             ::1/128                 trust" >> $PGDATA/pg_hba.conf
  echo "host    all             all             0.0.0.0/0               trust" >> $PGDATA/pg_hba.conf
done

4. 初始化数据库集群

$ rm -rf /data01/digoal/*
$ rm -rf /data02/digoal/*
$ cd ~ 
$ . ~/init.sh 100

5. 获取DM设备 major minor

# dmsetup ls
vgdata01-lv02   (253, 1)
vgdata01-lv01   (253, 0)

6. cgroup 限制

xlog盘限制iops 4000
data盘限制iops 800
cpu 0.7核, 周期1秒, quota 0.7秒
cpu real-time 调度统一 周期1秒, runtime 0.001秒
memory, 4G, 打开oom

7. 启动数据库集群脚本

$ vi ~/start.sh 

for ((i=1921;i<1921+$1;i++))
do
  . /home/digoal/env.sh $i
  cgcreate -g cpu:RULE$i
  cgcreate -g cpuacct:RULE$i
  cgcreate -g memory:RULE$i
  cgcreate -g blkio:RULE$i

  echo "253:0 4000" > /cgroup/blkio/RULE$i/blkio.throttle.write_iops_device
  echo "253:0 4000" > /cgroup/blkio/RULE$i/blkio.throttle.read_iops_device
  echo "253:1 800" > /cgroup/blkio/RULE$i/blkio.throttle.write_iops_device
  echo "253:1 800" > /cgroup/blkio/RULE$i/blkio.throttle.read_iops_device
  echo "70" > /cgroup/cpu/RULE$i/cpu.shares
  echo "1000000" > /cgroup/cpu/RULE$i/cpu.cfs_period_us
  echo "700000" > /cgroup/cpu/RULE$i/cpu.cfs_quota_us
  echo "1000000" > /cgroup/cpu/RULE$i/cpu.rt_period_us
  echo "1000" > /cgroup/cpu/RULE$i/cpu.rt_runtime_us
  echo "4294967296" > /cgroup/memory/RULE$i/memory.limit_in_bytes

  cgexec -g cpu:RULE$i -g cpuacct:RULE$i -g memory:RULE$i -g blkio:RULE$i su - digoal -c ". ~/env.sh $i ; nohup postgres -B 1GB -c port=$i -c listen_addresses='0.0.0.0' -c synchronous_commit=on -c full_page_writes=on -c wal_buffers=128MB -c wal_writer_flush_after=0 -c bgwriter_delay=10ms -c max_connections=100 -c bgwriter_lru_maxpages=1000 -c bgwriter_lru_multiplier=10.0 -c unix_socket_directories='.' -c max_wal_size=4GB -c checkpoint_timeout=30min -c checkpoint_completion_target=0.5 -c log_checkpoints=on -c log_connections=on -c log_disconnections=on -c log_error_verbosity=verbose -c autovacuum_vacuum_scale_factor=0.002 -c autovacuum_max_workers=4 -c autovacuum_naptime=5s -c random_page_cost=1.0 -c constraint_exclusion=on -c log_destination='csvlog' -c logging_collector=on -c maintenance_work_mem=256MB -c autovacuum_work_mem=256MB -D $PGDATA -k $PGDATA >/dev/null 2>&1 &"
done

8. 启动数据库集群
因为需要设置CGROUP,需要超级用户执行

$ sudo bash -c "bash"
# . /home/digoal/start.sh 100

9. 停集群脚本
为了尽快停库(checkpoint可能耗费大量IO),可以先将资源放大,然后停库。

$ vi ~/stop.sh 

for ((i=1921;i<1921+$1;i++))
do
  . /home/digoal/env.sh $i
  cgdelete cpu:RULE$i
  cgdelete cpuacct:RULE$i
  cgdelete blkio:RULE$i
  su - digoal -c ". ~/env.sh $i ; pg_ctl stop -m fast -w -t 600 -D $PGDATA"
  echo "0" > /cgroup/memory/RULE$i/memory.force_empty
  cgdelete memory:RULE$i
done

需要超级用户执行

$ sudo bash -c "bash"
# . /home/digoal/stop.sh 100

测试客户端机器部署

假设已安装postgresql 9.6

1. 目录

mkdir /data01/digoal
chown digoal /data01/digoal

2. 环境脚本

$ vi ~/env.sh

export PS1="$USER@`/bin/hostname -s`-> "
export PGPORT=$1
export PGDATA=/data02/digoal/pg_root$PGPORT
export LANG=en_US.utf8
export PGHOME=/home/digoal/pgsql9.6rc1
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
export DATE=`date +"%Y%m%d%H%M"`
export PATH=$PGHOME/bin:$PATH:.
export MANPATH=$PGHOME/share/man:$MANPATH
export PGHOST=$PGDATA
export PGUSER=postgres
export PGDATABASE=postgres
alias rm='rm -i'
alias ll='ls -lh'
unalias vi

3. 生成压测数据结构以及pgbench调用的测试脚本
定制内容都在这里。

$ vi ~/pgbench_init.sh 

for ((i=1921;i<1921+$1;i++))
do
  . ~/env.sh $i
  export PGHOST=$2
  psql -c "drop table if exists test; create table test(id int primary key, info text, crt_time timestamp);"
  echo "\set id random(1,100000000)" > ~/test$i.sql
  echo "insert into test (id,info,crt_time) values (:id, md5(random()::text), now()) on conflict on constraint test_pkey do update set info=excluded.info, crt_time=excluded.crt_time;" >> ~/test$i.sql
done

不需要执行。

4. 压测脚本

$ vi ~/pgbench.sh

mkdir -p /data01/digoal/log
for ((i=1921;i<1921+$1;i++))
do
  . ~/env.sh $i
  export PGHOST=$2
  nohup pgbench -M prepared -f ~/test$i.sql -n -r -P 1 -c 4 -j 4 -T 2592000 >>/data01/digoal/log/$2_$i.log 2>&1 &   # 每个实例测试4个连接
done

不需要执行,执行样例如下

cd ~
. ~/pgbench.sh 100 目标主机IP

5. 压测脚本

$ vi test.sh

#!/bin/bash

cd ~
. ~/pgbench_init.sh 100 $1

for ((i=1;i>0;i=1))
do
sleep 1
CNT=`ps -ewf|grep pgbench|grep -c -v grep`
if [ $CNT -eq 0 ]; then
  . ~/pgbench.sh 100 $1
  exit
fi
sleep 1
done


$ chmod 500 test.sh

6. 调用压测脚本

nohup ./test.sh 目标IP >/dev/null 2>&1 &

7. 压测结果

$ cat /data01/digoal/log/$2_$i.log

$ head -n 30000 /data01/digoal/log/$2_$i.log |tail -n 7200 > /tmp/1
$ cat /tmp/1|awk '{print $4 "," $7 "," $10}' >/tmp/2

输出TPS,RT,标准差。

TPS表示数据库视角的事务处理能力(也就是单个测试脚本的每秒调用次数)。

RT表示响应时间。

标准差可以用来表示抖动,通常应该在1以内(越大,说明抖动越厉害)。

8. 主机性能结果

$ sar -f ....

三、内置的测试模型tpc-b

只有有两处不一样,其他与定制测试一样。

1. 生成压测数据结构

$ vi ~/pgbench_init.sh 

for ((i=1921;i<1921+$1;i++))
do
  . ~/env.sh $i
  export PGHOST=$2
  nohup pgbench -i -s 2800 >/dev/null 2>&1 &   # 2.8 亿数据
done

不需要执行。

2. 压测脚本

$ vi ~/pgbench.sh

mkdir -p /data01/digoal/log
for ((i=1921;i<1921+$1;i++))
do
  . ~/env.sh $i
  export PGHOST=$2
  nohup pgbench -M prepared -n -r -P 10 -S -c 4 -j 4 -T 2592000 >>/data01/data/log/$2_$i.log 2>&1 &  # 每个实例测试4个连接
done

Count

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
1月前
|
测试技术 API 项目管理
API测试方法
【10月更文挑战第18天】API测试方法
46 1
|
1月前
|
安全 测试技术
北大李戈团队提出大模型单测生成新方法,显著提升代码测试覆盖率
【10月更文挑战第1天】北京大学李戈教授团队提出了一种名为“统一生成测试”的创新方法,有效提升了大模型如GPT-2和GPT-3在单一测试中的代码生成覆盖率,分别从56%提升至72%和从61%提升至78%。这种方法结合了模糊测试、变异测试和生成对抗网络等多种技术,克服了传统测试方法的局限性,在大模型测试领域实现了重要突破,有助于提高系统的可靠性和安全性。然而,该方法的实现复杂度较高且实际应用效果仍需进一步验证。论文可从此链接下载:【https://drive.weixin.qq.com/s?k=ACAAewd0AA48Z2kXrJ】
63 1
|
1月前
|
测试技术 UED
软件测试中的“灰盒”方法:一种平衡透明度与效率的策略
在软件开发的复杂世界中,确保产品质量和用户体验至关重要。本文将探讨一种被称为“灰盒测试”的方法,它结合了白盒和黑盒测试的优点,旨在提高测试效率同时保持一定程度的透明度。我们将通过具体案例分析,展示灰盒测试如何在实际工作中发挥作用,并讨论其对现代软件开发流程的影响。
|
2月前
|
人工智能 测试技术 开发者
北大李戈团队提出大模型单测生成新方法,显著提升代码测试覆盖率
【9月更文挑战第27天】北京大学李戈团队在人工智能领域取得重要突破,提出HITS新方法,通过将待测方法分解为多个切片并利用大型语言模型逐个生成测试用例,显著提升代码测试覆盖率,尤其在处理复杂方法时效果显著,为软件开发和测试领域带来新希望。尽管存在一定局限性,HITS仍展示了巨大潜力,未来有望克服限制,推动软件测试领域的创新发展。论文详情见【https://www.arxiv.org/pdf/2408.11324】。
102 6
|
16天前
|
数据采集 自然语言处理 数据库
深入体验阿里云通义灵码:测试与实例展示
阿里云通义灵码是一款强大的代码生成工具,支持自然语言描述需求,快速生成高质量代码。它在测试、代码质量和用户体验方面表现出色,能够高效地生成 Python 和 Java 等语言的代码,助力开发者提升开发效率和代码质量。无论是新手还是资深开发者,都能从中受益匪浅。
深入体验阿里云通义灵码:测试与实例展示
|
1月前
|
机器学习/深度学习 JSON 算法
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-Seg模型进行图像分割的完整流程,包括图像分割的基础知识、YOLOv5-Seg模型的特点、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。通过实例代码,指导读者从自定义数据集开始,直至模型的测试验证,适合深度学习领域的研究者和开发者参考。
506 3
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
|
23天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
64 2
|
1月前
|
测试技术 Python
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
本文介绍了使用Python的unittest框架来加载测试用例的四种方法,包括通过测试用例类、模块、路径和逐条加载测试用例。
66 0
自动化测试项目学习笔记(三):Unittest加载测试用例的四种方法
|
1月前
|
测试技术 Python
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
本文主要介绍了自动化测试中setup、teardown、断言方法的使用,以及unittest框架中setUp、tearDown、setUpClass和tearDownClass的区别和应用。
65 0
自动化测试项目学习笔记(二):学习各种setup、tearDown、断言方法
|
1月前
|
测试技术 UED
软件测试中的探索性测试:一种高效且灵活的测试方法
本文将深入探讨探索性测试的核心概念、优势及其在实际项目中的应用。我们将从探索性测试的基本定义入手,逐步解析其在不同场景下的具体实施方法和最佳实践。通过详细的案例分析和方法对比,帮助读者全面了解这种既高效又灵活的软件测试技术。

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 下一篇
    无影云桌面