openGauss 执行 HyBench 基准测试
HyBench 是一个 HTAP 数据库基准测试,用于评估数据库在事务与分析混合处理场景下的性能。
https://benchmark.tempos.cn/beachmarkDesc-htap.html
总体流程
-
生成数据集
八个
.csv
文件,分别对应八张表。 可通过配置文件控制数据集的规模。 -
装载数据集
HyBench 提供了一些语句模板,用于创建这八张表及其索引。 表结构与索引是允许修改的,因此可以视情况进行适当修改。 建表完成后,直接用
COPY
命令导入数据就行。 -
配置与调优
在执行负载前允许修改数据库与系统配置,也允许通过
ANALYZE
等方式采集统计信息。 但执行负载预热是不允许的。 -
执行负载
负载总共 2 小时,分为三个阶段:OLAP、OLTP、OLXP,时间比例为 3:3:4。 在不改变语义的情况下,允许对负载语句进行修改。 通常的优化方法是为语句添加查询计划提示。
- OLAP:复杂的只读查询,语句主要包含多表连接、聚合函数等。
- OLTP:简单事务查询,主要是增删改查。
- OLXP:并发地执行 OLAP 与 OLTP 负载
工作路径
为方便描述,本文把工作路径配置成环境变量:
export HY_WORKSPACE=${HOME}/hybench
安装 HyBench
下载 JRE
本文使用的是毕昇 JDK 17。
因为 HyBench 是直接把 .jar
包塞仓库里的,不需要编译,所以下载 JRE 就行。
https://www.hikunpeng.com/developer/devkit/download/jdk
cd ${HY_WORKSPACE}
wget https://mirrors.huaweicloud.com/kunpeng/archive/compiler/bisheng_jdk/bisheng-jre-17.0.14-b12-linux-aarch64.tar.gz
tar -zxf bisheng-jre-17.0.14-b12-linux-aarch64.tar.gz
rm bisheng-jre-17.0.14-b12-linux-aarch64.tar.gz
于是 JRE 就会被解压到 ${HY_WORKSPACE}/bisheng-jre-17.0.14
目录中。
获取 HyBench
https://benchmark.tempos.cn/downloadTool.html
https://gitee.com/cstc2023/hybench
cd ${HY_WORKSPACE}
git clone https://gitee.com/cstc2023/hybench.git
配置 HyBench
首先修改配置文件 ${HY_WORKSPACE}/hybench/conf/og.props
,主要包括:
-
数据库连接配置
包括 JDBC 驱动类名、用户名、密码、URL 等
-
数据规模
缩放系数,默认是
1x
。 配置为1x
时,生成的数据集文件总共约 500MB,其中最大的transfer.csv
含有 6000000 条记录。 -
并发量
HyBench 在执行负载时会多线程并发访问数据库执行随机语句。 可为各个负载阶段分别配置并发量。
-
运行时间
可对各个负载阶段分别配置执行时间。
db=openGauss
classname=org.opengauss.Driver
username=hybench
password=<password>
url=jdbc:opengauss://localhost:2333/hybench_1x?useUnicode=true&characterEncoding=utf-8
url_ap=jdbc:opengauss://localhost:2333/hybench_1x?useUnicode=true&characterEncoding=utf-8
classname_ap=org.opengauss.Driver
username_ap=hybench
password_ap=<password>
# 数据规模,可配置为 `1x` 或 `10x`
sf=1x
at1_percent=35
at2_percent=25
at3_percent=15
at4_percent=15
at5_percent=7
at6_percent=3
# AP 并发量
apclient=1
# TP 并发量
tpclient=1
fresh_interval=20
contention_num=100
# 运行时间
apRunMins=36
tpRunMins=36
xpRunMins=48
# XP 并发量
xtpclient=1
xapclient=1
apround=1
然后修改 ${HY_WORKSPACE}/hybench/hybench
文件,依据文件里的提示,删除含有 exit -1
的第一行,并配置 ${JAVA_HOME}
:
export JAVA_HOME=${HY_WORKSPACE}/bisheng-jre-17.0.14
最后为该文件添加可执行权限:
chmod +x ${HY_WORKSPACE}/hybench/hybench
导入 openGauss JDBC
HyBench 通过 JDBC 访问数据库,JDBC 驱动的类名已经由上文中的 og.props
指定好了。
观察 ${HY_WORKSPACE}/hybench/hybench
发现 HyBench 在执行时会加载 ${HY_WORKSPACE}/hybench/lib
中的所有 .jar
包。
所以只需要把 openGauss JDBC 驱动移动到这个目录里就行。
https://opengauss.org/zh/download
这里的驱动下载 6.0.1 版本。
cd ${HY_WORKSPACE}
mkdir pkg && cd pkg
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.1/openEuler22.03/arm/openGauss-JDBC-6.0.1.tar.gz
tar -zxf openGauss-JDBC-6.0.1.tar.gz
mv opengauss-jdbc-6.0.1.jar ${HY_WORKSPACE}/hybench/lib
cd ${HY_WORKSPACE}
rm -rf pkg
部署 openGauss
安装 openGauss
为了方便描述,同样将 openGauss 的工作路径配置到环境变量中:
export OG_WORKSPACE=${HOME}/og
继续配置环境变量:
export GAUSSHOME=${OG_WORKSPACE}/install
export PGDATA=${OG_WORKSPACE}/data
export PGPORT=2333
export PGDATABASE=postgres
export LD_LIBRARY_PATH=${GAUSSHOME}/lib:${LD_LIBRARY_PATH}
export PATH=${GAUSSHOME}/bin:${PATH}
https://opengauss.org/zh/download
这里我下载的是 6.0.1 企业版,下载完之后解压到 ${GAUSSHOME}
目录中。
cd ${OG_WORKSPACE}
mkdir pkg && cd pkg
wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.1/openEuler22.03/arm/openGauss-All-6.0.1-openEuler22.03-aarch64.tar.gz
tar -zxf openGauss-All-6.0.1-openEuler22.03-aarch64.tar.gz
mkdir ${GAUSSHOME}
tar -C ${GAUSSHOME} -jxf openGauss-Server-6.0.1-openEuler22.03-aarch64.tar.bz2
cd ${OG_WORKSPACE}
rm -rf pkg
准备数据库节点
gs_initdb --nodename=single_node -w <password>
数据库节点会被生成在 ${PGDATA}
目录中,于是启动数据库:
gs_ctl start
创建数据库与用户
连接数据库:
gsql -r
为 HyBench 单独创建数据库与用户:
CREATE DATABASE hybench_1x;
CREATE USER hybench PASSWORD '<pasword>';
GRANT ALL PRIVILEGES ON DATABASE hybench_1x TO hybench;
\c hybench_1x
GRANT ALL PRIVILEGES ON SCHEMA public TO hybench;
装载数据集
建表
这里直接使用 HyBench 自带的建表脚本就行:
cd ${HY_WORKSPACE}/hybench
./hybench -t sql -f conf/ddl_og.sql -c conf/og.props
生成数据集
cd ${HY_WORKSPACE}/hybench
./hybench -t gendata -c conf/og.props
数据集是八个 .csv
文件,分别对应八张表,会被生成在 ${HY_WORKSPACE}/hybench/Data_1x
目录内。
导入数据集
gsql -d hybench_1x -c "COPY checking FROM '${HY_WORKSPACE}/hybench/Data_1x/checking.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY checkingaccount FROM '${HY_WORKSPACE}/hybench/Data_1x/checkingAccount.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY company FROM '${HY_WORKSPACE}/hybench/Data_1x/company.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY customer FROM '${HY_WORKSPACE}/hybench/Data_1x/customer.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY loanapps FROM '${HY_WORKSPACE}/hybench/Data_1x/loanApps.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY loantrans FROM '${HY_WORKSPACE}/hybench/Data_1x/loanTrans.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY savingaccount FROM '${HY_WORKSPACE}/hybench/Data_1x/savingAccount.csv' WITH (FORMAT 'text', DELIMITER ',');"
gsql -d hybench_1x -c "COPY transfer FROM '${HY_WORKSPACE}/hybench/Data_1x/transfer.csv' WITH (FORMAT 'text', DELIMITER ',');"
建索引
一般习惯是导入数据之后再建索引,能节约一些时间。 这里同样使用 HyBench 自带的脚本:
cd ${HY_WORKSPACE}/hybench
./hybench -t sql -f conf/ddl_og_afterload.sql -c conf/og.props
执行基准测试负载
在执行之前,HyBench 要求查询各表记录数,以确认数据集正常:
gsql -r -d hybench_1x
SELECT count(*) FROM checking;
SELECT count(*) FROM checkingaccount;
SELECT count(*) FROM company;
SELECT count(*) FROM customer;
SELECT count(*) FROM loanapps;
SELECT count(*) FROM loantrans;
SELECT count(*) FROM savingaccount;
SELECT count(*) FROM transfer;
确认记录数正确后,需要先检查负载语句的配置是否正常。
HyBench 自带的负载语句配置文件是 ${HY_WORKSPACE}/hybench/conf/stmt_opengauss.toml
。
直接用这个文件跑的话会出问题,需要做一些修改:
[TP-9]
sql = [
"SELECT balance FROM savingAccount WHERE accountid = ?;",
"UPDATE savingaccount SET balance = balance - ? where accountid = ?;",
"UPDATE savingaccount SET balance = balance + ? where accountid = ?;",
"INSERT INTO transfer VALUES (DEFAULT, ?, ?, ?, ?, ?);"
]
[TP-13]
sql = [
"INSERT INTO loantrans VALUES(DEFAULT, ?, ?, ?, ?, ?, ?, ?, ?);",
"UPDATE customer SET loan_balance = loan_balance + ? where custid = ?;",
"UPDATE company SET loan_balance = loan_balance + ? where companyid = ?;",
"UPDATE loanapps SET status = ? WHERE id = ?;"
]
[TP-14]
sql = [
"UPDATE savingaccount SET balance = balance + ? WHERE accountid = ?;",
"UPDATE loantrans SET status = 'lent', timestamp = ? WHERE id = ?;"
]
[TP-16]
sql = [
"SELECT balance FROM savingaccount WHERE accountid = ?;",
"UPDATE savingaccount SET balance = balance - ? WHERE accountid = ?;",
"UPDATE loantrans SET status = 'repaid', timestamp = ? WHERE id = ?;"
]
[AppQueue]
sql = "SELECT id, applicantid, amount, duration, status, timestamp FROM loanapps WHERE status= ? LIMIT 10000;"
[TransQueue]
sql = "SELECT id, applicantid, appid, amount, status, timestamp, duration, contract_timestamp, delinquency FROM loantrans WHERE status = ? LIMIT 10000;"
最后执行基准测试的负载:
./hybench -t runall -f conf/stmt_opengauss.toml -c conf/og.props
其中 stmt_opengauss.toml
指定了负载语句的模板。
HyBench 执行负载时会生成随机值填充到模板中。
og.props
指定了并发量与执行时间。
HyBench 负载的执行分为三个阶段(AP、TP、XP),每个阶段依据并发量创建线程分别执行负载语句。
每个线程会按照特定比例以随机的顺序执行该阶段的所有语句。
比如在 AP 阶段,每个线程实际上会被分配一个随机排序的语句队列,保证每条 AP 语句都各执行一次。
因此并发量足够高的情况下,语句的执行是均匀的。