本記事では、benchmarksql5.0(TPC-Cベンチマークに基づくJava実装ツール)を使用して、OceanBaseクラウドデータベースのOLTP性能をテストする方法について説明します。
説明
ユーザーエクスペリエンスと使いやすさを向上させ、すべての開発者がデータベースを使用する際に良好なパフォーマンスを得られるようにするため、OceanBaseデータベースはV4.0.0以降、多くの最適化が施されました。この性能テスト方法は、基本的なパラメータに基づいて調整されており、開発者が良好なデータベース性能体験を得られるようにするものであり、TPC-C標準と完全に一致するものではありません。
TPCCの紹介
TPCCにはさまざまな実行方法があり、データベースの負荷をテストするツールとして使用されます。これは、eコマース業務をシミュレートし、主に新規注文、在庫照会、出荷、支払いなどのモジュールのテストを行います。詳細については、https://sourceforge.net/projects/benchmarksql/files/latest/download/をご参照ください。
環境の準備
プレッシャーマシンECS
ECSを1台用意してください。プレッシャーマシンがボトルネックにならないよう、OceanBase Observerのスペックと同じ仕様を推奨します。プレッシャーマシンECSはOceanBaseテナントと同一のVPCネットワークに属している必要があり、かつOceanBaseクラスタがプレッシャーマシンECSのホワイトリストアクセスを許可している必要があります。
OceanBaseインスタンスの作成
- OceanBaseクラスタインスタンスを1つ作成します。操作手順については、クラスタインスタンスの作成をご参照ください。
- テナントを作成し、クラスタのリソースに応じて必要に応じてテナントのスペックを設定します。操作手順については、テナントの作成をご参照ください。
- データベースを作成します。本記事ではtpcctestを例に説明します。操作手順については、データベースの作成をご参照ください。
Benchmark SQLツールのインストール:ダウンロードURL:Benchmark SQL
環境最適化
テストシナリオの説明:
OceanBase分散データベースの特性をより深く理解するために、データベースプロキシを有効にすることを推奨します。データベースプロキシ管理をご参照ください。
OceanBaseデータベースインスタンスでは、デフォルトでデータベースプロキシとOBserveが同一のECSにデプロイされます。データベースプロキシを有効にすると、パフォーマンスに積極的な影響を与えます。
テストの実行
Antのインストール
以下の手順に従って、プレッシャーマシンのECSにAntをインストールします:
Antをダウンロードします。
wget "http://archive.apache.org/dist/ant/binaries/apache-ant-1.10.6-bin.zip"Antをインストールします。
unzip apache-ant-1.10.6-bin.zip環境変数を設定します。
[admin@obtest004 ~]$ sudo vim /etc/profile #ant export ANT_HOME=xx/apache-ant-1.10.6 export PATH=xx/apache-ant-1.10.6/bin:$PATH [admin@obtest004 ~]$ source /etc/profileインストールが成功したかどうか確認します。
[admin@obtest004 ~]$ ant -version以下のメッセージが返された場合、インストールは成功です。
Apache Ant(TM) version 1.10.6 compiled on May 2 2019
Benchmark SQLのインストール
以下の手順に従って、プレッシャーマシンのECSにBenchmark SQLをインストールします:
Benchmark SQLをダウンロードします。
詳細については、Benchmark SQLのダウンロードURLをご参照ください。
Benchmark SQLを解凍します。
unzip ./benchmarksql-5.0.zipBenchmark SQLをコンパイルします。
Benchmark SQLの解凍ディレクトリに移動し、Antを使用してBenchmark SQLをコンパイルします:
[admin@obtest004 ~] $ cd benchmarksql-5.0 [admin@obtest004 benchmarksql-5.0] $ ant
Benchmark SQL5への対応
Benchmark SQL5はOceanBaseデータベースのTPC-Cテストをサポートしていないため、このセクションでは、Benchmark SQL5の一部のソースコードを修正して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; else if (iDB.equals("oceanbase")) //OceanBaseデータベース関連の内容を追加 dbType = DB_OCEANBASE; else { log.error("unknown database type '" + iDB + "'"); return; }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;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"); //「AS L」エイリアスを追加 break;修正後のソースコードを再コンパイルします。
[xxxxx@obtest004 ~]# cd benchmarksql-5.0 [xxxxx@obtest004 benchmarksql-5.0]# antbenchmarksql-5.0/runディレクトリに、prop.oceanbaseファイルを作成します。db=oceanbase driver=com.mysql.jdbc.Driver conn=jdbc:mysql://$oceanbase_url:$port/$db_name?rewriteBatchedStatements=true&allowMultiQueries=true&useLocalSessionState=true&useUnicode=true&characterEncoding=utf-8&socketTimeout=30000000 //ユーザー情報を完全に入力してください user=$user password=***** warehouses=1000 loadWorkers=40 terminals=600 database=$db_name //To run specified transactions per terminal- runMins must equal zero runTxnsPerTerminal=0 //To run for specified minutes- runTxnsPerTerminal must equal zero runMins=5 //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 //以下の5つの値は合計で100になる必要があります。 //デフォルトの割合45、43、4、4、4はTPC-C仕様に準拠しています。 newOrderWeight=45 paymentWeight=43 orderStatusWeight=4 deliveryWeight=4 stockLevelWeight=4 // 詳細な結果データを収集するために作成するディレクトリ名。 // このコメントアウトを削除すると、結果ディレクトリが作成されます。 resultDirectory=my_result_%tY-%tm-%td_%tH%tM%tS osCollectorScript=./misc/os_collector_linux.py osCollectorInterval=1 //osCollectorSSHAddr=user@dbhost //osCollectorDevices=net_eth0 blk_sdaprop.oceanbaseのパラメータ説明:
- JDBC接続文字列:
conn=jdbc:mysql://x.x.x.x(オーシャンベース接続アドレス):xx(port)/xxxx(dbname)?rewriteBatchedStatements=true&allowMultiQueries=true&useLocalSessionState=true&useUnicode=true&characterEncoding=utf-8&socketTimeout=3000000 - rewriteBatchedStatements:
- このパラメータは非常に重要で、データインポートの効率に大きな影響を与えるため、無視できません。
- データインポートが遅い場合、該当するテナントにログインし、
show full processlistコマンドでこの機能が有効になっているか確認できます。 - new orderトランザクションでもbatch updateが使用されるため、データインポートとベンチマークの両方の段階で有効にする必要があります。
- 並列数(terminals):600、MySQL互換モードのテナント設定では、並列数は具体的な設定に応じて動的に調整する必要があります。
- useLocalSessionState:autocommit、read_only、およびtransaction isolationの内部値(JDBC側のローカル値)を使用するかどうかを指定します。trueに設定することを推奨します。falseに設定した場合、リモート側にステートメントを送信する必要があるため、リクエストの送信頻度が増加し、パフォーマンスに影響します。
- warehouses/loadWorkersの2項目は負荷テストのデータ量を設定するために使用され、適宜調整可能です。
- numTerminals > 0 && numTerminals <= 10*numWarehouses、terminalsの範囲はこの区間内である必要があります。
- JDBC接続文字列:
ファイルを修正します:
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 firebird|oracle|postgres|oceanbase) #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 ;; esacmysql java connectorドライバを追加します。mysql-connector-java-5.1.47.jarを推奨します。
[xxxxxx@obtest004 benchmarksql-5.0]# mkdir lib/oceanbase/ [xxxxxx@obtest004 benchmarksql-5.0]# cp xx/mysql-connector-java-5.1.47.jar lib/oceanbase/benchmarksql-5.0/run/runDatabaseBuild.shを修正します。AFTER_LOAD="indexCreates foreignKeys extraHistID buildFinish" # 変更後: AFTER_LOAD="indexCreates buildFinish"BenchMarkSQL5内のSQLを改造します。
benchmarksql-5.0/run/sql.common/tableCreates.sqlをバックアップして書き換えます。CREATE TABLE bmsql_config ( cfg_name varchar(30) PRIMARY KEY, cfg_value varchar(50) ); CREATE TABLEGROUP IF NOT EXISTS tpcc_group binding true partition by hash partitions 96; 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 96; 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 96; 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 96; CREATE TABLE bmsql_history ( hist_id integer AUTO_INCREMENT, 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 96; 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 96; 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 96; 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 96; 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' partition by hash(s_w_id) partitions 96;benchmarksql-5.0/run/sql.common/tableDrops.sqlをバックアップして書き換えます。DROP TABLE bmsql_config; DROP TABLE bmsql_new_order; DROP TABLE bmsql_order_line; DROP TABLE bmsql_oorder; DROP TABLE bmsql_history; DROP TABLE bmsql_customer; DROP TABLE bmsql_stock; DROP TABLE bmsql_item; DROP TABLE bmsql_district; DROP TABLE bmsql_warehouse; DROP TABLEGROUP tpcc_group;benchmarksql-5.0/run/sql.common/indexCreates.sqlをバックアップして書き換えます。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;benchmarksql-5.0/run/sql.common/indexDrops.sqlをバックアップして書き換えます。ALTER TABLE bmsql_customer DROP INDEX bmsql_customer_idx1; ALTER TABLE bmsql_oorder DROP INDEX bmsql_oorder_idx1;
操作手順
以下のコマンドはすべて benchmarksql-5.0/run ディレクトリで実行します。以下の手順に従ってTPC-Cテストを実行します:
以下のコマンドを実行して、環境を初期化します:
[obcloud ~]./runDatabaseDestroy.sh prop.oceanbase以下のコマンドを実行して、テーブルを作成し、データをインポートします:
[obcloud ~]./runDatabaseBuild.sh prop.oceanbaseテナントでメジャーコンパクションを実行します:
メジャーコンパクションは、現在の大きなバージョンのSSTableとMemTableを前の大きなバージョンの全量静的データと統合し、ストレージ層の統計情報をより正確にし、生成される実行計画をより安定させます。
MySQL [oceanbase]> ALTER SYSTEM major freeze; Query OK, 0 rows affectedコンパクションが完了したかどうかを確認します:
MySQL [oceanbase]> select STATUS from oceanbase.DBA_OB_MAJOR_COMPACTION;STATUSがCOMPACTINGからIDLEに変わったら、コンパクションは完了です。
統計情報を手動で収集します。
MySQL [oceanbase]> call dbms_stats.gather_schema_stats('$db_name',degree=>96);以下のコマンドを実行して、負荷テストを開始します:
[obcloud ~]$./runBenchmark.sh prop.oceanbase