一次oceanbase数据库TPC-C测试实践

2024年 7月 23日 34.5k 0

  • 此为实验场景,所有机器都为虚拟机
  • 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数据库,因此需要修改配置文件来适配

  1. 修改 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"

创建测试租户:

  1. 查看可用资源
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删除数据,调整参数后重新执行测试过程。

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论