AnalyticDB for PostgreSQL は、gpossext 外部テーブル機能を使用して、Object Storage Service (OSS) からデータを並列でインポートできます。各コンピュートノードが OSS オブジェクトを同時に読み取るため、このアプローチは、大量のデータロードにおいて、1行ずつ挿入するよりも大幅に高速です。
この機能は、AnalyticDB for PostgreSQL V6.0 インスタンスにのみ適用されます。V7.0 については、「OSS 外部テーブルを使用してデータをインポートおよびエクスポートする」をご参照ください。
仕組み
gpossext 機能は、oss:// プロトコルハンドラで AnalyticDB for PostgreSQL を拡張します。oss_ext 拡張機能をインストールした後、OSS オブジェクトにマッピングされる読み取り可能な外部テーブルを定義します。INSERT INTO ... SELECT * FROM を実行すると、各コンピュートノードはポーリングメカニズムを介して OSS オブジェクトのサブセットを並列で読み取り、その後、行を正しい宛先パーティションに再配布します。
gpossext は、GZIP 圧縮の有無にかかわらず、TEXT および CSV ファイルを読み取ります。
外部テーブルを作成および使用するための構文は、location 関連のパラメーターの構文を除き、Greenplum Database の構文と同じです。
前提条件
開始する前に、以下が準備できていることを確認してください。
-
AnalyticDB for PostgreSQL V6.0 インスタンス
-
ご利用のインスタンスと同じリージョンにある OSS バケット
-
バケットへの読み取りアクセス権を持つ AccessKey ID と AccessKey Secret
-
TEXT または CSV ファイル (プレーンまたは GZIP 圧縮) として OSS にアップロード済みのソースデータ
OSS からのデータインポート
ステップ 1: oss_ext 拡張機能のインストール
OSS へのアクセスが必要な各データベースで、次の文を実行します。
CREATE EXTENSION IF NOT EXISTS oss_ext;
ステップ 2: 並列読み取りのためのソースファイルの分散
各コンピュートノードは、ポーリングメカニズムを使用して OSS オブジェクトを要求します。スループットを最大化するには、OSS オブジェクトの数をインスタンスのコンピュートノード数の整数倍に設定します。たとえば、4 つのコンピュートノードがある場合は、4、8、または 12 個のオブジェクトを使用します。
コンピュートノードが作業を分散する方法の詳細については、「OSS 外部テーブルの概要」をご参照ください。
ステップ 3: 読み取り可能な外部テーブルの作成
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]
必須パラメーター
| パラメーター | 説明 |
|---|---|
oss://oss_endpoint |
oss://oss_endpoint 形式の OSS エンドポイントです。例:oss://oss-cn-hangzhou.aliyuncs.com。AnalyticDB インスタンスが Alibaba Cloud サーバー上で実行されている場合は、内部エンドポイント (エンドポイント URL にキーワード internal が含まれています) を使用して、インターネットトラフィック料金を回避してください。 |
id |
ご利用の AccessKey ID です。「AccessKey ペアの作成」をご参照ください。 |
key |
ご利用の AccessKey Secret です。「AccessKey ペアの作成」をご参照ください。 |
bucket |
OSS バケット名です。インポートを実行する前にバケットを作成してください。 |
パスパラメーター (相互排他的 — いずれか 1 つだけを指定)
| パラメーター | 説明 |
|---|---|
prefix |
OSS オブジェクトのパスプレフィックスです。パスがこのプレフィックスで始まるすべてのオブジェクトをインポートします。正規表現はサポートされていません。たとえば、prefix=test/filename/ は test/filename/aa のみをインポートしますが、prefix=test/filename は test/filename、test/filenamexxx、test/filename/aa、test/filenameyyy/aa、および test/filenameyyy/bb/aa をインポートします。 |
dir |
OSS ディレクトリパスです。パスは / で終わる必要があります (例:test/mydir/)。サブディレクトリを除き、ディレクトリ内のすべてのオブジェクトを直接インポートします。 |
filepath |
OSS オブジェクトパスを含むオブジェクト名です。読み取り可能な外部テーブルのみ。 |
任意パラメーター
| パラメーター | デフォルト | 説明 |
|---|---|---|
FORMAT |
— | ファイル形式:TEXT または CSV。 |
ENCODING |
— | オブジェクトの文字エンコーディングです (utf8 など)。 |
compressiontype |
none |
圧縮形式です。有効な値:none、gzip。 |
compressionlevel |
6 |
OSS に書き込まれるファイルの圧縮レベルです。有効な値:1~9。 |
async |
true |
補助スレッドを使用して非同期インポートを有効にします。無効にするには false または f に設定します。非同期インポートは、通常のデータインポートと比較してより多くのハードウェアリソースを消費します。 |
oss_connect_timeout |
10 (秒) |
接続タイムアウト。 |
oss_dns_cache_timeout |
60 (秒) |
DNS 解決タイムアウト。 |
oss_speed_limit |
1024 (バイト/秒) |
最小転送レートです。oss_speed_time と一緒に設定する必要があります。 |
oss_speed_time |
15 (秒) |
タイムアウトが発生する前に転送レートが oss_speed_limit を下回ることができる最大持続時間です。oss_speed_limit と一緒に設定する必要があります。デフォルトでは、レートが 15 秒間連続して 1 KB/s を下回るとタイムアウトがトリガーされます。 |
LOG ERRORS |
— | インポートに失敗した行をスキップし、error_table に書き込みます。count を使用してエラー許容しきい値を設定します。 |
ステップ 4: (任意) 外部テーブルが読み取り可能であることの確認
完全なインポートを実行する前に、外部テーブルが OSS から読み取り可能であることを確認します。
-- 行のサンプルを確認
SELECT * FROM <External table> LIMIT 10;
-- クエリプランを検査して並列読み取りを確認
EXPLAIN INSERT INTO <Destination table> SELECT * FROM <External table>;
クエリプランには、すべてのセグメントで External Scan ノードが実行されていることが表示され、コンピュートノードが OSS オブジェクトを並列で読み取ることが確認できます。
ステップ 5: 並列インポートの実行
INSERT INTO <Destination table> SELECT * FROM <External table>;
各コンピュートノードは、割り当てられた OSS オブジェクトを読み取り、行を宛先テーブルに挿入します。再配布モーションノードは行をハッシュ化し、分散キーに基づいて正しいコンピュートノードにルーティングします。
例
この例では、OSS から株価データを example という名前のテーブルにインポートします。
1. 拡張機能をインストールします。
CREATE EXTENSION IF NOT EXISTS oss_ext;
2. 宛先テーブルを作成します。
CREATE TABLE example
(date text, time text, open float,
high float, low float, volume int)
DISTRIBUTED BY (date);
インポートパフォーマンスを最大化するには、圧縮を使用した列指向ストレージを使用します。たとえば、次の句を指定できます:WITH (APPENDONLY=true, ORIENTATION=column, COMPRESSTYPE=zlib, COMPRESSLEVEL=5, BLOCKSIZE=1048576)。詳細については、「CREATE TABLE」をご参照ください。
3. 外部テーブルを作成します。OSS でのファイルの整理方法に一致するパスパラメーターを選択します。
prefix を使用 (一致するパスプレフィックスを持つすべてのオブジェクトをインポート、GZIP をサポート):
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 を使用 (ディレクトリ内のすべてのオブジェクトを直接インポート、GZIP なし):
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;
4. データをインポートします。
INSERT INTO example SELECT * FROM ossexample;
クエリプランは、4 つすべてのコンピュートノードが OSS から並列で読み取ることを確認します。
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)
TEXT および CSV 形式のリファレンス
以下のパラメーターは、gpossext が TEXT および CSV ファイルを解析する方法を制御します。これらは CREATE EXTERNAL TABLE 文の FORMAT 句で指定します。
-
\n:行区切り文字 (改行文字) -
DELIMITER:列区切り文字です。指定した場合、QUOTEも指定する必要があります。一般的な選択肢:,、|、\t。 -
QUOTE:特殊文字を含む列値を囲みます。DELIMITERとは異なる必要があります。デフォルト:"。QUOTE文字を含む値はESCAPEも使用する必要があります。 -
ESCAPE:リテラルとして扱う必要がある文字の前に置かれます。デフォルト:QUOTEと同じです。バックスラッシュ (\) も一般的に使用されます。
すべての制御文字はシングルバイトである必要があります。
デフォルトの制御文字
| 制御文字 | TEXT | CSV |
|---|---|---|
| DELIMITER | \t (タブ) |
, (カンマ) |
| QUOTE | " (二重引用符) |
" (二重引用符) |
| ESCAPE | N/A | " (二重引用符) |
| NULL | \N (バックスラッシュ n) |
引用符なしの空文字列 |
トラブルシューティング
インポートエラーの確認
外部テーブルの作成時に LOG ERRORS を使用した場合、次のコマンドで失敗した行を取得します。
SELECT * FROM gp_read_error_log('external_table_name');
確認後にエラーログをクリアするには、次のようにします。
SELECT gp_truncate_error_log('external_table_name');
エラーログは、外部テーブルを削除すると自動的に削除されます。
SDK エラーフィールドの解釈
インポートログの OSS SDK エラーには、次のフィールドが含まれます。
| フィールド | 説明 |
|---|---|
code |
失敗したリクエストの HTTP ステータスコード |
error_code |
OSS エラーコード |
error_msg |
OSS エラーメッセージ |
req_id |
失敗したリクエストの UUID です。継続的な問題を Alibaba Cloud サポートに報告する際に、これを提供してください。 |
OSS のエラーコードの詳細については、「エラー応答」をご参照ください。
タイムアウトエラーの修正
oss_speed_limit と oss_speed_time を一緒に調整して、タイムアウトの動作をチューニングします。一般的な OSS のタイムアウト処理については、「エラー処理エラー処理」をご参照ください。
次のステップ
-
OSS ドメイン名 — リージョンごとの正しいエンドポイントを検索
-
OSS ドキュメント — バケットとオブジェクトの管理
-
CREATE TABLE — テーブルストレージオプションの完全な構文
-
エラー応答 — OSS エラーコードリファレンス