本文介紹使用JMeter測試OceanBase性能的方法。
這個方法适用于所有關系資料庫(包括分布式的)。
測試方法。
在前文《
分布式資料庫選型測試(一)——測試需求》裡已經就資料庫性能對比測試的方法做過總結,這裡再補充一些内容。
測試OceanBase叢集性能的方法有很多,如sysbench、benchmarksql。不過如果想對比OceanBase資料庫跟傳統資料庫、其他友商分布式資料庫産品的性能差異,還需要找到一個能适用彼此的測試方案。sysbench的功能太弱,且隻有0.4 支援ORACLE,不同版本的sql還不完全一樣。benchmarksql倒是很合适,有一定業務模型,内部複雜但是評測标準簡單,容易統一比較。不過如果客戶還想測試一點點業務sql,那就隻能自己寫程式了。如果嫌寫程式麻煩,還有個簡單的辦法就是使用JMeter。
資料庫驅動
使用JMeter測試OceanBase性能的時候也需要加載OceanBase的Java驅動。檔案可以從官網的下載下傳檔案中擷取,或者從這個途徑:
https://github.com/obpilot/benchmarksql-5.0/blob/master/lib/oracle/oceanbase-client-1.0.9.jar下載下傳的oceanbase-client-1.0.9.jar需要放到Jmeter的lib檔案夾夾中。
業務場景定義
建表語句
請在OB-ORACLE租戶下業務賬戶執行下面SQL 。
$obclient -h127.1 -utpcc@obbmsql#obdemo -P2883 -p123456 -c -A tpcc
CREATE TABLE account(id number NOT NULL PRIMARY KEY
, name varchar2(50) NOT NULL UNIQUE
, value number NOT NULL
, gmt_create date DEFAULT sysdate NOT NULL
, gmt_modified date DEFAULT sysdate NOT NULL );
CREATE SEQUENCE seq_account START WITH 1 INCREMENT BY 1 nocycle;
delimiter /
CREATE OR REPLACE TRIGGER trg_before_ins_account
BEFORE INSERT
ON account
FOR EACH ROW
BEGIN
select seq_account.nextval INTO :NEW.id FROM DUAL ;
END;
/
delimiter ;
示例中的觸發器和序列不是必須的。這隻是一種常用的用法。ORACLE租戶的序列能保證值遞增(序列屬性是NOCYCLE),但不一定保證連續(事務復原時會浪費序列值)。這裡的測試案例期望産生的測試資料是連續的。
造連續自增的測試資料的方法就不說了。
場景SQL
此次測試模拟一個分布式事務,SQL類似如下:
-- session
begin ;
select value from account where id = 174 for update ;
update account set value = value - 7 , gmt_modified = sysdate where id = 174 ;
update account set value = value + 7 , gmt_modified = sysdate where id = 165 ;
-- commit or rollback;
commit;
建立JMeter測試計劃
JMeter能在指令行下運作,也可以以圖形界面運作。這裡我簡單點直接用圖形界面這種方式。
建立測試計劃
測試計劃屬性

建立 Thread-Group
這裡有很多跟多線程運作有關的JMeter參數,具體說明可以檢視JMeter官網文檔。
注意這裡的Number of Threads是指壓測的用戶端線程數。
JDBC連接配接屬性
這裡面屬性很多,都是一個連接配接池常具備的參數。有興趣的可以看看網上關于Java連接配接池配置的經驗。
這裡面也有幾個參數強調一下:
-
Max Number of Connections:這個指連接配接池裡最多多少個連接配接。如果壓測線程數遠高于這個值,那麼壓測線程可能會需要等待這個連接配接池建立或返還資料庫連接配接(即到OceanBase的連接配接)給它。如果等不到可能會報錯。在這個環節,用戶端壓測線程拿不到連接配接,不一定跟OceanBase資料庫有直接關系。在Java應用裡面也同理。
Transaction Isolation:這個是資料庫連接配接使用的事務隔離級别,OceanBase支援兩種事務隔離級别:讀已送出(Read-Committed)和序列化(Serializable)。前者很常見容易了解,後者是ORACLE特有隔離級别,OceanBase也相容了。有興趣的可以看看《OceanBase事務引擎特性和應用實踐分享》。了解序列化隔離級别的特點和場景可以加深自己對資料庫事務的了解。
-
Test While Idle:這個是連接配接探活(keepalive)設定。這個設定對應用卻很優必要。有時候應用會說資料庫連接配接報錯說在一個關閉的連接配接上執行SQL報錯,這個就是因為連接配接池中的資料庫連接配接因為其他原因已斷開了。是以,資料庫連接配接池通常都需要探活機制。這裡由于是壓測場景基本無閑置連接配接,是以可以設定為False。
Database URL:資料庫連接配接URL格式,直接類似填寫 jdbc:oceanbase://11.166.87.5:2883/tpcc 。
-
JDBC Driver Class:資料庫驅動中的Main類名,這個要按OceanBase格式填寫,com.alipay.oceanbase.obproxy.mysql.jdbc.Driver。
Username:使用者格式,OceanBase的使用者名格式比較特别,是租戶裡使用者名@租戶名#叢集名或叢集名:租戶名:租戶裡使用者名。如 tpcc@obbmsql#obdemo
事務參數(變量)
在這個測試裡,有三個變量:賬戶A,賬戶B,轉賬金額,是以需要設定參數。
賬戶參數和金額采取随機數,随機數的值不要超出測試資料實際範圍。
事務控制器
這裡面是維護每個事務的邏輯。事務由一組JDBC請求組成。
開啟事務
選擇 Autocommit(false),開啟顯式事務。
查詢賬戶A的餘額
這裡查詢賬戶A的記錄會同時鎖住這筆記錄,即常用的悲觀鎖技術。這一步看測試需要,不是必需的。
select value from account where id = ? for update ;
注意所有參數都使用 Prepared Statement,以下同。
這一步後面按業務設計應該檢查一下傳回值是否大于要轉賬的值,如果不滿足就是“轉賬餘額不足”。這裡我沒有去研究JMeter如果根據查詢傳回值進行邏輯判斷。有興趣的朋友可以自己研究。
扣減賬戶A的餘額
SQL很簡單。
update account set value = value - ? , gmt_modified = sysdate where id = ? ;
多個綁定參數使用逗号(,)分隔。
然後要新增一個Post處理邏輯,擷取更新傳回值
增加賬戶B的餘額
update account set value = value + ? , gmt_modified = sysdate where id = ? ;
同樣,需要增加一個Post處理器
判斷邏輯——成功流程
如果上面兩筆賬戶的更新成功,則送出事務。
新增判斷控制 IF
新增動作
判斷邏輯——失敗流程
如果上面兩筆賬戶的更新有一筆失敗,則復原事務。
檢視結果細節
可以檢視成功、失敗的結果
檢視彙總報告
資料庫SQL審計
在業務租戶下的sys使用者下,利用OceanBase的SQL審計功能可以檢視JMeter發出的測試SQL細節。在這個裡面可以看到SQL的執行細節(錯誤碼、耗時、等待事件之類),對分析性能結果非常有幫助。
select /*+ read_consistency(weak) query_timeout(1000000000) */ TO_CHAR(request_time / (1000000 * 60 * 60 * 24) + TO_DATE('1970-01-01 08:00:00', 'YYYY-MM-DD HH:MI:SS'), 'HH24:MI:SS') request_time_, sid ,query_sql, affected_rows,return_rows, ret_code, event, state, plan_type,is_hit_plan, elapsed_time, execute_time, queue_time, decode_time, get_plan_time, block_cache_hit, bloom_filter_cache_Hit, block_index_cache_hit, disk_reads,retry_cnt,table_scan, memstore_read_row_count, ssstore_read_row_count, round(request_memory_used/1024/1024) req_mem_mb
from gv$sql_audit
where 1=1 AND user_name='TPCC' AND DB_NAME='TPCC' AND query_sql NOT LIKE '%SHOW%'
order by request_time desc ;
其他
這個測試場景和方法雖然簡單,但實際測試中可能會遇到一些問題。分析這些問題也可以了解OceanBase的特點。
如果測試資料記錄數很少,使用一定的并發壓測,很容易就出現鎖等待和阻塞現象。這個時候看報告會發現update的延時會增加,甚至rollback的事件會增加。如果預設的鎖等待時間和事務逾時時間很長,可能發現update都堵在那裡,會有很多死鎖事件。詳情請參見《
從ORACLE/MySQL到OceanBase:資料庫逾時機制》。