OceanBase學習之路16|體驗 OceanBase 資料庫熱點行更新能力
隨著線上交易、電商行業的發展,業務系統的熱點併發壓力逐漸成為一種挑戰。熱點賬戶短時間內餘額大量更新,或者熱門商品在營銷活動中限時秒殺,都是這種場景的直接體現。熱點更新的本質是短時間內對資料庫中的同一行資料的某些欄位值進行高併發的修改(餘額,庫存等),這其中的瓶頸主要在於關係型資料庫為了保持事務一致性,對資料行的更新都需要經過“加鎖->更新->寫日誌提交->釋放鎖”的過程,而這個過程實質上是序列的。所以,提高熱點行更新能力的關鍵在於如何儘可能縮短持有鎖的時間。
雖然學術界很早就提出了“提前解行鎖(Early Lock Release)”的方案(即 ELR),但是因為 ELR 的異常處理場景非常複雜,業界很少有成熟的工業實現。OceanBase 資料庫在這個問題上透過持續的探索,提出了一種基於分散式架構的實現方式,提升類似業務場景中單行併發更新的能力,作為 OceanBase 資料庫“可擴充套件的 OLTP ”中的關鍵能力之一。
本篇文章中,我們將透過構造一個多併發單行更新的場景,介紹 OceanBase 資料庫 ELR 特性的使用方法和效果對比。因為是在多併發壓力場景下驗證,我們建議至少使用和本例中相同的節點規格進行體驗和驗證,達到更好的效果。關於 OceanBase 資料庫 ELR 的設計和原理實現,因其較為複雜,本文暫不做詳細討論。
本例中我們使用一臺 16C-128GB 配置的節點,下面我們來分步驟體驗 OceanBase 資料庫 ELR 特性。
1.建立測試表,插入測試資料
首先我們在測試庫中建立一張表,並插入測試資料。
CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ); INSERT INTO sbtest1 VALUES(1,0,'aa','aa');
本例中我們透過類似
UPDATE sbtest1 SET k=k+1 WHERE id=1
的語句,以主鍵查詢方式針對
k
列進行併發更新,您也可以插入更多資料進行測試,但因為是針對單行併發的壓測,對整體結果基本沒有影響。
2.構造併發更新場景
本例中,我們使用 Python 多執行緒的方式來模擬併發更新,同時啟動 50 個 Thread,每個 Thread 併發的對 id=1 的行資料將 k 欄位值 +1。您在自己搭建的環境中也可以直接使用下面的指令碼
ob_elr.py
進行測試。只需要將指令碼中的資料庫連線資訊修改一下即可使用。
#!/usr/bin/env python3 from concurrent.futures import ThreadPoolExecutor import pymysql import time import threading # database connection info config = { 'user': 'root@test', 'password': 'root', 'host': '172.19.81.183', 'port': 2881, 'database': 'test' } # parallel thread and updates in each thread parallel = 50 batch_num = 2000 # update query def update_elr(): update_hot_row = ("update sbtest1 set k=k+1 where id=1") cnx = pymysql.connect(**config) cursor = cnx.cursor() for i in range(0,batch_num): cursor.execute(update_hot_row) cursor.close() cnx.close() start=time.time() with ThreadPoolExecutor(max_workers=parallel) as pool: for i in range(parallel): pool.submit(update_elr) end = time.time() elapse_time = round((end-start),2) print('Parallel Degree:',parallel) print('Total Updates:',parallel*batch_num) print('Elapse Time:',elapse_time,'s') print('TPS on Hot Row:' ,round(parallel*batch_num/elapse_time,2),'/s')
3.預設配置下執行測試
作為對比參照,我們先在預設不開啟 ELR 的情況下測試,在測試機器上直接執行
ob_elr.py
指令碼。
本例中我們採用 50 併發數,總計更新 100000 次。
./ob_elr.py
執行完成,測試指令碼輸出執行時間和 TPS:
[root@obce00 ~]# ./ob_elr.py Parallel Degree: 50 Total Updates: 100000 Elapse Time: 54.5 s TPS on Hot Row: 1834.86 /s
測試結果
在不開啟 ELR 的預設配置下,本例測試環境中,單行併發更新 TPS 為1834.86/s
4.開啟 OceanBase 資料庫 ELR 配置
接下來我們開啟 OceanBase 資料庫的熱點行功能,首先需要登入到
sys
管理員租戶。
[root@obce00 ~]# obclient -h127.0.0.1 -P2881 -uroot@sys -Doceanbase -A -p -c
然後進行如下兩個引數的設定。其中
enable_early_lock_release
引數的生效範圍,既可以指定具體租戶,也可以指定全部租戶,即
tenant=all
。
ALTER SYSTEM SET _max_elr_dependent_trx_count = 1000; ALTER SYSTEM SET enable_early_lock_release=true tenant= test;
5.開啟 OceanBase 資料庫 ELR 進行測試
開啟熱點行功能後,我們再次執行測試。在執行前我們先檢視錶
sbtest
中
id=1
的記錄,
k
欄位值為 100000,這是因為剛剛執行了一輪預設配置下的 100000 次的更新。
SELECT * FROM sbtest1 WHERE id=1; +----+--------+----+-----+ | id | k | c | pad | +----+--------+----+-----+ | 1 | 100000 | aa | aa | +----+--------+----+-----+ 1 row in set
接下來我們在測試機器上再次執行
ob_elr.py
。仍然採用 50 併發數,總計更新 100000 次。
./ob_elr.py
執行完成,測試指令碼會輸出執行時間和 TPS:
[root@obce00 ~]# ./ob_elr.py Parallel Degree: 50 Total Updates: 100000 Elapse Time: 12.16 s TPS on Hot Row: 8223.68 /s
測試結果
OceanBase 資料庫在開啟 ELR 提前解行鎖能力後,單行更新的 TPS 達到 8223.68/s,相比預設配置下提升 4.5 倍左右。 同時我們可以看到表
sbtest1
的
k
值為 200000,即本次也更新了 100000 次。
SELECT * FROM sbtest1 WHERE id=1; +----+--------+----+-----+ | id | k | c | pad | +----+--------+----+-----+ | 1 | 200000 | aa | aa | +----+--------+----+-----+ 1 row in set
本例中僅介紹了單行併發更新的場景,OceanBase 資料庫的 ELR 能力還支援多語句事務的併發更新,根據語句數量和場景差異,同樣可以獲得顯著的效能提升。
此外 OceanBase 資料庫的 ELR 還可以應用在多地部署高網路延遲的場景中,例如單個事務在預設場景下 30 ms,併發下開啟 ELR 可以獲得進百倍的 TPS 吞吐量提升。
由於 OceanBase 資料庫的日誌協議基於 Multi-Paxos 構建,並且最佳化了 2PC 提交過程,OceanBase 資料庫在開啟 ELR 後,如果發生節點當機重啟、Leader 切換,仍然可以保證事務的一致性。您可以嘗試構造這些實驗進行體驗。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026075/viewspace-2932350/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- OceanBase學習之路14|體驗並行匯入 & 資料壓縮並行
- OceanBase學習之路5|C 應用程式連線 OceanBase 資料庫資料庫
- OceanBase學習之路8|Java 應用程式連線 OceanBase 資料庫Java資料庫
- OceanBase學習之路15|體驗 Operational OLAP
- OceanBase學習之路13|體驗多租戶特性
- OceanBase學習之路11|體驗 DDL 新特性(Oracle 模式)Oracle模式
- OceanBase學習之路12|體驗 DDL 新特性(MySQL 模式)MySql模式
- OceanBase學習之路6|透過 Obclient 連線 OceanBase 租戶client
- OceanBase學習之路38|如何合併資源池?
- OceanBase學習之路47|什麼是資源管理?
- 一點點進步的OceanBase資料庫文件!資料庫
- OceanBase學習之路3 |SpringJDBC 連線示例SpringJDBC
- OceanBase學習之路4|SpringBoot 連線示例Spring Boot
- OceanBase學習之路9|連線方式概述
- oceanbase資料庫簡介資料庫
- OceanBase學習之路37|什麼是分裂資源池?
- OceanBase學習之路39|什麼是修改資源池?
- OceanBase學習之路7|透過 MySQL 客戶端連線 OceanBase 租戶MySql客戶端
- 從IDC資料庫安全報告,看OceanBase安全能力資料庫
- OceanBase學習之路45|如何檢視資源單元配置?
- 實踐練習一:OceanBase Docker 體驗Docker
- 初探oceanbase和newsql資料庫SQL資料庫
- OceanBase學習之路10|C 相關 API 介紹API
- OceanBase學習之路54|如何配置多租戶管理?
- OceanBase學習之路40|如何將資源池分配給租戶?
- OceanBase學習之路42|建立新的資源池的步驟?
- OceanBase學習之路49|最小資源引數配置是什麼?
- OceanBase易鴻偉 OceanBase Cloud 核心能力解讀Cloud
- oceanbase資料庫比賽總結資料庫
- OceanBase學習之路43|如何刪除不再使用的資源單元?
- OceanBase學習之路44|修改資源單元配置有什麼方法??
- OceanBase學習之路52|如何透過系統變數進行設定?變數
- OceanBase學習之路41|如何檢視資源池的分佈情況?
- OceanBase學習之路48|最佳效能引數的配置參考
- 《OceanBase 資料庫系統概念》首次釋出,系統精準定義 OceanBase !資料庫
- OceanBase學習之路53|多租戶管理引數如何設定?
- OceanBase學習之路46|如何透過 SQL 語句或 OCP 建立資源單元?SQL
- 4.0體驗站|OceanBase 4.0 我回來給你點個贊