- 此为实验场景,所有机器都为虚拟机
- OceanBase 集群部署规模为 1:1:1,租户的 PRIMARY_ZONE 设置为 RANDOM。
测试规格如下所示:
warehouses=100
loadWorkers=10
terminals=100
runMins=20
newOrderWeight=45
paymentWeight=43
orderStatusWeight=4
deliveryWeight=4
stockLevelWeight=4
测试环境
硬件配置
项目类型 | 内存 | CPU |
OceanBase 数据库 | 3 台 * 132G | 3 台 * 32 核 |
benchmarksql(复用OCP) | 1 台 * 132G | 1 台 * 32 核 |
ODP(复用OBServer) | 1 台 * 132G | 1 台 * 32 核 |
租户规格
- 4C16G,3个zone,unit_num为3
- 您需根据自身数据库的硬件配置进行动态调整。
项目类型 | 软件版本及型号 |
OceanBase 数据库 | V3.2.4 |
ODP | V3.2.9 |
BenchMarkSQL | V5.0 |
JDBC | mysql-connector-java-5.1.47 |
OS | CentOS Linux release 7.6.1810 (Core) |
CPU | Intel(R) Xeon(R) Gold 5320 CPU @ 2.20GHz |
环境信息
操作系统信息
$cat /etc/redhat-release
$uname -a
CPU信息
cat /proc/cpuinfo
内存信息
free -g
软件信息
#observer
cd /home/admin/oceanbase/bin
./observer --version
#obproxy
cd /home/admin/oceanbase/obproxy/bin
./obproxy --version
测试过程
注意:
benchmarksql需要JAVA环境,且版本不低于1.8.0,因此需确认系统已经部署好JAVA
压缩包上传至/root/tpcctest/目录下
下载相关工具及软件包:
下载编译工具ant:
wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.10.6-bin.zip
下载benchmaksql:
wget --no-check-certificate https://nchc.dl.sourceforge.net/project/benchmarksql/benchmarksql-5.0.zip
下载mysql的jdbc驱动:
wget https://downloads.mysql.com/archives/get/p/3/file/mysql-connector-java-5.1.47.zip
部署测试工具
准备java环境:
查看JAVA版本:
[root@kylinv10SP3 tpcctest]# java -version
java version "1.8.0_421"
Java(TM) SE Runtime Environment (build 1.8.0_421-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.421-b09, mixed mode)
准备编译环境:
解压ant工具:
cd /root/tpcctest/
unzip apache-ant-1.10.6-bin.zip
修改配置文件并使其生效
vim /etc/profile
export ANT_HOME=/root/rpcctest/apache-ant-1.10.6
export PATH=/root/rpcctest/apache-ant-1.10.6/bin:$PATH
source /etc/profile
验证ant安装:
ant -version
适配测试环境:
由于benchmarksql-5.0不支持oceanbase数据库,因此需要修改配置文件来适配
- 修改 benchmarksql-5.0/src/client/jTPCC.java 文件,增加 OceanBase 数据库相关内容。
if (iDB.equals("firebird"))
dbType = DB_FIREBIRD;
else if (iDB.equals("oracle"))
dbType = DB_ORACLE;
else if (iDB.equals("postgres"))
dbType = DB_POSTGRES;
#增加oceanbase部分
else if (iDB.equals("oceanbase"))
dbType = DB_OCEANBASE;
else
{
log.error("unknown database type '" + iDB + "'");
return;
}
2. 修改 benchmarksql-5.0/src/client/jTPCCConfig.java 文件,增加 OceanBase 数据库类型。
public final static int
DB_UNKNOWN = 0,
DB_FIREBIRD = 1,
DB_ORACLE = 2,
DB_POSTGRES = 3,
DB_OCEANBASE = 4;
3. 修改benchmarksql-5.0/src/client/jTPCCConnection.java 文件,在 SQL 子查询增加 AS L 别名。
default:
stmtStockLevelSelectLow = dbConn.prepareStatement(
"SELECT count(*) AS low_stock FROM (" +
" SELECT s_w_id, s_i_id, s_quantity " +
" FROM bmsql_stock " +
" WHERE s_w_id = ? AND s_quantity < ? AND s_i_id IN (" +
" SELECT ol_i_id " +
" FROM bmsql_district " +
" JOIN bmsql_order_line ON ol_w_id = d_w_id " +
" AND ol_d_id = d_id " +
" AND ol_o_id >= d_next_o_id - 20 " +
" AND ol_o_id < d_next_o_id " +
" WHERE d_w_id = ? AND d_id = ? " +
" ) " +
" )AS L");
break;
4. 重新编译修改后的源码。
[oceanbase@testdrier test]# cd benchmarksql-5.0
[oceanbase@testdrier benchmarksql-5.0]# ant
5. 修改文件:benchmarksql-5.0/run/funcs.sh,添加 OceanBase 数据库类型。
function setCP()
{
case "$(getProp db)" in
firebird)
cp="../lib/firebird/*:../lib/*"
;;
oracle)
cp="../lib/oracle/*"
if [ ! -z "${ORACLE_HOME}" -a -d ${ORACLE_HOME}/lib ] ; then
cp="${cp}:${ORACLE_HOME}/lib/*"
fi
cp="${cp}:../lib/*"
;;
postgres)
cp="../lib/postgres/*:../lib/*"
;;
#添加oceanbase部分
oceanbase)
cp="../lib/oceanbase/*:../lib/*"
;;
esac
myCP=".:${cp}:../dist/*"
export myCP
}
...省略
case "$(getProp db)" in
#添加oceanbase
firebird|oracle|postgres|oceanbase)
;;
"") echo "ERROR: missing db= config option in ${PROPS}" >&2
exit 1
;;
*) echo "ERROR: unsupported database type 'db=$(getProp db)' in ${PROPS}" >&2
exit 1
;;
esac
6. 修改 benchmarksql-5.0/run/runDatabaseBuild.sh。
AFTER_LOAD="indexCreates foreignKeys extraHistID buildFinish"
# 修改为:
AFTER_LOAD="indexCreates buildFinish"
创建测试租户:
- 查看可用资源
select a.zone,concat(a.svr_ip,':',a.svr_port) observer,
cpu_total,(cpu_total-cpu_max_assigned) cpu_free,
floor(mem_total/1024/1024/1024) as mem_total_gb,floor((mem_total-mem_max_assigned)/1024/1024/1024) mem_free_gb,
floor(disk_total/1024/1024/1024) as disk_total_gb,floor((disk_total-disk_assigned)/1024/1024/1024) disk_free_gb
from __all_virtual_server_stat a
order by a.zone,a.svr_ip;
2. 创建测试租户
create resource unit ut_test max_cpu=4,min_cpu=4,max_memory='16g',min_memory='16g',max_disk_size='10g',max_session_num=1000000;
create resource pool p_test unit='ut_test',unit_num=1,zone_list=('z1','z2','z3');
create tenant tnt_test resource_pool_list('p_test'),primary_zone='RANDOM' set ob_compatibility_mode='mysql',ob_tcp_invited_nodes='%';
3. 安装jdbc驱动
cd /root/tpcctest/
unzip mysql-connector-java-5.1.47.zip
在benchmarksql目录下创建lib/oceanbase目录并拷贝驱动
mkdir /root/tpcctest/benchmarksql-5.0/lib/oceanbase
cp /root/tpcctest/mysql-connector-java-5.1.47/mysql-connector-java-5.1.47.jar /root/tpcctest/benchmarksql-5.0/lib/oceanbase/
4. 修改配置文件
配置文件 props.ob 在 BenchmarkSQL 的 run/ 目录下,可以复制一个其它的配置文件再进行修改:
db=oceanbase
driver=com.mysql.jdbc.Driver
conn=jdbc:mysql://127.0.0.1:2881/tpccdb?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&allowMultiQueries=true
user=root@tnt_test
password=
warehouses=100
loadWorkers=20
//fileLocation=/data/temp/
terminals=100
//To run specified transactions per terminal- runMins must equal zero
runTxnsPerTerminal=0
//To run for specified minutes- runTxnsPerTerminal must equal zero
runMins=20
//Number of total transactions per minute
limitTxnsPerMin=0
//Set to true to run in 4.x compatible mode. Set to false to use the
//entire configured database evenly.
terminalWarehouseFixed=true
//The following five values must add up to 100
newOrderWeight=45
paymentWeight=43
orderStatusWeight=4
deliveryWeight=4
stockLevelWeight=4
// Directory name to create for collecting detailed result data.
// Comment this out to suppress.
resultDirectory=my_result_%tY-%tm-%td_%tH%tM%tS
osCollectorScript=./misc/os_collector_linux.py
osCollectorInterval=1
//osCollectorSSHAddr=user@dbhost
//osCollectorDevices=net_eth0 blk_sda
说明
- db:指定数据库类型。此处保持和模板一致即可。
- driver:驱动程序文件,推荐使用 MySQL 的 JDBC 驱动:mysql-connector-java-5.1.47,驱动下载地址
- conn:此处的 IP 建议填写 OceanBase Server 的 IP,端口为 OceanBase Server 部署端口,其他部分保持和模板一致。
- user & password:根据环境中使用的用户名、租户名以及密码即可。如果环境中有多个 OceanBase 集群,则 user 的格式建议为 {user_name}@{tenant_name}#{cluster_name}。
- warehouses:指定仓库数,仓库数决定性能测试的成绩。如果希望针对多节点的 OceanBase 集群进行测试,建议选择 1000 仓以上。如果机器配置有限,可以选择 100 仓进行测试。这里设置为100
- loadWorkers:指定仓库数据加载时的并发。如果机器配置较高,该值可以设置大一些,例如 100。如果机器配置有限,该值需要设置小一些,如 10 并发。过高的并发可能会导致内存消耗太快,出现报错,导致数据加载需要重新进行,这里设置为20
- terminals:指定性能压测时的并发数。建议并发数不要高于仓库数 * 10。否则,会有不必要的锁等待。在生产环境中,建议将此参数设置为最多 1000。在测试环境中,建议从 100 开始。这里设置为100。
- runMins:指定性能测试持续的时间。时间越久,越能考验数据库的性能和稳定性。建议不要少于 10 分钟,生产环境中机器建议不少于 1 小时。这里设置为20
数据准备
创建 tpccdb 数据库
在测试租户tnt_ test 中,创建本次测试的数据库 tpccdb:
obclient -h127.0.0.1 -P2883 -uroot@tnt_test -Doceanbase -A
CREATE DATABASE tpccdb;
创建表
建表脚本放在 benchmarskSQL 的 run/sql.common 下。建表脚本如下,采用分区表方式创建,大部分表按照仓库 ID 做 HASH 分区。分区数取决于要测试的数据规模和机器数。 如果集群只有 1 台或 3 台机器,分区数设置 9 个即可。如果是 5000 仓以上,或者集群中节点数较多,则分区数可以调整到 99。这里根据实际环境设置分区数为9
vim run/sql.comm/tableCreates.sql
CREATE TABLE bmsql_config (
cfg_name varchar(30) primary key,
cfg_value varchar(50)
);
-- drop tablegroup tpcc_group;
CREATE TABLEGROUP tpcc_group binding true partition by hash partitions 9;
CREATE TABLE bmsql_warehouse (
w_id integer not null,
w_ytd decimal(12,2),
w_tax decimal(4,4),
w_name varchar(10),
w_street_1 varchar(20),
w_street_2 varchar(20),
w_city varchar(20),
w_state char(2),
w_zip char(9),
primary key(w_id)
)tablegroup='tpcc_group' partition by hash(w_id) partitions 9;
CREATE TABLE bmsql_district (
d_w_id integer not null,
d_id integer not null,
d_ytd decimal(12,2),
d_tax decimal(4,4),
d_next_o_id integer,
d_name varchar(10),
d_street_1 varchar(20),
d_street_2 varchar(20),
d_city varchar(20),
d_state char(2),
d_zip char(9),
PRIMARY KEY (d_w_id, d_id)
)tablegroup='tpcc_group' partition by hash(d_w_id) partitions 9;
CREATE TABLE bmsql_customer (
c_w_id integer not null,
c_d_id integer not null,
c_id integer not null,
c_discount decimal(4,4),
c_credit char(2),
c_last varchar(16),
c_first varchar(16),
c_credit_lim decimal(12,2),
c_balance decimal(12,2),
c_ytd_payment decimal(12,2),
c_payment_cnt integer,
c_delivery_cnt integer,
c_street_1 varchar(20),
c_street_2 varchar(20),
c_city varchar(20),
c_state char(2),
c_zip char(9),
c_phone char(16),
c_since timestamp,
c_middle char(2),
c_data varchar(500),
PRIMARY KEY (c_w_id, c_d_id, c_id)
)tablegroup='tpcc_group' partition by hash(c_w_id) partitions 9;
CREATE TABLE bmsql_history (
hist_id integer,
h_c_id integer,
h_c_d_id integer,
h_c_w_id integer,
h_d_id integer,
h_w_id integer,
h_date timestamp,
h_amount decimal(6,2),
h_data varchar(24)
)tablegroup='tpcc_group' partition by hash(h_w_id) partitions 9;
CREATE TABLE bmsql_new_order (
no_w_id integer not null ,
no_d_id integer not null,
no_o_id integer not null,
PRIMARY KEY (no_w_id, no_d_id, no_o_id)
)tablegroup='tpcc_group' partition by hash(no_w_id) partitions 9;
CREATE TABLE bmsql_oorder (
o_w_id integer not null,
o_d_id integer not null,
o_id integer not null,
o_c_id integer,
o_carrier_id integer,
o_ol_cnt integer,
o_all_local integer,
o_entry_d timestamp,
PRIMARY KEY (o_w_id, o_d_id, o_id)
)tablegroup='tpcc_group' partition by hash(o_w_id) partitions 9;
CREATE TABLE bmsql_order_line (
ol_w_id integer not null,
ol_d_id integer not null,
ol_o_id integer not null,
ol_number integer not null,
ol_i_id integer not null,
ol_delivery_d timestamp,
ol_amount decimal(6,2),
ol_supply_w_id integer,
ol_quantity integer,
ol_dist_info char(24),
PRIMARY KEY (ol_w_id, ol_d_id, ol_o_id, ol_number)
)tablegroup='tpcc_group' partition by hash(ol_w_id) partitions 9;
CREATE TABLE bmsql_item (
i_id integer not null,
i_name varchar(24),
i_price decimal(5,2),
i_data varchar(50),
i_im_id integer,
PRIMARY KEY (i_id)
);
CREATE TABLE bmsql_stock (
s_w_id integer not null,
s_i_id integer not null,
s_quantity integer,
s_ytd integer,
s_order_cnt integer,
s_remote_cnt integer,
s_data varchar(50),
s_dist_01 char(24),
s_dist_02 char(24),
s_dist_03 char(24),
s_dist_04 char(24),
s_dist_05 char(24),
s_dist_06 char(24),
s_dist_07 char(24),
s_dist_08 char(24),
s_dist_09 char(24),
s_dist_10 char(24),
PRIMARY KEY (s_w_id, s_i_id)
)tablegroup='tpcc_group' use_bloom_filter=true partition by hash(s_w_id) partitions 9;
运行如下命令建表
./runSQL.sh props.ob sql.common/tableCreates_parts.sql
加载数据
- 加载数据即数据初始化,加载数据的速度,取决于机器配置,配置越高的机器,加载数据的速度越快。
./runLoader.sh props.ob
- 加载数据的 INSERT SQL 使用了 Batch Insert 特性,这点是在 props.ob 里的 JDBC URL 里指定的。开启该特性的写入性能会有明显提升。
创建索引
- 当数据初始化完成后,登录到集群的 tnt_test 租户,在 tpccdb 中补充创建如下两个索引。
use tpccdb;
CREATE INDEX bmsql_customer_idx1
on bmsql_customer (c_w_id, c_d_id, c_last, c_first) local;
CREATE INDEX bmsql_oorder_idx1
on bmsql_oorder (o_w_id, o_d_id, o_carrier_id, o_id) local;
开始测试
在开始性能测试之前,建议您先登录到对应租户做一次集群合并(major freeze),获得更好的测试结果。您可以通过如下的方式手动触发合并,这个过程并不是必须的。
obclient[oceanbase]> ALTER SYSTEM MAJOR FREEZE;
当看到merge_status全部为IDLE 时,表示合并完成。
MySQL [oceanbase]> SELECT * FROM oceanbase.__all_zone where name like '%merge%';
合并完成后,开始执行测试:
./runBenchmark.sh props.ob
测试结果
- TPC-C 用 tpmC 值(Transactions per Minute)来衡量系统最大有效吞吐量。其中 Transactions 以 NewOrder Transaction 为准,即最终衡量单位为每分钟处理的订单数。
- 14:00:50,422 [Thread-3] INFO jTPCC : Term-00, 14:00:50,423 [Thread-3] INFO jTPCC : Term-00,
14:00:50,423 [Thread-3] INFO jTPCC : Term-00, Measured tpmC (NewOrders) = 46939.9
14:00:50,423 [Thread-3] INFO jTPCC : Term-00, Measured tpmTOTAL = 104656.08
14:00:50,423 [Thread-3] INFO jTPCC : Term-00, Session Start = 2024-07-23 13:50:50
14:00:50,423 [Thread-3] INFO jTPCC : Term-00, Session End = 2024-07-23 14:00:50
14:00:50,423 [Thread-3] INFO jTPCC : Term-00, Transaction Count = 2087345
测试中遇到的问题:
- loadWorkers参数设置过大会导致加载数据时出错,导致warehouse创建不足100,在测试时会报错
- 处理方法:用./runSQL.sh props.ob sql.common/tableDrops.sql删除数据,调整参数后重新执行测试过程。