使用OSS外表高速導入OSS數據
云原生數據倉庫AnalyticDB PostgreSQL版支持通過OSS外部表(gpossext功能),將數據并行從阿里云對象存儲OSS導入到AnalyticDB PostgreSQL。
功能介紹
目前gpossext支持讀寫TEXT、CSV格式的文件以及GZIP壓縮格式的TEXT、CSV文件。
gpossext架構圖如下。
TEXT和CSV格式說明
下列幾個參數可以在外表DDL參數中指定,用于規定讀寫OSS的文件格式:
TEXT和CSV行分割符號是
\n
,也就是換行符。DELIMITER用于定義列的分割符:
當用戶數據中包括DELIMITER時,則需要和QUOTE參數一同使用。
推薦的列分割符有
,
、\t
、|
或一些不常見的字符。
QUOTE用于包裹有特殊字符的用戶數據(以列為單位):
包含有特殊字符的字符串會被QUOTE包裹,用于區分用戶數據和控制字符。
如果不必要,例如整數,基于優化效率的考慮,不必使用QUOTE包裹數據。
QUOTE不能和DELIMITER相同,默認QUOTE是雙引號。
當用戶數據中包含了QUOTE字符,則需要使用轉義字符ESCAPE加以區分。
ESCAPE用于特殊字符轉義:
轉義字符出現在需要轉義的特殊字符前,表示它不是一個特殊字符。
ESCAPE默認和QUOTE相同,為雙引號
""
。也支持設置成
\
(MySQL默認的轉義字符)或別的字符。
控制字符和格式 | TEXT | CSV |
DELIMITER(列分割符) | \t(Tab) | , (Comma) |
QUOTE(摘引) | " (Double-Quote) | "(Double-Quote) |
ESCAPE(轉義) | (不適用) | 與QUOTE相同 |
NULL(空值) | \N(Backslash-N) | (無引號的空字符串) |
所有的控制字符都必須是單字節字符。
注意事項
創建和使用外部表的語法,除了location相關參數,其余參數和Greenplum的使用方式相同。
數據導入導出的性能和AnalyticDB PostgreSQL的資源(CPU、I/O、內存、網絡等)有關,也和OSS相關。為了獲取最優的導入導出性能,建議在創建表時,使用列式存儲加壓縮功能。例如,指定子句
"WITH (APPENDONLY=true, ORIENTATION=column, COMPRESSTYPE=zlib, COMPRESSLEVEL=5, BLOCKSIZE=1048576)"
,詳細信息,請參見 Greenplum Database創建表官方文檔。為了保證數據導入導出的性能,請保證OSS與AnalyticDB PostgreSQL在同一地域下。
操作步驟
創建OSS外部表插件。
使用OSS外部表時,需要在AnalyticDB PostgreSQL中先創建OSS外部表插件(每個庫中均需要單獨創建)。創建命令如下:
CREATE EXTENSION IF NOT EXISTS oss_ext;
將待導入AnalyticDB PostgreSQL的數據均勻分散存儲在多個OSS文件中。操作方式,請參見大文件切分。
說明AnalyticDB PostgreSQL的每個數據分區(Segment節點)將按輪詢方式并行對OSS上的數據文件進行讀取,文件的數目建議為數據節點數(Segment個數)的整數倍,從而提升讀取效率。
在AnalyticDB PostgreSQL中,創建READABLE外部表。
創建OSS外部表語法如下。
CREATE [READABLE] EXTERNAL TABLE tablename ( columnname datatype [, ...] | LIKE othertable ) LOCATION ('ossprotocol') FORMAT 'TEXT' [( [HEADER] [DELIMITER [AS] 'delimiter' | 'OFF'] [NULL [AS] 'null string'] [ESCAPE [AS] 'escape' | 'OFF'] [NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF'] [FILL MISSING FIELDS] )] | 'CSV' [( [HEADER] [QUOTE [AS] 'quote'] [DELIMITER [AS] 'delimiter'] [NULL [AS] 'null string'] [FORCE NOT NULL column [, ...]] [ESCAPE [AS] 'escape'] [NEWLINE [ AS ] 'LF' | 'CR' | 'CRLF'] [FILL MISSING FIELDS] )] [ ENCODING 'encoding' ] [ [LOG ERRORS [INTO error_table]] SEGMENT REJECT LIMIT count [ROWS | PERCENT] ] ossprotocol: oss://oss_endpoint [prefix=prefix_name|dir=[folder/[folder/]...]/file_name|filepath=[folder/[folder/]...]/file_name] id=userossid key=userosskey bucket=ossbucket compressiontype=[none|gzip] async=[true|false]
參數說明如下。
參數
說明
FORMAT
支持文件格式,例如TEXT、CSV。
ENCODING
文件中數據的編碼格式,例如UTF8。
LOG ERRORS
指定該子句可以忽略掉導入中出錯的數據,將這些數據寫入error_table,并可以使用count參數指定報錯的閾值。
說明通過
LOG ERRORS
將錯誤行信息記錄到內部關聯文件。LOG ERRORS SEGMENT REJECT LIMIT 5;
通過函數
gp_read_error_log('external_table_name')
可以讀取錯誤行信息。SELECT * FROM gp_read_error_log('external_table_name');
內部文件隨外表刪除而刪除,也可以通過函數
gp_truncate_error_log('external_table_name')
刪除。SELECT gp_truncate_error_log('external_table_name');
oss://oss_endpoint
協議和Endpoint,格式為
協議名://oss_endpoint
,其中協議名為oss,oss_endpoint為OSS對應區域的域名。示例如下:oss://oss-cn-hangzhou.aliyuncs.com
重要如果是從阿里云的主機訪問數據庫,應該使用內網域名(即帶有
internal
的域名),避免產生公網流量。id
阿里云賬號的AccessKey ID。獲取AccessKey操作,請參見創建AccessKey。
key
阿里云賬號的AccessKey Secret。獲取AccessKey操作,請參見創建AccessKey。
bucket
指定數據文件所在的Bucket,需要在OSS上預先創建。
prefix
指定數據文件對應路徑名的前綴,不支持正則表達式,僅是匹配前綴。
說明與dir、filepath互斥,三者只能設置其中一個。
READABLE外部表會在導入數據時將含有這一前綴的所有OSS文件都會被導入。
如果指定prefix=test/filename,以下文件都會被導入:
test/filename
test/filenamexxx
test/filename/aa
test/filenameyyy/aa
test/filenameyyy/bb/aa
如果指定prefix=test/filename/,只有以下文件會被導入(上面列的其他文件不會被導入):
test/filename/aa
dir
OSS中的虛擬文件夾路徑。
說明與prefix、filepath互斥,三者只能設置其中一個。
文件夾路徑需要以
/
結尾,如test/mydir/
。在導入數據時,使用此參數創建外部表,會導入指定虛擬目錄下的所有文件,但不包括它子目錄和子目錄下的文件。與filepath不同,dir下的文件沒有命名要求。
filepath
OSS中包含路徑的文件名稱。
說明與prefix、dir互斥,三者只能設置其中一個。
這個參數只能在創建READABLE外部表時指定,即僅支持在導入數據時使用。
compressiontype
導入文件的壓縮格式。
none(默認值):導入的文件未壓縮。
gzip:導入的文件壓縮格式為GZIP。
說明目前僅支持GZIP壓縮格式。
compressionlevel
設置寫入OSS的文件的壓縮等級,取值范圍為1~9,默認值為6。示例如下:
compressionlevel=6
oss_connect_timeout
設置連接超時。單位為秒,默認為10秒。
oss_dns_cache_timeout
設置DNS超時。單位為秒,默認為60秒。
oss_speed_limit
設置觸發超時的最小速率。默認為1024字節,即1 KB。
需要與oss_speed_time參數配合使用。
說明如果使用默認值且連續15秒的傳輸速率小于1 KB,會觸發超時。具體信息,請參見OSS SDK 錯誤處理。
oss_speed_time
設置觸發超時的最長時間。默認為15秒。
需要與oss_speed_limit參數配合使用。
說明如果使用默認值且連續15秒的傳輸速率小于1 KB,會觸發超時。具體信息,請參見OSS SDK 錯誤處理。
async
是否啟用異步模式導入數據。
開啟輔助線程從OSS導入數據,加速導入性能。
默認情況下異步模式為開啟狀態,如果需要關掉,可以使用參數
async = false
或async = f
。異步模式和普通模式比,會消耗更多的硬件資源。
并行導入數據。
在AnalyticDB PostgreSQL數據庫中執行如下命令,將OSS上的數據并行導入到AnalyticDB PostgreSQL數據庫。
INSERT INTO <目標表> SELECT * FROM <外部表>
操作示例
本文以目標表example為例,介紹將OSS的數據通過外部表導入目標表example。
創建OSS外部表插件。
創建命令如下:
CREATE EXTENSION IF NOT EXISTS oss_ext;
創建目標表,用于裝載數據。
CREATE TABLE example (date text, time text, open float, high float, low float, volume int) DISTRIBUTED BY (date);
創建OSS導入外部表。
創建外部表時,使用prefix參數指定待導入數據所在的路徑。示例如下:
CREATE READABLE EXTERNAL TABLE ossexample (date text, time text, open float, high float, low float, volume int) location('oss://oss-cn-hangzhou.aliyuncs.com prefix=osstest/example id=XXX key=XXX bucket=testbucket compressiontype=gzip') FORMAT 'csv' (QUOTE '''' DELIMITER E'\t') ENCODING 'utf8' LOG ERRORS SEGMENT REJECT LIMIT 5;
創建外部表時,使用dir參數指定待導入數據所在的路徑。示例如下:
CREATE READABLE EXTERNAL TABLE ossexample (date text, time text, open float, high float, low float, volume int) location('oss://oss-cn-hangzhou.aliyuncs.com dir=osstest/ id=XXX key=XXX bucket=testbucket') FORMAT 'csv' LOG ERRORS SEGMENT REJECT LIMIT 5;
創建外部表時,使用filepath參數指定待導入數據所在的路徑。示例如下:
CREATE READABLE EXTERNAL TABLE ossexample (date text, time text, open float, high float, low float, volume int) location('oss://oss-cn-hangzhou.aliyuncs.com filepath=osstest/example.csv id=XXX key=XXX bucket=testbucket') FORMAT 'csv' LOG ERRORS SEGMENT REJECT LIMIT 5;
將數據并行從ossexample外部表導入example表中。
INSERT INTO example SELECT * FROM ossexample;
執行如下查詢計劃,可以看到每個Segment節點都會從OSS并行拉取數據,然后通過執行節點Redistribution Motion將數據HASH計算后分發給對應的Segment節點,接收數據的Segment節點通過INSERT執行節點進行入庫。
EXPLAIN INSERT INTO example SELECT * FROM ossexample;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Insert (slice0; segments: 4) (rows=250000 width=92)
-> Redistribute Motion 4:4 (slice1; segments: 4) (cost=0.00..11000.00 rows=250000 width=92)
Hash Key: ossexample.date
-> External Scan on ossexample (cost=0.00..11000.00 rows=250000 width=92)
(4 rows)
SDK錯誤處理
當導入或導出操作出錯時,錯誤日志可能會出現如下信息:
code:出錯請求的HTTP狀態碼。
error_code:OSS的錯誤碼。
error_msg:OSS的錯誤信息。
req_id:標識該次請求的UUID。當您無法解決問題時,可以憑req_id來請求OSS開發工程師的幫助。
具體信息,請參見OSS API 錯誤響應,超時相關的錯誤可以使用oss_ext相關參數處理。