AnalyticDB for MySQL支援通過外表匯入匯出資料。本文介紹如何通過外表將AnalyticDB for MySQL數倉版資料匯出至HDFS。
前提條件
AnalyticDB for MySQL叢集需為V3.1.4.4或以上版本。
說明查看湖倉版叢集的核心版本,請執行
SELECT adb_version();
。如需升級核心版本,請聯絡支援人員。已建立HDFS叢集,並在HDFS叢集中建立了一個新的檔案夾(本樣本中檔案夾名為hdfs_output_test_csv_data),用於儲存匯入的AnalyticDB for MySQL資料。
說明使用
INSERT OVERWRITE
進行匯入時,系統會覆蓋目標檔案夾下的原始檔案。為避免原始檔案被覆蓋,建議在匯出時建立一個新的目標檔案夾。已在HDFS叢集中為AnalyticDB for MySQL叢集配置如下服務訪問連接埠:
namenode
:用於讀寫檔案系統元資訊。您可以在fs.defaultFS參數中配置連接埠號碼,預設連接埠號碼為8020。詳細配置方式,請參見core-default.xml。
datanode
:用於讀寫資料。您可以在dfs.datanode.address參數中配置連接埠號碼,預設連接埠號碼為50010。詳細配置方式,請參見hdfs-default.xml。
如果您的AnalyticDB for MySQL叢集是彈性模式,您需要在集群資訊頁面的網路資訊地區,開啟啟用ENI網絡的開關。
注意事項
AnalyticDB for MySQL叢集僅支援匯出檔案格式為CSV和Parquet的資料至HDFS。不支援匯出檔案格式為ORC的資料。
AnalyticDB for MySQL叢集不支援自訂行級寫入的
INSERT
文法,如INSERT INTO VALUES
和REPLACE INTO VALUES
。不支援通過分區外表匯出單個檔案至HDFS。
通過分區外表匯出資料時,資料檔案內不包含分區列的資料,分區列的資料資訊以HDFS目錄的形式展現。
例如,已在分區外表中定義了3個普通列和2個分區列。其中一級分區列的列名為
p1
,分區列的值為1
。二級分區名稱為p2
,分區數值為a
,現需要通過分區外表將資料匯出到HDFS的adb_data/路徑下。那麼當
p1=1
且p2=a
的外表分區匯出資料時,資料檔案相對路徑目錄為adb_data/p1=1/p2=a/,且外表CSV或Parquet資料檔案內不包含p1
和p2
這兩列,只包含3列普通列的值。
操作步驟
串連目標AnalyticDB for MySQL叢集。詳細操作步驟,請參見串連叢集。
建立來源資料庫。詳細操作步驟,請參見建立資料庫。
本樣本中,AnalyticDB for MySQL叢集的源庫名為
adb_demo
。建立源表並插入來源資料。
您可以使用以下語句在源庫
adb_demo
中建立一張源表adb_hdfs_import_source
,建表語句如下:CREATE TABLE IF NOT EXISTS adb_hdfs_import_source ( uid string, other string ) DISTRIBUTED BY HASH(uid);
往源表
adb_hdfs_import_source
中插入一行測試資料,語句如下:INSERT INTO adb_hdfs_import_source VALUES ("1", "a"), ("2", "b"), ("3", "c");
建立外部映射表。
您可以使用以下文法在源庫
adb_demo
中建立一張外部映射表,用於將AnalyticDB for MySQL資料匯出至HDFS:建立普通外部映射表(本文樣本中目標表名為
hdfs_import_external
),文法如下。CREATE TABLE IF NOT EXISTS hdfs_import_external ( uid string, other string ) ENGINE='HDFS' TABLE_PROPERTIES='{ "format":"csv", "delimiter":",", "hdfs_url":"hdfs://172.17.***.***:9000/adb/hdfs_output_test_csv_data" }';
建立帶分區的外部映射表時(本文樣本中目標表名為
hdfs_import_external_par
),需要同時在建立語句中定義普通列(如uid
和other
)和分區列(如p1
、p2
和p3
),文法如下。CREATE TABLE IF NOT EXISTS hdfs_import_external_par ( uid string, other string, p1 date, p2 int, p3 varchar ) ENGINE='HDFS' TABLE_PROPERTIES='{ "format":"csv", "delimiter":",", "hdfs_url":"hdfs://172.17.***.***:9000/adb/hdfs_output_test_csv_data" "partition_column":"p1, p2, p3" }';
說明AnalyticDB for MySQL叢集僅支援匯出檔案格式為CSV和Parquet的資料至HDFS。不支援匯出檔案格式為ORC的資料。
建立外表的詳細文法說明,請參見建立HDFS外表和建立帶分區的HDFS外表。
將源AnalyticDB for MySQL叢集中的資料匯出至目標HDFS中。
如需通過普通外表匯出資料,具體文法,請參見附錄1:資料匯出文法(普通外表)。
如需通過分區外表匯出資料,具體文法,請參見附錄2:資料匯出文法(分區外表)。
後續步驟
匯出完成後,您可以通過Hadoop用戶端到目標檔案夾hdfs_output_test_csv_data
中查看匯出的資料檔案。您也可以登入AnalyticDB for MySQL叢集,在外表中(分區外表與普通外表查詢語句一致,本樣本以普通外表hdfs_import_external
為例)執行如下語句查詢已匯出的資料:
SELECT * FROM hdfs_import_external LIMIT 100;
附錄1:資料匯出文法(普通外表)
若建立外表時未指定分區列,您可以根據業務需要選擇如下幾種方式匯出資料:
方式一:如果您的資料已存在於目標表中,可以通過
INSERT INTO
語句將資料匯入外表。使用該語句會將源表的資料寫入外表對應的HDFS位置,每次寫入會產生新的HDFS資料檔案。說明外表裡的列和需要匯出的列,必須保持列個數的完整。
INSERT INTO
為增量寫入,會額外產生新的檔案,不會覆蓋舊的歷史檔案。文法如下。
INSERT INTO <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
INSERT INTO hdfs_import_external SELECT col1, col2, col3 FROM adb_hdfs_import_source;
說明col1, col2, col3
表示外表中的所有列。方式二:HDFS外表不支援定義主鍵,因此
REPLACE INTO
的寫入表現與INSERT INTO
一致,都會將資料複製到外表。如果目標表內已有資料,執行REPLACE INTO
語句匯入時,已有資料保持不變,新資料會被追加到目標資料檔案中。說明寫入的外表必須保持列個數的完整,不允許使用者指定唯寫入一部分的列。
REPLACE INTO
為增量寫入,會額外產生新的檔案,不會覆蓋舊的歷史檔案。
文法如下。
REPLACE INTO <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
REPLACE INTO hdfs_import_external SELECT col1, col2, col3 FROM adb_hdfs_import_source;
方式三:您可以使用
INSERT OVERWRITE
文法向外表中批量插入資料。如果目標外表中已存在資料,每次寫入會先刪除外表路徑下的全部資料檔案,再產生新的HDFS資料檔案。重要寫入的外表必須保持列個數的完整,不允許指定唯寫入部分的列。
INSERT OVERWRITE
為覆蓋寫入,會覆蓋匯出目錄內已有的歷史資料,謹慎使用。
文法如下。
INSERT OVERWRITE <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
INSERT OVERWRITE hdfs_import_external SELECT col1, col2, col3 FROM adb_hdfs_import_source;
方式四:非同步執行
INSERT OVERWRITE
匯出資料,文法如下。SUBMIT job INSERT OVERWRITE <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
SUBMIT JOB INSERT OVERWRITE hdfs_import_external SELECT col1, col2, col3 FROM adb_hdfs_import_source;
返回結果如下。
+---------------------------------------+ | job_id | +---------------------------------------+ | 2020112122202917203100908203303****** | +---------------------------------------+
您還可以根據上述
job_id
查看非同步任務的狀態。更多詳情,請參見非同步提交匯入任務。
附錄2:資料匯出文法(分區外表)
分區外表在文法中加入PARTITION
欄位匯出資料,您還可以通過指定PARTITION
欄位中的分區列和分區值來確定是否使用靜態或者動態分區。
方式一:您可以使用
INSERT INTO PARTITION
文法往帶分區的外表中批量插入資料。說明寫入時,資料將在對應分區追加寫入,每次寫入會產生新的HDFS資料檔案,歷史資料不會被覆蓋;寫入的外表必須保持列個數的完整,不允許使用者指定唯寫入一部分的列。
全靜態分區
文法如下。
INSERT INTO <target_table> PARTITION(par1=val1,par2=val2,...) SELECT <col_name> FROM <source_table>;
樣本如下。
INSERT INTO hdfs_import_external_par PARTITION(p1='2021-05-06',p2=1,p3='test') SELECT col1, col2, col3, FROM adb_hdfs_import_source;
半靜態半動態分區
說明靜態列必須位於動態列的前面,不允許穿插使用。
文法如下。
INSERT INTO <target_table> PARTITION(par1=val1,par2,...) SELECT <col_name> FROM <source_table>;
樣本如下。
INSERT INTO hdfs_import_external_par PARTITION(p1='2021-05-27',p2,p3) SELECT col1, col2, col3, FROM adb_hdfs_import_source;
全動態分區(即不需要
PARTITION
欄位)文法如下。
INSERT INTO <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
INSERT INTO hdfs_import_external_par SELECT col1, col2, col3, FROM adb_hdfs_import_source;
方式二:HDFS外表不支援定義主鍵,因此
REPLACE INTO PARTITION
的寫入表現與INSERT INTO PARTITION
一致。說明寫入的外表必須保持列個數的完整,不允許使用者指定唯寫入一部分的列;
REPLACE INTO PARTITION
為增量寫入,會額外產生新的檔案,不會覆蓋舊的歷史檔案。文法如下:
全靜態分區
文法如下。
REPLACE INTO <target_table> PARTITION(par1=val1,par2=val2,...) SELECT <col_name> FROM <source_table>;
樣本如下。
REPLACE INTO hdfs_import_external_par PARTITION(p1='2021-05-06',p2=1,p3='test') SELECT col1, col2, col3, FROM adb_hdfs_import_source;
半靜態半動態分區
說明靜態列必須位於動態列的前面,不允許穿插使用。
文法如下。
REPLACE INTO <target_table> PARTITION(par1=val1,par2,...) SELECT <col_name> FROM <source_table>;
樣本如下。
REPLACE INTO hdfs_import_external_par PARTITION(p1='2021-05-06',p2,p3) SELECT col1, col2, col3, FROM adb_hdfs_import_source;
全動態分區(即不需要
PARTITION
欄位)文法如下。
REPLACE INTO <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
REPLACE INTO hdfs_import_external_par SELECT col1, col2, col3, FROM adb_hdfs_import_source;
方式三:
INSERT OVERWRITE PARTITION
與INSERT INTO PARTITION
使用方法相同,但使用INSERT OVERWRITE PARTITION
時,會覆蓋掉本次執行中涉及到的目標資料分割中之前已有的資料檔案,對於沒有新資料寫入的分區,則不會清除其中的資料檔案。文法如下。
INSERT OVERWRITE <target_table> PARTITION(par1=val1,par2=val2,...)[IF NOT EXISTS] SELECT <col_name> FROM <source_table>;
重要寫入的外表必須保持列個數的完整,不允許使用者指定唯寫入一部分的列;
INSERT OVERWRITE PARTITION
為覆蓋寫入,會覆蓋匯出目錄內已有的歷史資料,謹慎使用。IF NOT EXISTS
:表示如果外表分區已存在,則不會匯出到這個分區。
樣本如下。
INSERT OVERWRITE hdfs_import_external_par PARTITION(p1='2021-05-06',p2=1,p3='test') IF NOT EXISTS SELECT col1, col2, col3 FROM adb_hdfs_import_source;
方式四:非同步執行
INSERT OVERWRITE
匯出資料,文法如下。SUBMIT JOB INSERT OVERWRITE <target_table> SELECT <col_name> FROM <source_table>;
樣本如下。
SUBMIT JOB INSERT OVERWRITE hdfs_import_external_par PARTITION(p1='2021-05-06',p2=1,p3='test') IF NOT EXISTS SELECT col1, col2, col3 FROM adb_hdfs_import_source;
返回結果如下。
+---------------------------------------+ | job_id | +---------------------------------------+ | 2020112122202917203100908203303****** | +---------------------------------------+
您還可以根據上述
job_id
查看非同步任務的狀態。更多詳情,請參見非同步提交匯入任務。