列存即列式儲存,是一種將資料按列進行儲存和處理的資料管理方式。Lindorm計算引擎支援將半結構化、結構化資料以列存方式進行儲存,相較於行式儲存,列式儲存的查詢回應時間更短,消耗IO更少。本文介紹如何通過計算引擎訪問Lindorm列存資料。
背景資訊
Lindorm列存是面向海量半結構化、結構化資料設計的列格式分布式儲存服務,適用於車連網、物聯網、訂單、日誌等大規模儲存情境,核心能力包括:
計算分析
Lindorm計算引擎可以訪問列存資料,完成海量資料的互動式分析和離線計算。列存提供豐富的索引能力和資料分布特徵,可以有效加速計算過程中的資料定位與排布,通過SQL即可完成海量主鍵資料的增刪改查。
高吞吐
列存引擎吞吐能力支援水平擴充,提供每分鐘TB級資料的讀寫能力。適用於車連網資料快速匯入、模型訓練資料集存取和大規模報表分析生產等高吞吐資料情境。
低成本
通過列格式高壓縮比演算法、高密度低成本介質、冷熱分離、多壓縮編碼和資料冷歸檔等技術,Lindorm列存相比自建系統儲存成本顯著降低,滿足海量資料歸檔留存等低成本儲存需求。
高可用
通過糾刪碼等技術,Lindorm列存保證了分布式資料集的高可用性,同時保證了資料訪問無單點。
開源相容
相容Iceberg開源標準介面,與Spark、Flink等多種計算引擎互聯互連,無縫對接主流資料生態。
冷熱分離
您可以根據業務需求將冷熱資料存放區在不同的介質上,減少訪問冷資料帶來的效能消耗,同時有效降低儲存成本。
前提條件
已閱讀使用須知。
根據不同的作業形態,請確保已經完成了以下操作:
JDBC開發實踐:JDBC開發實踐。
JAR作業開發實踐:JAR作業開發實踐。
Python作業開發實踐:Python作業開發實踐。
如果您需要使用冷熱分離功能,請確保已開通容量型雲端儲存。具體操作,請參見開通容量型雲端儲存。
功能說明
DDL
命名空間
表
分區
DML
表
分區整理
在列存分區寫入資料,經過一段時間後,您可以執行rewrite_data_files或rewrite_manifest命令,整理分區資料,可以將零散的小檔案合并為大檔案,減少資料或中繼資料冗餘,提升資料查詢效能。詳細說明,請參見rewrite_data_files文法和rewrite_manifest文法。
執行rewrite_data_files或rewrite_manifest命令時,會佔用資料庫資源,建議在業務低峰期執行。
樣本一:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');樣本二:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');樣本三:
USE lindorm_columnar; CALL lindorm_columnar.system.rewrite_manifest('mydb.mytable');
冷熱介質
在資料管理時,為最佳化成本與效能,通常會選擇將高頻訪問的資料存放區在高效能介質上,而對於長時間未訪問的歷史資料,則希望將其遷移到低成本的儲存介質中。Lindorm列存支援三級冷熱分層解決方案(從熱到冷分別為L1、L2和L3),可以根據業務需求靈活制定列存資料的冷熱轉換策略。通過資料湖服務自動完成資料在冷熱介質之間的自動轉儲,協助您有效管理儲存成本而不犧牲關鍵業務的響應速度。
Lindorm列存資料自動冷熱轉換功能,需聯絡Lindorm支援人員(DingTalk號:s0s3eg3)開通。
參數配置
您可以通過在建立列存表時定義CHS(Cold or Hot Storage)屬性,以列存表的時間分區為粒度,定義資料冷熱轉儲。配置CHS的參數說明如下:
參數 | 說明 |
CHS | 配置該參數即表示開啟冷熱分離,可以配置為:
|
CHS_L1 | 配置L1層選用的儲存介質,參數格式為: 說明 如果在建立表時沒有配置CHS_L1指定儲存介質,則預設使用容量型雲端儲存。 如果您是雲端儲存使用者,目標儲存類型可選值如下:
如果您是本地碟使用者,目標儲存類型可選值如下:
|
CHS_L2 | 配置L2層選用的儲存介質,參數格式與可選值同CHS_L1。 說明 CHS_L2參數必須配置。 |
CHS_L3 | 配置L3層選用的儲存介質,參數格式與可選值同CHS_L1。 說明 如果您的CHS參數為兩個長整數時,CHS_L3參數必須配置。 |
CHS_EXP | 配置分區資料時間的提取方法,您需要將其定義為形如: 其中:
Lindorm計算引擎會基於CHS_EXP擷取時間分區的最巨量資料時間,結合CHS中定義的時間閾值範圍,將分區資料轉儲到相應的分層介質。 |
樣本
樣本一:
建立表
table0,按年,月,日三個欄位分區,欄位名稱為year,month,day。定義冷熱分層策略為:1個月(2592000秒)以前的資料自動轉儲到容量型雲端儲存。建表語句如下:CREATE TABLE table0 (col0 INT,year STRING,month STRING,day STRING) PARTITIONED BY (year,month) TBLPROPERTIES 'CHS'='2592000', 'CHS_L2'='storagetype=CAPACITY_CLOUD_STORAGE', 'CHS_EXP'='toSec(year,yyyy,month,MM,day,dd)' );樣本二:
修改
table0冷熱分層策略為:1個月(2592000秒)以前的資料自動轉儲到容量型雲端儲存,超過3個月(5184000秒)後自動轉儲到歸檔型儲存,其他規則不變。更新表語句如下:ALTER TABLE table0 SET TBLPROPERTIES ( 'CHS'='2592000,5184000', 'CHS_L2'='storagetype=CAPACITY_CLOUD_STORAGE', 'CHS_L3'='storagetype=CLOUD_ARCHIVE_STORAGE', 'CHS_EXP'='toSec(year,yyyy,month,MM,day,dd)' );樣本三:
建立
table1,按天分區,欄位名為dt,形如:2020/12/1。定義冷熱分層策略為:1個月(2592000秒)以前的資料自動轉儲到容量型雲端儲存,超過3個月(5184000秒)後自動轉儲到歸檔型儲存。建表語句如下:CREATE TABLE table1 (col0 INT,dt STRING) PARTITIONED BY (dt) TBLPROPERTIES ( 'CHS'='2592000,5184000', 'CHS_L2'='storagetype=CAPACITY_CLOUD_STORAGE', 'CHS_L3'='storagetype=CLOUD_ARCHIVE_STORAGE', 'CHS_EXP'='toSec(dt,yyyy/MM/dd)' );
注意事項
在建立表時,您可以指定CHS參數。如果後續需要更改冷熱分層策略,可以通過執行
ALTER TABLE ...SET TBLPROPERTIES...語句來調整配置。錯誤的CHS配置不會影響表建立與更新,但會導致無法自動觸發冷熱介質轉換功能。
資料的冷熱轉儲過程是通過非同步方式觸發的。在整個轉儲過程中及完成後,資料訪問均不受影響,但基於不同儲存介質,訪問效能可能會有所變化。
僅支援基於列存表的時間分區來實現資料冷熱分層策略,暫不支援其他方式。
最佳實務
您可以通過以下方案,加速資料查詢或計算。
主鍵資料查詢
如果表中儲存了海量資料集,查詢時可以指定通過主鍵過濾條件,實現加速效果。查詢時,主鍵的資料範圍設定得越小,加速效果越好。
假設表結構如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderkey'); 樣本一:
USE lindorm_columnar; SELECT * FROM orders WHERE o_orderkey=18394;樣本二:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_orderkey>100000 AND o_orderkey<200000;樣本三:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_orderkey>100000;
添加分區過濾
Lindorm列存引擎中不同分區之間彼此物理隔離,因此,通過添加分區過濾條件,可以加速資料查詢。
假設表結構如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING NOT NULL,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (o_orderdate, bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderdate,o_orderkey');樣本一:
USE lindorm_columnar; SELECT o_orderdate, count(*) FROM orders WHERE o_orderdate='2022-01-01' GROUP BY o_orderdate;樣本二:
USE lindorm_columnar; SELECT o_orderdate, count(*) FROM orders WHERE o_orderdate>='2022-01-01' AND o_orderdate<='2022-01-07' GROUP BY o_orderdate;
查詢加速
對指定表或者表中的指定分區進行資料整理(Rewrite),可以增強資料的有序性或緊湊性,從而提升資料掃描效能。
假設表結構如下:
CREATE TABLE mydb.mytable (
id INT NOT NULL,
city STRING NOT NULL,
name STRING,
score INT)
partitioned by (city, bucket(4, id))
tblproperties('primary-key' = 'id,city');樣本一:對mydb.mytable全表進行資料整理。
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');樣本二:對指定分區進行資料整理。
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');
完成資料整理後,如果想要進一步提升後續查詢的效率,可以執行以下語句設定表的相關參數來加速後續查詢:
ALTER TABLE mydb.mytable SET TBLPROPERTIES ('read.scan-major-rewritten-files-only' = true);參數說明
read.scan-major-rewritten-files-only:指定資料查詢範圍。資料類型為BOOLEAN。取值如下:
true:只查詢已完成資料整理的資料,忽略增量寫入且未完成資料整理的資料。
false:預設值。查詢所有資料。
非主鍵條件查詢
針對分區整理過程,列存表預設按主鍵排序,可以在建表後按需配置排序鍵,從而加速非主鍵條件查詢。
自訂排序鍵加速查詢效果需要在配置排序鍵後進行分區整理,且只掃描已進行分區整理的資料,不再掃描增量資料。
假設表結構如下:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE ,
o_orderdate STRING ,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024,o_orderkey))
TBLPROPERTIES(
'primary-key' = 'o_orderkey',
'read.scan-major-rewritten-files-only' = 'true');執行以下語句配置排序鍵:
ALTER TABLE orders WRITE ORDERED BY o_shippriority,o_totalprice;執行以下語句整理分區:
CALL lindorm_columnar.system.rewrite_data_files(table => 'orders');您可以使用以下SQL語句查詢已完成分區整理的表中的資料。
樣本一:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_shippriority=0;樣本二:
USE lindorm_columnar; SELECT count(*) FROM orders WHERE o_shippriority=0 AND o_totalprice>999.9;