本文介紹PolarDB-X的全密態資料庫在不同加密條件下的效能表現,有助於您評估和選擇加密方案。
測試結論概覽
測試維度 | 核心結論 |
在不同規格和並發壓力下,開啟100%列加密(對錶所有列進行加密)的效能損耗穩定在10%左右。 | |
即使不開啟加密,僅將標準JDBC替換為EncJDBC驅動,用戶端CPU消耗會增加30%~50%。 | |
開啟100%列加密(對錶所有列進行加密)後,為達到最佳效能,用戶端CPU消耗相較於明文情境增幅約55%~150%。 | |
效能損耗與加密列的數量呈正相關。加密列越多,效能損耗越大,用戶端CPU消耗也越高。建議按需對敏感列進行加密。 |
測試設計
測試模型與指標
測試模型:採用業界標準的OLTP(線上交易處理)基準測試載入器Oltpbench,並使用其中的TPC-C模型。
測試資料量:基於TPC-C模型的1000個倉庫(Warehouse)構建,其中核心表
bmsql_order_line資料量為3億行,bmsql_stock為1億行。效能指標:TPS(Transactions Per Second),即資料庫每秒成功提交的事務數。
本文中TPC-C的實現基於TPC-C的基準測試,並不能與發行的TPC-C基準測試結果相比較,本文中的測試並不符合TPC-C基準測試的所有要求。
測試環境
測試用戶端(ECS執行個體)與PolarDB-X執行個體部署於同一地區的同一VPC網路下,以降低網路延遲對測試結果的影響。
配置項 | ECS執行個體(用戶端) | PolarDB-X執行個體(資料庫) |
地區 | 北京 可用性區域I/H | 北京 可用性區域I/H |
執行個體規格 | 2 * ecs.c7.4xlarge(16核32 GB) | 2 * 4核32 GB |
4 * ecs.c7.4xlarge(16核32 GB) | 4 * 8核64 GB | |
鏡像/版本 | Alibaba Cloud Linux 3.2104 LTS 64位 | polardb-2.4.0_5.4.19-20240927_xcluster5.4.19-20241010 |
測試情境
為類比真實業務的資料敏感度差異,測試覆蓋了不同比例的加密列:
20%列加密:優先加密ID、訂單號等關鍵標識符欄位。
50%列加密:在20%的基礎上,增加對價格、日期、數量等商務資訊欄位的加密。
100%列加密:對所有表的全部欄位進行加密。
詳細測試結果
整體效能(100%列加密 vs 明文)
在100%列加密的情境下,全密態資料庫的TPS相較於明文情境,效能損耗基本穩定在10%左右。
測試結果
2 * 4核32 GB
並發數
明文TPS
100%加密TPS
效能損耗
64
80,223
72,248
10%
128
99,019
88,469
11%
256
105,309
94,756
10%
512
104,313
95,962
8%
1024
98,990
95,182
4%
4 * 8核64 GB
並發數
明文TPS
100%加密TPS
效能損耗
64
108,581
96,828
11%
128
184,293
167,380
9%
256
263,538
239,913
9%
512
292,481
252,741
13%
1024
284,561
252,432
11%
EncJDBC驅動自身開銷(明文測試)
為評估EncJDBC驅動自身的效能影響,在不開啟任何加密的情況下,對比了標準JDBC和EncJDBC的用戶端資源消耗。結果顯示,主要的額外開銷在於CPU。
測試條件
用戶端規格(ECS執行個體)為ecs.c7.4xlarge(16核32 GB),並發數為1024。
測試結果
規格 | CPU使用率 | 記憶體使用量率(MB) | ||||
標準JDBC | EncJDBC | 標準JDBC | EncJDBC | |||
2 * 4核32 GB | 21.37% | 28.00% | +31% | 1077 | 1001 | -7.06% |
4 * 8核64 GB | 47.09% | 69.90% | +48% | 1048 | 1024 | -2.29% |
開啟加密後用戶端資源消耗
開啟100%列加密後,用戶端(ECS執行個體)的CPU消耗顯著增加,這是全密態功能效能開銷的主要部分。為達到最佳效能,應用側需要預留充足的CPU資源。
測試條件
並發數為1024。
測試結果
規格 | CPU使用率 (加密前) | CPU使用率 (100%加密) | CPU增幅 |
2 * 4核32 GB | 13.01% | 33.45% | +157% |
4 * 4核32 GB | 20.60% | 32.07% | +56% |
2 * 8核64 GB | 19.93% | 36.77% | +85% |
4 * 8核64 GB | 17.73% | 43.59% | +146% |
結論
綜合不同執行個體規格,開啟全密態加密後,用戶端的CPU資源消耗增幅在56%至157%之間,最大增幅超過1.5倍。
不同加密比例對效能和資源的影響
加密列的數量直接影響效能和用戶端CPU消耗。下表資料展示了隨著加密列比例的增加,效能損耗和用戶端CPU使用率的變化。
測試條件
並發數為1024。
測試結果
2 * 4核32 GB
加密比例
用戶端CPU使用率
TPS
效能損耗
20%
20.01%
96,792
2%
50%
22.23%
96,639
2%
100%
33.45%
95,182
4%
4 * 8核64 GB
加密比例
用戶端CPU使用率
TPS
效能損耗
20%
22.50%
276,640
3%
50%
28.80%
276,640
8%
100%
43.59%
276,640
11%
結論
加密列的增加對效能有顯著影響。在實際應用中,建議您僅對必要的敏感性資料列進行加密,以在安全性與效能之間取得最佳平衡。
附錄:測試步驟
步驟1:準備ECS壓力機
需準備一個ECS執行個體,後續操作步驟中涉及的資料匯入、運行壓測等使用的都是這台ECS機器。
ECS執行個體推薦架構與作業系統:
X86:
CentOS 7.9及以上。
Alibaba Cloud Linux 3。
Ubuntu 18.0及以上。
ARM:CentOS 8.0及以上。
需將測試所用的ECS執行個體部署在Virtual Private Cloud內,並記住該VPC的名稱和ID,後續的所有執行個體都將部署在該VPC內。
需開放ECS執行個體的公網IP,用於後續操作壓測工具。
步驟2:準備壓測所用PolarDB-X執行個體
- 說明
建立PolarDB-X執行個體時,請將執行個體和壓力機ECS執行個體放至同一個Virtual Private Cloud內。
將壓力機ECS執行個體的內網地址添加至PolarDB-X執行個體的白名單中。
在執行個體中建立一個待壓測的資料庫,此處以
tpcc_1000為例。CREATE DATABASE tpcc_1000 MODE = 'auto';
步驟3:準備壓測資料
準備壓測工具
在壓力機ECS上,下載並解壓壓測工具包benchmarksql.tar.gz。
tar xzvf benchmarksql.tar.gz下載全密態驅動包aliyun-encdb-mysql-jdbc-1.0.9-2-20240910.094626-1.jar,並將其放置在
benchmarksql/lib目錄下。
配置壓測參數
進入
benchmarksql/run目錄,編輯props.mysql設定檔。cd benchmarksql/run vi props.mysql根據您的環境修改配置。以下為配置樣本及關鍵參數說明:
db=mysql driver=com.aliyun.encdb.mysql.jdbc.EncDriver conn=jdbc:mysql:encdb://{HOST}:{PORT}/tpcc_1000_enc?/MEK={MEK}&ENC_ALGO={ENC_ALGO}&useSSL=false&useServerPrepStmts=false&useConfigs=maxPerformance&rewriteBatchedStatements= true user={USER} password={PASSWORD} warehouses=1000 loadWorkers=100 terminals=128 //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 //The following five values must add up to 100 //The default percentages of 45, 43, 4, 4 & 4 match the TPC-C spec 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參數說明
conn: 資料庫連接串。請替換{HOST}和{PORT}。{MEK}: 主加密金鑰(Master Encryption Key),一個32位的十六進位字串。{ENC_ALGO}: 對稱式加密演算法,例如SM4_128_GCM。user: 資料庫使用者名稱。password: 資料庫密碼。warehouses: TPC-C倉庫數量,決定資料總量。loadWorkers: 資料匯入時的並發線程數。terminals: 壓測時的並發線程數。runMins: 壓測期間(分鐘)。
匯入資料 在
benchmarksql/run目錄下,執行以下命令開始匯入資料。cd benchmarksql/run/sql.common cp tableCreates.sql.auto tableCreates.sql cd .. nohup ./runDatabaseBuild.sh props.mysql &驗證資料完整性 資料匯入完成後,通過命令列串連到PolarDB-X執行個體,執行以下SQL語句進行校正。若所有查詢均返回空結果集,則表明資料匯入成功且完整。
SELECT a.* FROM (SELECT w_id, w_ytd FROM bmsql_warehouse) a LEFT JOIN (SELECT d_w_id, sum(d_ytd) AS d_ytd_sum FROM bmsql_district GROUP BY d_w_id) b ON a.w_id = b.d_w_id AND a.w_ytd = b.d_ytd_sum WHERE b.d_w_id IS; SELECT a.* FROM (SELECT d_w_id, d_id, D_NEXT_O_ID - 1 AS d_n_o_id FROM bmsql_district) a LEFT JOIN (SELECT o_w_id, o_d_id, max(o_id) AS o_id_max FROM bmsql_oorder GROUP BY o_w_id, o_d_id) b ON a.d_w_id = b.o_w_id AND a.d_id = b.o_d_id AND a.d_n_o_id = b.o_id_max WHERE b.o_w_id IS NULL; SELECT a.* FROM (SELECT d_w_id, d_id, D_NEXT_O_ID - 1 AS d_n_o_id FROM bmsql_district) a LEFT JOIN (SELECT no_w_id, no_d_id, max(no_o_id) AS no_id_max FROM bmsql_new_order GROUP BY no_w_id, no_d_id) b ON a.d_w_id = b.no_w_id AND a.d_id = b.no_d_id AND a.d_n_o_id = b.no_id_max WHERE b.no_id_max IS NULL; SELECT * FROM (SELECT (count(no_o_id)-(max(no_o_id)-min(no_o_id)+1)) AS diff FROM bmsql_new_order GROUP BY no_w_id, no_d_id) a WHERE diff != 0; SELECT a.* FROM (SELECT o_w_id, o_d_id, sum(o_ol_cnt) AS o_ol_cnt_cnt FROM bmsql_oorder GROUP BY o_w_id, o_d_id) a LEFT JOIN (SELECT ol_w_id, ol_d_id, count(ol_o_id) AS ol_o_id_cnt FROM bmsql_order_line GROUP BY ol_w_id, ol_d_id) b ON a.o_w_id = b.ol_w_id AND a.o_d_id = b.ol_d_id AND a.o_ol_cnt_cnt = b.ol_o_id_cnt WHERE b.ol_w_id IS NULL; SELECT a.* FROM (SELECT d_w_id, sum(d_ytd) AS d_ytd_sum FROM bmsql_district GROUP BY d_w_id) a LEFT JOIN (SELECT w_id, w_ytd FROM bmsql_warehouse) b ON a.d_w_id = b.w_id AND a.d_ytd_sum = b.w_ytd WHERE b.w_id IS NULL;
步驟四:執行壓測
在benchmarksql/run目錄下,執行以下命令運行TPC-C測試。終端會即時顯示tpmC(每分鐘事務數),測試結束後會輸出最終的平均值。
cd benchmarksql/run
./runBenchmark.sh props.mysql