【Greenplum】TPC性能测试指南
1、准备工作
1.1、Greenplum集群
集群版本 | 集群规格 | 集群节点数 | 分片数 | 测试类型 |
---|---|---|---|---|
6.1.0 | 4C/32G/320G SSD | 1P/1M/16Segment | 4 | TPC-B、TPC-C |
6.1.0 | 4C/32G/320G SSD | 1P/1M/32Segment | 4 | TPC-H |
1.2、测试参考
网络链接 |
---|
https://segmentfault.com/a/1190000022522888 |
https://segmentfault.com/a/1190000021947479/ |
https://cloud.tencent.com/developer/article/1344308 |
2、TPC-B
2.1、简介
TPC-B是由TPC(Transaction Processing Performance Council,事务处理性能委员会)提供的benchmark,主要用于衡量一个系统每秒能够处理的并发事务数。TPC-B不像TPC-C那样模拟了现实生活中一个具体的交易场景,其中的事务都是由简单SQL构成的没有语义的事务(事务中混杂了大表与小表的插入、更新与查询操作),而且每个client的请求间也不会像TPC-C那样会有一个human think time的间隔时间,而是一旦前一个事务执行完成,立马会有下一个事务请求发出。因此,TPC-B经常用于对数据库系统的事务性能压测。TPC-B性能的衡量指标是每秒处理的事务数量,即TPS(Transactions per Second)。
2.2、测试步骤
2.2.1、集群参数优化(可选)
参数 | 参数值 | 说明 | 参数设置方式 |
---|---|---|---|
optimizer | off | 关闭针对AP场景的orca优化器,对TP性能更友好。 | gpconfig -c optimizer -v off |
shared_buffers | 8GB | 将数据共享缓存调大。修改该参数需要重启实例。 | gpconfig -c shared_buffers -v 8GB |
wal_buffers | 256MB | 将WAL日志缓存调大。修改该参数需要重启实例。 | gpconfig -c wal_buffers -v 256MB |
log_statement | none | 将日志输出关闭。 | gpconfig -c log_statement -v none |
random_page_cost | 10 | 将随机访问代价开销调小,有利于查询走索引。 | gpconfig -c random_page_cost -v 10 |
gp_resqueue_priority | off | 将resource queue关闭。需要重启实例 | gpconfig -c gp_resqueue_priority -v off |
resource_scheduler | off | 将resource queue关闭。需要重启实例 | gpconfig -c resource_scheduler -v off |
gp_enable_global_deadlock_detector | on | 控制是否开启全局死锁检测功能,打开它才可以支持并发更新/删除操作; | gpconfig -c gp_enable_global_deadlock_detector -v on |
checkpoint_segments | 2 | 影响checkpoint主动刷盘的频率,针对OLTP大量更新类语句适当调小此设置会增加刷盘频率,平均性能会有较明显提升; | gpconfig -c checkpoint_segments -v 2 –skipvalidation |
2.2.2、测试工具准备
工具 | 安装说明 |
---|---|
pgbench(version 9.5) | 源码安装:下载开源数据库PostgreSQL源码,然后到pgbench对应的目录中单独对pgbench进行编译生成可执行的二进制文件。 |
pgbench(version 9.5) | 二进制安装:可以先直接yum install postgresql95-server来安装PostgreSQL程序,此过程会自动安装pgbench工具。 |
2.2.3、测试数据准备
测试数据总量
表名 | 数据量(行数) |
---|---|
pgbench_accounts | 1142400000 |
pgbench_branches | 11424 |
pgbench_history | 0 |
pgbench_tellers | 114240 |
pgbench使用,填充因子为100,比例因子为11424
代码语言:javascript复制# 其中-F参数就是上文说的装填因子,-s值得是比例因子
./pgbench -i -F 100 -s 11424 -p port -h host -U user_name -d db_name
2.2.4、测试执行
执行TPC-B负载
代码语言:javascript复制# -c指定了连接数据库client数量,-j指定了建立连接使用的线程数量,推荐将两者设置成一样
# -T指定了测试执行时间,单位为秒
./pgbench -h host -p port -r -n -c 96 -j 96 -T 120 -f all.sql -U user_name -d db_name
all.sql
代码语言:javascript复制set scale 11424
set nbranches 1 * :scale
set ntellers 10 * :scale
set naccounts 100000 * :scale
setrandom aid 1 :naccounts
setrandom bid 1 :nbranches
setrandom tid 1 :ntellers
setrandom delta -5000 5000
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;
执行只读负载
代码语言:javascript复制# -c指定了连接数据库client数量,-j指定了建立连接使用的线程数量,推荐将两者设置成一样
# -T指定了测试执行时间,单位为秒
./pgbench -h host -p port -r -n -c 96 -j 96 -T 120 -f select.sql -U user_name -d db_name
select.sql
代码语言:javascript复制set scale 11424
set naccounts 100000 * :scale
setrandom aid 1 :naccounts
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
执行只更新负载
代码语言:javascript复制# -c指定了连接数据库client数量,-j指定了建立连接使用的线程数量,推荐将两者设置成一样
# -T指定了测试执行时间,单位为秒
./pgbench -h host -p port -r -n -c 96 -j 96 -T 120 -f update.sql -U user_name -d db_name
update.sql
代码语言:javascript复制set scale 11424
set naccounts 100000 * :scale
setrandom aid 1 :naccounts
setrandom delta -5000 5000
UPDATE pgbench_accounts SET abalance = abalance :delta WHERE aid = :aid;
执行只插入负载
代码语言:javascript复制# -c指定了连接数据库client数量,-j指定了建立连接使用的线程数量,推荐将两者设置成一样
# -T指定了测试执行时间,单位为秒
./pgbench -h host -p port -r -n -c 96 -j 96 -T 120 -f insert.sql -U user_name -d db_name
insert.sql
代码语言:javascript复制set scale 11424
set nbranches 1 * :scale
set ntellers 10 * :scale
set naccounts 100000 * :scale
setrandom aid 1 :naccounts
setrandom bid 1 :nbranches
setrandom tid 1 :ntellers
setrandom delta -5000 5000
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
3、TPC-C
3.1、简介
TPC-C是由TPC(Transaction Processing Performance Council,事务处理性能委员会)提供的专门针对联机交易处理系统的规范,TPC-C模拟的是一个大型的商品批发销售公司交易负载。这个事务负载主要由9张表组成,主要涉及5类交易类型:新订单生成(New-Order)、订单支付(Payment)、发货(Delivery)、订单状态查询(Order-Status)、和库存状态查询(Stock-Level)。TPC-C测试使用吞吐量指标(Transaction per minute,简称tpmC)来衡量系统的性能,其中所统计的事务指的是新订单生成的事务,即以每分钟新订单生成的事务数来衡量系统的性能指标(在标准的TPC-C测试中,新订单的事务数量占总事务数的45%左右)。
3.2、测试步骤
3.2.1、集群参数优化(可选)
参数 | 参数值 | 说明 | 参数设置方式 |
---|---|---|---|
optimizer | off | 关闭针对AP场景的orca优化器,对TP性能更友好。 | gpconfig -c optimizer -v off |
shared_buffers | 8GB | 将数据共享缓存调大。修改该参数需要重启实例。 | gpconfig -c shared_buffers -v 8GB |
wal_buffers | 256MB | 将WAL日志缓存调大。修改该参数需要重启实例。 | gpconfig -c wal_buffers -v 256MB |
log_statement | none | 将日志输出关闭。 | gpconfig -c log_statement -v none |
random_page_cost | 10 | 将随机访问代价开销调小,有利于查询走索引。 | gpconfig -c random_page_cost -v 10 |
gp_resqueue_priority | off | 将resource queue关闭。需要重启实例 | gpconfig -c gp_resqueue_priority -v off |
resource_scheduler | off | 将resource queue关闭。需要重启实例 | gpconfig -c resource_scheduler -v off |
gp_enable_global_deadlock_detector | on | 控制是否开启全局死锁检测功能,打开它才可以支持并发更新/删除操作; | gpconfig -c gp_enable_global_deadlock_detector -v on |
checkpoint_segments | 2 | 影响checkpoint主动刷盘的频率,针对OLTP大量更新类语句适当调小此设置会增加刷盘频率,平均性能会有较明显提升; | gpconfig -c checkpoint_segments -v 2 –skipvalidation |
3.2.2、测试工具准备
工具 | 安装说明 |
---|---|
benchmarksql | 软件说明:https://github.com/dreamedcheng/benchmarksql-5.0?spm=a2c4e.10696291.0.0.605719a4TUrbqS&file=benchmarksql-5.0 |
软件安装步骤: git clone https://github.com/dreamedcheng/benchmarksql-5.0.git yum install ant cd benchmarksql-5.0 ant |
3.2.3、测试数据准备
测试数据总量
表名 | 数据量(行数) |
---|---|
bmsql_warehouse | 1000 |
bmsql_district | 10000 |
bmsql_customer | 30000000 |
bmsql_history | 30000000 |
bmsql_new_order | 9000000 |
bmsql_oorder | 30000000 |
bmsql_order_line | 299976737 |
bmsql_item | 100000 |
bmsql_stock | 100000000 |
使用benchmarksql工具生成1000个warehouse的数据集
· 创建测试用户
代码语言:javascript复制CREATE USER benchmarksql WITH ENCRYPTED PASSWORD 'changeme';
CREATE DATABASE benchmarksql OWNER benchmarksql;
· 生成测试数据
代码语言:javascript复制-----------数据文件生成-----------
cd benchmarksql-5.0/run
./runLoader.sh gpdb.properties
-----------gpdb.properties文件内容说明-----------
db=postgres // 使用默认的postgres
driver=org.postgresql.Driver // 使用默认的org.postgresql.Drive
conn=jdbc:postgresql://host:port/benchmarksql //实例连接地址
user=benchmarksql // 连接实例的测试用户
password=your_password // 对应用户的密码
warehouses=1000 // 指定生成数据集warehouse的数量
loadWorkers=16 // 指定生成数据的线程数量,如果CPU core和内存 够用可以将其大小调大,这样速度更快
fileLocation=/data/tpcc_1000/ // 指定生成数据的存储目录
数据加载
· 使用benchmarksql提供的tableCreates.sql进行建表
代码语言:javascript复制psql -f tableCreates.sql -U user_name -d db_name -h host -p port
· 使用COPY命令导入数据
代码语言:javascript复制# 使用COPY方式将数据加载到数据库中
psql -h host -d db_name -p your_port -U user_name -c "copy bmsql_history from '/data/tpcc_1000/cust-hist.csv' with delimiter ',' null '';"
· 使用benchmarksql提供的indexCreates.sql进行创建索引
代码语言:javascript复制psql -f indexCreates.sql -U user_name -d db_name -h host -p port
收集统计信息
代码语言:javascript复制analyze bmsql_warehouse;
analyze bmsql_district;
analyze bmsql_customer;
analyze bmsql_history;
analyze bmsql_new_order;
analyze bmsql_oorder;
analyze bmsql_order_line;
analyze bmsql_item;
analyze bmsql_stock;
3.3.4、测试执行
代码语言:javascript复制-------------运行测试脚本---------------
./runBenchmark.sh gpdb.properties
-----------gpdb.properties文件内容说明-----------
db=postgres // 使用默认的postgres
driver=org.postgresql.Driver // 使用默认的org.postgresql.Drive
conn=jdbc:postgresql://host:port/benchmarksql //adbpg实例连接地址
user=benchmarksql // 连接adbpg实例测试的用户
password=your_password // 对应用户的密码
terminals=128 // TPC-C测试的并发数
//To run specified transactions per terminal- runMins must equal zero
runTxnsPerTerminal=0 // 使用默认的0
//To run for specified minutes- runTxnsPerTerminal must equal zero
runMins=10 // TPC-C执行时间,单位分钟
//Number of total transactions per minute
limitTxnsPerMin=30000000 // 使用默认的30000000
// 下面配置各个事务的比重,也使用如下给定的默认值
//The following five values must add up to 100
//The default percentages of 45, 43, 4, 4 & 4 match the TPC-C spec
newOrderWeight=45
paymentWeight=43
orderStatusWeight=4
deliveryWeight=4
stockLevelWeight=4
4、TPC-H
4.1、简介
TPC-H(商业智能计算测试)是美国交易处理效能委员会(TPC,TransactionProcessing Performance Council) 组织制定的用来模拟决策支持类应用的一个测试集。目前在学术界和工业界普遍采用它来评价决策支持技术方面应用的性能。TPC-H是根据真实的生产运行环境来建模,模拟了一套销售系统的数据仓库。其共包含8个基本关系,数据量可设定从1G~3T不等。其基准测试共包含了22个查询,主要评价指标各个查询的响应时间,即从提交查询到结果返回所需时间。其测试结果可综合反映系统处理查询时的能力。
4.2、测试步骤
4.2.1、测试工具准备
工具 | 安装说明 | 使用说明 |
---|---|---|
TPC-H dbgen | git clone https://github.com/gregrahn/tpch-kit.git |
cd tpch-kit/dbgen make MACHINE=LINUX DATABASE=POSTGRESQL | ./dbgen -help ./qgen -help |
4.2.2、测试数据准备
测试数据总量:TPC-H 中使用SF描述数据量,1SF 对应1GB 单位,1SF对应的数据量只是8个表的总数据量不包括索引等空间占用,准备数据时需预留更多空间,测试数据总量为1TB,即1000SF。
表名 | 数据条目数 |
---|---|
customer | 15000w |
lineitem | 5999989709 |
nation | 25 |
orders | 150000w |
part | 20000w |
partsupp | 80000w |
region | 5 |
supplier | 1000w |
测试数据文件生成 · 声明环境变量
代码语言:javascript复制export DSS_CONFIG=/.../tpch-kit/dbgen //tpch-kit/dbgen路径
export DSS_QUERY=$DSS_CONFIG/queries
export DSS_PATH=/path-to-dir-for-output-files //输出文件保存路径
· 方式一:直接生成1TB数据文件
代码语言:javascript复制cd tpch-kit/dbgen
./dbgen -vf -s 1000
· 方式二:并行生成分片文件
代码语言:javascript复制#生成数据文件
#10个分片文件
for((i=1;i<=10;i ));
do
./dbgen -s 1000 -S $i -C 10 -f &
done
代码语言:javascript复制#处理生成的 tbl 文件,tbl文件每行最后会多1个'|',可以用seed命令将每行后面的'|'去掉
sed -i 's/.$//' ./region.tbl &
sed -i 's/.$//' ./nation.tbl &
for((i=1;i<=10;i ));
do
sed -i 's/.$//' ./lineitem.tbl.$i &
sed -i 's/.$//' ./orders.tbl.$i &
sed -i 's/.$//' ./customer.tbl.$i &
sed -i 's/.$//' ./partsupp.tbl.$i &
sed -i 's/.$//' ./part.tbl.$i &
sed -i 's/.$//' ./supplier.tbl.$i &
done
建表语句
代码语言:javascript复制-- AO列存表、不开压缩、设置复制表
create table nation (
n_nationkey integer not null,
n_name char(25) not null,
n_regionkey integer not null,
n_comment varchar(152))
with (appendonly=true, orientation=column)
distributed REPLICATED;
create table region (
r_regionkey integer not null,
r_name char(25) not null,
r_comment varchar(152))
with (appendonly=true, orientation=column)
distributed REPLICATED;
create table part (
p_partkey integer not null,
p_name varchar(55) not null,
p_mfgr char(25) not null,
p_brand char(10) not null,
p_type varchar(25) not null,
p_size integer not null,
p_container char(10) not null,
p_retailprice DECIMAL(15,2) not null,
p_comment varchar(23) not null)
with (appendonly=true, orientation=column)
distributed by (p_partkey);
create table supplier (
s_suppkey integer not null,
s_name char(25) not null,
s_address varchar(40) not null,
s_nationkey integer not null,
s_phone char(15) not null,
s_acctbal DECIMAL(15,2) not null,
s_comment varchar(101) not null)
with (appendonly=true, orientation=column)
distributed by (s_suppkey);
create table partsupp (
ps_partkey integer not null,
ps_suppkey integer not null,
ps_availqty integer not null,
ps_supplycost DECIMAL(15,2) not null,
ps_comment varchar(199) not null)
with (appendonly=true, orientation=column)
distributed by (ps_partkey);
create table customer (
c_custkey integer not null,
c_name varchar(25) not null,
c_address varchar(40) not null,
c_nationkey integer not null,
c_phone char(15) not null,
c_acctbal DECIMAL(15,2) not null,
c_mktsegment char(10) not null,
c_comment varchar(117) not null)
with (appendonly=true, orientation=column)
distributed by (c_custkey);
create table orders (
o_orderkey bigint not null,
o_custkey integer not null,
o_orderstatus char(1) not null,
o_totalprice DECIMAL(15,2) not null,
o_orderdate date not null,
o_orderpriority char(15) not null,
o_clerk char(15) not null,
o_shippriority integer not null,
o_comment varchar(79) not null)
with (appendonly=true, orientation=column)
distributed by (o_orderkey);
create table lineitem (
l_orderkey bigint not null,
l_partkey integer not null,
l_suppkey integer not null,
l_linenumber integer not null,
l_quantity DECIMAL(15,2) not null,
l_extendedprice DECIMAL(15,2) not null,
l_discount DECIMAL(15,2) not null,
l_tax DECIMAL(15,2) not null,
l_returnflag char(1) not null,
l_linestatus char(1) not null,
l_shipdate date not null,
l_commitdate date not null,
l_receiptdate date not null,
l_shipinstruct char(25) not null,
l_shipmode char(10) not null,
l_comment varchar(44) not null)
with (appendonly=true, orientation=column)
distributed by (l_orderkey);
数据导入 · COPY方式导入,SQL脚本参考
代码语言:javascript复制copy nation from '/data/tpch_1t/nation.tbl' DELIMITER '|';
copy region from '/data/tpch_1t/region.tbl' DELIMITER '|';
copy supplier from '/data/tpch_1t/supplier.tbl' DELIMITER '|';
copy part from '/data/tpch_1t/part.tbl' DELIMITER '|';
copy partsupp from '/data/tpch_1t/partsupp.tbl' DELIMITER '|';
copy customer from '/data/tpch_1t/customer.tbl' DELIMITER '|';
copy orders from '/data/tpch_1t/orders.tbl' DELIMITER '|';
copy lineitem from '/data/tpch_1t/lineitem.tbl' DELIMITER '|';
1、可以psql连接到数据库后,依次单条执行上述SQL语句 2、直接执行脚本文件,方式如下
代码语言:javascript复制psql -f copy.sql -U user_name -d db_name -h host -p port
· 利用对象存储和外部表导入 1、将数据文件上传至JSS上 2、创建外部表
代码语言:javascript复制create extension jss;
create readable external table ext_nation ( n_nationkey int, n_name varchar(25), n_regionkey integer, n_comment varchar(152))
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
create readable external table ext_region ( R_REGIONKEY int, R_NAME CHAR(25),R_COMMENT VARCHAR(152))
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_lineitem ( l_orderkey bigint, l_partkey bigint, l_suppkey bigint,
l_linenumber bigint, l_quantity double precision, l_extendedprice double precision,
l_discount double precision, l_tax double precision, l_returnflag CHAR(1),
l_linestatus CHAR(1), l_shipdate DATE, l_commitdate DATE, l_receiptdate DATE,
l_shipinstruct CHAR(25), l_shipmode CHAR(10), l_comment VARCHAR(44))
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_orders ( o_orderkey bigint , o_custkey bigint, o_orderstatus CHAR(1) ,
o_totalprice double precision, o_orderdate DATE , o_orderpriority CHAR(15) , o_clerk CHAR(15) ,
o_shippriority bigint , o_comment VARCHAR(79) )
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_part ( p_partkey bigint , p_name VARCHAR(55) , p_mfgr CHAR(25) ,
p_brand CHAR(10) , p_type VARCHAR(25) , p_size bigint , p_container CHAR(10) ,
p_retailprice double precision , p_comment VARCHAR(23) )
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_partsupp ( ps_partkey bigint , ps_suppkey bigint ,
ps_availqty bigint , ps_supplycost double precision , ps_comment VARCHAR(199) )
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_supplier ( s_suppkey bigint , s_name CHAR(25) ,
s_address VARCHAR(40) , s_nationkey bigint , s_phone CHAR(15) , s_acctbal DECIMAL(15,2) ,
s_comment VARCHAR(101) )
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
CREATE readable external TABLE ext_customer ( c_custkey bigint , c_name VARCHAR(25) ,
c_address VARCHAR(40) , c_nationkey bigint , c_phone CHAR(15) , c_acctbal double precision ,
c_mktsegment CHAR(10) , c_comment VARCHAR(117) )
LOCATION('')
FORMAT 'TEXT' (DELIMITER '|' ) ;
3、将数据导入表中
代码语言:javascript复制insert into nation select * from ext_nation;
insert into region select * from ext_region;
insert into lineitem select * from ext_lineitem;
insert into orders select * from ext_orders;
insert into customer select * from ext_customer;
insert into part select * from ext_part;
insert into partsupp select * from ext_partsupp;
insert into supplier select * from ext_supplier;
收集统计信息
代码语言:javascript复制analyze nation;
analyze region;
analyze lineitem;
analyze orders;
analyze customer;
analyze part;
analyze partsupp;
analyze supplier;
4.2.3、测试执行
· 生成测试22条测试sql
代码语言:javascript复制for ((i=1;i<=22;i )); do
./qgen -v -c -s 1000 ${i} > /tmp/sf1000/tpch-q${i}.sql
done
· 执行sql
- 依次手动执行22条sql语句或利用脚本执行
total_cost=0
for i in {1..22}
do
echo "begin run Q${i}, /tmp/sf1000/tpch-q$i.sql , `date`"
begin_time=`date %s.%N`
#psql -h ${实例连接地址} -p ${端口号} -U ${数据库用户} -f /tmp/sf1000/tpch-q${i}.sql > ./log/log_q${i}.out
rc=$?
end_time=`date %s.%N`
cost=`echo "$end_time-$begin_time"|bc`
total_cost=`echo "$total_cost $cost"|bc`
if [ $rc -ne 0 ] ; then
printf "run Q%s fail, cost: %.2f, totalCost: %.2f, `date`n" $i $cost $total_cost
else
printf "run Q%s succ, cost: %.2f, totalCost: %.2f, `date`n" $i $cost $total_cost
fi
done