Hologres是相容PostgreSQL協議的一站式即時數倉引擎,支援即時離線一體化情境下的海量資料寫入、更新與查詢。本文針對Hologres的批量寫入情境,結合Spark批量寫入Hologres的效能測試與結果,為您介紹不同的寫入情境下應如何選擇合適的寫入模式。
針對資料的即時寫入與即時更新,效能測試方案與結果請參見資料寫入、更新、點查情境壓測最佳實務。
批量寫入模式對比
針對資料批量寫入情境,Hologres支援不同的寫入模式,包括:傳統的COPY模式、基於COPY協議開發的FIXED COPY流式匯入模式,以及將大量匯入轉化成流式的INSERT INTO VALUES模式。
三種寫入模式詳細對比如下:
|
對比項 |
COPY |
FIXED COPY |
INSERT INTO VALUES |
|
|
簡介 |
COPY大量匯入無主鍵表 |
COPY大量匯入有主鍵表 |
基於COPY協議開發的流式匯入模式 |
基礎流式匯入模式 |
|
典型情境 |
|
|
|
|
|
鎖粒度 |
行鎖 |
表鎖 |
行鎖 |
行鎖 |
|
資料可見度 |
COPY結束後可見 |
COPY結束後可見 |
即時可見 |
即時可見 |
|
效能 |
高 |
高 |
中 |
中 |
|
Hologres資源消耗 |
低 |
低 |
高 |
高 |
|
用戶端資源消耗 |
低 |
高 |
低 |
中 |
|
主鍵衝突策略支援 |
不涉及 |
|
|
|
批量寫入模式選擇
針對資料批量寫入情境,三種模式的特點如下:
-
COPY模式:傳統的COPY模式,擁有最優的寫入效能、最低的Hologres資源消耗。
-
FIXED COPY模式:基於COPY協議開發的流式匯入模式。僅產生行鎖、資料即時可見。
-
INSERT INTO VALUES模式:將大量匯入轉化為傳統的流式寫入模式,在批量寫入情境下已不具備明顯優勢。
說明INSERT模式僅在批量寫入情境下不具備明顯優勢,但僅INSERT模式具備資料回撤(即刪除)能力,在Binlog資料寫入等情境下仍需使用該模式。
若您對資料即時可見度、鎖粒度(產生表鎖時,該表無法支援多個任務同時寫入),以及資料來源端負載沒有特殊要求,可以優先選擇COPY模式進行批量寫入。
-
以Spark批量寫入為例:推薦將Hologres執行個體升級至V2.2.25或以上版本,並將Connector的寫入參數
write.mode值設為auto(預設值),系統將會自動選擇最優的寫入模式。 -
以Flink批量寫入為例:需要先根據下述決策樹確定選用COPY模式或FIXED COPY模式,然後分別配置如下參數。
-
jdbccopywritemode:設為TRUE,即不使用INSERT模式。
-
bulkload:TRUE(COPY模式)或FALSE(FIXED COPY模式),請根據需求進行配置。
-
針對具體的批量寫入情境,可根據如下決策樹選擇合適的寫入模式。
批量寫入效能測試
測試過程使用Hologres研發的開源組件Hologres-Spark-Connector。
準備工作
基礎環境準備
您需準備以下環境:
Hologres執行個體和EMR-Spark叢集需要位於同一地區,且使用相同的VPC。
-
開通V2.2.25或以上版本的Hologres執行個體,並建立資料庫。
-
下載Spark-Connector包。
您可通過Maven中央倉庫下載Spark讀寫Hologres時需要引用的連接器JAR包
hologres-connector-spark-3.x。
本文中使用的環境資訊如下:
|
服務 |
版本 |
規格 |
|
Hologres |
V3.0.30 |
64 Core,256 GB(1CU=1 core 4GB) |
|
EMR-Spark |
EMR-5.18.1,Spark-3.5.3 |
8 Core,32 GB * 8(1個master節點,7個core節點) 重要
需開通OSS-HDFS服務。 |
|
Spark-Connector |
1.5.2 |
不涉及 |
測試資料準備
-
準備未經處理資料。
-
登入EMR-Spark叢集的master節點,詳情請參見串連ECS執行個體的方式。
-
單擊TPC-H_Tools_v3.0.0.zip下載TPCH工具,將其複製到叢集master節點的ECS機器中進行解壓,然後進入
TPC-H_Tools_v3.0.0/TPC-H_Tools_v3.0.0/dbgen目錄。 -
執行如下代碼,在
dbgen目錄下產生1 TB測試集檔案customer.tbl,原tbl格式檔案大小為23 GB。./dbgen -s 1000 -T cTPC-H 1 TB資料集中customer表的詳細資料如下:
表資訊
說明
欄位資料量
8
欄位類型
INT、BIGINT、TEXT、DECIMAL
資料行數
150,000,000
表Shard數
40
-
-
測試資料匯入Spark。
執行如下命令,將customer.tbl檔案上傳到Spark叢集。
hadoop fs -put customer.tbl <spark_resource>其中spark_resource為建立EMR-Spark叢集時,配置的叢集儲存根路徑。
-
在Hologres中建立不同儲存格式的表。SQL命令如下:
行列共存
CREATE TABLE test_table_mixed ( C_CUSTKEY BIGINT PRIMARY KEY, C_NAME TEXT, C_ADDRESS TEXT, C_NATIONKEY INT, C_PHONE TEXT, C_ACCTBAL DECIMAL(15, 2), C_MKTSEGMENT TEXT, C_COMMENT TEXT ) WITH ( orientation = 'column,row' );列存(有主鍵)
CREATE TABLE test_table_column ( C_CUSTKEY BIGINT PRIMARY KEY, C_NAME TEXT, C_ADDRESS TEXT, C_NATIONKEY INT, C_PHONE TEXT, C_ACCTBAL DECIMAL(15, 2), C_MKTSEGMENT TEXT, C_COMMENT TEXT ) WITH ( orientation = 'column' );列存(無主鍵)
CREATE TABLE test_table_column_no_pk ( C_CUSTKEY BIGINT, C_NAME TEXT, C_ADDRESS TEXT, C_NATIONKEY INT, C_PHONE TEXT, C_ACCTBAL DECIMAL(15, 2), C_MKTSEGMENT TEXT, C_COMMENT TEXT ) WITH ( orientation = 'column' );行存(有主鍵)
CREATE TABLE test_table_row ( C_CUSTKEY BIGINT PRIMARY KEY, C_NAME TEXT, C_ADDRESS TEXT, C_NATIONKEY INT, C_PHONE TEXT, C_ACCTBAL DECIMAL(15, 2), C_MKTSEGMENT TEXT, C_COMMENT TEXT ) WITH ( orientation = 'row' );行存(無主鍵)
CREATE TABLE test_table_row_no_pk ( C_CUSTKEY BIGINT, C_NAME TEXT, C_ADDRESS TEXT, C_NATIONKEY INT, C_PHONE TEXT, C_ACCTBAL DECIMAL(15, 2), C_MKTSEGMENT TEXT, C_COMMENT TEXT ) WITH ( orientation = 'row' );
效能測試
測試組態
本文主要測試不同模式下的匯入效能。
-
登入EMR-Spark叢集的master節點(登入方式請參見串連ECS執行個體的方式),上傳已下載的Spark-Connector包,然後執行如下命令進入spark-sql互動介面。
說明通過調整
spark.sql.files.maxPartitionBytes參數值, 可以控制Spark讀取HDFS檔案的並發。此處並發控製為40。# 進入spark-sql互動介面 spark-sql --jars <path>/hologres-connector-spark-3.x-1.5.2-jar-with-dependencies.jar \ --conf spark.executor.instances=40 \ --conf spark.executor.cores=1 \ --conf spark.executor.memory=4g \ --conf spark.sql.files.maxPartitionBytes=644245094其中path為hologres-connector-spark-3.x-1.5.2-jar-with-dependencies.jar所在的根路徑。
-
在spark-sql互動介面執行如下SQL,通過建立暫存資料表的方式寫入資料。
由於測試過程中,需要多次調整參數以測試不同模式的寫入效能,此處選擇建立暫存資料表的方式。
說明實際使用中,您可直接使用Catalog載入Hologres表,更加方便。
-- 建立csv格式的暫存資料表 CREATE TEMPORARY VIEW csvtable ( c_custkey BIGINT, c_name STRING, c_address STRING, c_nationkey INT, c_phone STRING, c_acctbal DECIMAL(15, 2), c_mktsegment STRING, c_comment STRING) USING csv OPTIONS ( path "<spark_resources>/customer.tbl", sep "|" ); CREATE TEMPORARY VIEW hologresTable ( c_custkey BIGINT, c_name STRING, c_address STRING, c_nationkey INT, c_phone STRING, c_acctbal DECIMAL(15, 2), c_mktsegment STRING, c_comment STRING) USING hologres OPTIONS ( jdbcurl "jdbc:postgresql://<hologres_vpc_endpoint>/<database_name>", username "<accesskey_id>", password "<accesskey_secret>", table "<table_name>", direct_connect "false", write.mode "auto", write.insert.thread_size "3", write.insert.batch_size "2048" ); INSERT INTO hologresTable SELECT * FROM csvTable;參數說明如下:
參數名
描述
spark_resources
建立EMR-Spark叢集時,配置的叢集儲存根路徑。
您可登入EMR on ECS控制台,單擊目的地組群ID,在基礎資訊頁面的叢集資訊地區擷取叢集儲存根路徑。
hologres_vpc_endpoint
Hologres執行個體對應的VPC網路類型的網域名稱。
您可登入Hologres管理主控台,單擊目標執行個體ID,在執行個體詳情頁的網路資訊地區,擷取指定VPC的網域名稱。例如:杭州地區的VPC Endpoint格式為
<Instance ID>-cn-hangzhou-vpc-st.hologres.aliyuncs.com:80。database_name
Hologres執行個體的資料庫名稱。
accesskey_id
具有Hologres相應Database讀取許可權的AccessKey ID。
accesskey_secret
具有Hologres相應Database讀取許可權的AccessKey Secret。
table_name
待寫入的Hologres目標表名稱。
write.mode
寫入模式,取值如下:
-
auto:預設值,Connector自行選擇最佳的模式。 -
insert:使用INSERT INTO VALUES方式寫入。 -
stream:使用FIXED COPY流式寫入。 -
bulk_load:使用COPY模式大量匯入無主鍵表。 -
bulk_load_on_conflict:使用COPY模式大量匯入有主鍵表。
write.insert.thread_size
寫入並發,僅使用INSERT寫入時生效。
write.insert.batch_size
寫入攢批,僅使用INSERT寫入時生效。
write.on_conflict_action
INSERT_OR_REPLACE(預設):主鍵衝突更新。
INSERT_OR_IGNORE: 主鍵衝突忽略。
更多參數資訊請參見參數說明。
-
測試情境
|
測試情境 |
可選情境 |
|
表格儲存體格式 |
|
|
資料更新方式 |
|
|
寫入方式 |
|
測試結果
測試結果包括以下欄位:
|
欄位 |
描述 |
|
作業總耗時 |
Spark作業總的已耗用時間。 即您在EMR-Spark叢集節點的spark-sql互動介面,執行INSERT資料寫入操作的耗時。擷取方法如下圖: |
|
資料寫入平均耗時 |
剔除Spark叢集調度以及讀取資料或者資料重分布的時間,僅統計寫入作業的平均耗時。 您可在Hologres管理主控台的HoloWeb頁面,執行如下SQL命令,即可擷取Shard並發數(count)和資料寫入平均耗時(avg_duration_ms,單位為:毫秒)。
參數說明如下:
|
|
Hologres負載 |
Hologres執行個體的CPU使用率。 您可在Hologres管理主控台的執行個體監控資訊頁面擷取CPU使用率。 |
|
Spark負載 |
EMR節點負載。 您可在EMR on ECS控制台單擊目的地組群ID,進入監控診斷 > 指標監控頁簽,選擇如下參數:
然後查詢CPU utilization指標,即為Spark負載。 |
詳細測試結果如下:
|
儲存格式 |
主鍵 |
寫入模式 |
作業總耗時 |
資料寫入平均耗時 |
Hologres負載 |
Spark負載 |
|
列存 |
無主鍵 |
insert |
241.61s |
232.70s |
92% |
15% |
|
stream |
228.11s |
222.34s |
100% |
36% |
||
|
bulk_load |
88.72s |
57.16s |
97% |
47% |
||
|
有主鍵 ignore |
insert |
190.96s |
172.60s |
90% |
14% |
|
|
stream |
149.60s |
142.16s |
100% |
14% |
||
|
bulk_load_on_conflict |
115.96s |
42.92s |
60% |
75% |
||
|
有主鍵 replace |
insert |
600.40s |
574.31s |
91% |
5% |
|
|
stream |
550.29s |
540.32s |
100% |
5% |
||
|
bulk_load_on_conflict |
188.05s |
109.77s |
93% |
78% |
||
|
行存 |
無主鍵 |
insert |
132.38s |
123.79s |
94% |
22% |
|
stream |
114.41s |
103.81s |
100% |
17% |
||
|
bulk_load |
68.20s |
41.22s |
98% |
32% |
||
|
有主鍵 ignore |
insert |
190.48s |
170.49s |
89% |
15% |
|
|
stream |
185.46s |
172.48s |
85% |
14% |
||
|
bulk_load_on_conflict |
117.81s |
47.69s |
58% |
75% |
||
|
有主鍵 replace |
insert |
177.97s |
170.78s |
93% |
15% |
|
|
stream |
142.44s |
130.16s |
100% |
20% |
||
|
bulk_load_on_conflict |
137.69s |
65.18s |
92% |
78% |
||
|
行列共存 |
有主鍵 ignore |
insert |
172.19s |
158.74s |
86% |
16% |
|
stream |
150.63s |
149.76s |
100% |
12% |
||
|
bulk_load_on_conflict |
128.83s |
42.09s |
59% |
79% |
||
|
有主鍵 replace |
insert |
690.37s |
662.00s |
92% |
5% |
|
|
stream |
625.84s |
623.08s |
100% |
4% |
||
|
bulk_load_on_conflict |
202.07s |
121.58s |
93% |
80% |
寫入模式的對應關係如下:
-
insert:INSERT INTO VALUES
-
stream:FIXED COPY
-
bulk_load:COPY匯入無主鍵表
-
bulk_load_on_conflict :COPY匯入有主鍵表
