MaxCompute では、Object Storage Service (OSS) 外部テーブルを作成して OSS ディレクトリにマッピングできます。これにより、OSS ディレクトリ内のファイルから非構造化データにアクセスしたり、MaxCompute プロジェクトから OSS ディレクトリにデータを書き込んだりできます。このトピックでは、OSS 外部テーブルの作成、およびそこからのデータの読み取りまたは書き込みの構文とパラメーターについて説明します。
前提条件
Alibaba Cloud アカウント、RAM ユーザー、または RAM ロールには、OSS 外部テーブルにアクセスするために必要な権限が必要です。権限付与の詳細については、「OSS の STS 権限付与」をご参照ください。
(オプション) OSS バケット、OSS ディレクトリ、および OSS データファイルを作成済みであること。詳細については、「バケットの作成」、「ディレクトリの管理」、および「簡易アップロード」をご参照ください。
MaxCompute は OSS 内にディレクトリを自動的に作成できます。単一の SQL 文を使用して、外部テーブルと UDF の両方を含む読み取りおよび書き込み操作を実行できます。手動でのディレクトリ作成は不要になりましたが、従来の方法も引き続きサポートされています。
MaxCompute プロジェクトを作成済みであること。詳細については、「MaxCompute プロジェクトの作成」をご参照ください。
MaxCompute は特定のリージョンにのみデプロイされます。リージョン間のデータ接続性の問題を回避するため、MaxCompute プロジェクトと同じリージョンにあるバケットを使用してください。
Alibaba Cloud アカウントまたは RAM ユーザーが、プロジェクトに対する CreateTable 権限を持っていること。テーブル操作の権限の詳細については、「MaxCompute の権限」をご参照ください。
注意
OSS 外部テーブルは、OSS ディレクトリへのマッピングのみを記録します。OSS 外部テーブルを削除しても、マッピングされた OSS ディレクトリ内のデータファイルは削除されません。
OSS データファイルがアーカイブ済みのオブジェクトである場合、まずオブジェクトを解凍する必要があります。
OSS にはクラシックネットワークのエンドポイントを使用してください。MaxCompute はパブリックエンドポイントのネットワーク接続を保証しません。
制限事項
OSS 外部テーブルではクラスタープロパティはサポートされていません。
単一ファイルのサイズは 3 GB を超えることはできません。ファイルが 3 GB を超える場合は、分割する必要があります。
エントリポイント
以下のプラットフォームで OSS 外部テーブルを作成し、そこからデータを読み取ったり、データを書き込んだりできます。
方法 | プラットフォーム |
MaxCompute SQL | |
可視化 |
OSS 外部テーブルの作成
OSS 外部テーブルは、パーティション化されている場合とされていない場合があります。作成する外部テーブルのタイプは、データファイルが OSS にどのように格納されているかによって決まります。データファイルがパーティション化されたディレクトリに格納されている場合は、パーティション化された外部テーブルを作成します。それ以外の場合は、パーティション化されていない外部テーブルを作成します。
注意
CREATE EXTERNAL TABLE 文は、データファイル形式によって異なるパラメーターを必要とします。読み取りまたは書き込み操作中にエラーを回避するために、特定のビジネスニーズに合わせて正しい構文とパラメーターを使用していることを確認してください。
構文
シナリオ: 組み込みのテキストデータパーサーを使用して外部テーブルを作成する
構文
データファイル形式
例
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [comment <table_comment>] [partitioned BY (<col_name> <data_type>, ...)] stored BY '<StorageHandler>' WITH serdeproperties ( ['<property_name>'='<property_value>',...] ) location '<oss_location>';OSS からのデータの読み取りまたは OSS へのデータの書き込みでサポートされているデータファイル形式:
CSV
TSV
GZIP、SNAPPY、または LZO 形式で圧縮された CSV または TSV ファイル
シナリオ: 組み込みのオープンソースデータパーサーを使用して外部テーブルを作成する
構文
データファイル形式
例
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [comment <table_comment>] [partitioned BY (<col_name> <data_type>, ...)] [row format serde '<serde_class>' [WITH serdeproperties ( ['<property_name>'='<property_value>',...]) ] ] stored AS <file_format> location '<oss_location>' [USING '<resource_name>'] [tblproperties ('<tbproperty_name>'='<tbproperty_value>',...)];OSS からのデータの読み取りまたは OSS へのデータの書き込みでサポートされているデータファイル形式:
PARQUET
TEXTFILE
ORC
RCFILE
AVRO
JSON
SEQUENCEFILE
Hudi (Data Lake Formation (DLF) によって生成された Hudi データの読み取りのみをサポートします。)
ZSTD、SNAPPY、または GZIP 形式で圧縮された PARQUET ファイル
SNAPPY または ZLIB 形式で圧縮された ORC ファイル
GZIP、SNAPPY、または LZO 形式で圧縮された TEXTFILE ファイル
シナリオ: カスタムパーサーを使用して外部テーブルを作成する
構文
データファイル形式
例
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <date_type>, ... ) [comment <table_comment>] [partitioned BY (<col_name> <data_type>, ...)] stored BY '<StorageHandler>' WITH serdeproperties ( ['<property_name>'='<property_value>',...] ) location '<oss_location>' USING '<jar_name>';OSS からのデータの読み取りまたは OSS へのデータの書き込みでサポートされているデータファイル形式: 上記以外の形式のデータファイル。
パラメーター
次の表に、すべての形式の外部テーブルに共通のパラメーターを示します。特定の形式に固有のパラメーターについては、その形式のドキュメントをご参照ください。
基本構文パラメーター
パラメーター
必須
説明
mc_oss_extable_name
はい
作成する OSS 外部テーブルの名前。
テーブル名では大文字と小文字は区別されません。外部テーブルをクエリする場合、大文字と小文字を区別する必要はありません。強制的な大文字と小文字の変換はサポートされていません。
col_name
はい
OSS 外部テーブルの列の名前。
OSS からデータを読み取る場合、作成された OSS 外部テーブルのスキーマは、OSS データファイルのスキーマと同じでなければなりません。そうでない場合、OSS データを読み取ることはできません。
data_type
はい
OSS 外部テーブルの列のデータ型。
OSS からデータを読み取る場合、OSS 外部テーブルの列のデータ型は、OSS データファイルの列のデータ型と同じでなければなりません。そうでない場合、OSS データを読み取ることはできません。
table_comment
いいえ
テーブルのコメント。コメントは、最大 1,024 バイトの有効な文字列である必要があります。そうでない場合、エラーが返されます。
partitioned by (col_name data_type, ...)
いいえ
OSS のデータファイルがパーティション化されたディレクトリに格納されている場合、このパラメーターはパーティションテーブルを作成するために必須です。
col_name: パーティションキー列の名前。
data_type: パーティションキー列のデータ型。
'<(tb)property_name>' = '<(tb)property_value>'
はい
OSS 外部テーブルの拡張プロパティ。パラメーターの詳細については、特定の形式のドキュメントをご参照ください。
oss_location
はい
データファイルが格納されている OSS パス。デフォルトでは、MaxCompute はこのパス内のすべてのデータファイルを読み取ります。
フォーマット:
oss://<oss_endpoint>/<Bucket name>/<OSS directory name>/。oss_endpoint:
OSS エンドポイント。OSS が提供するクラシックネットワークのエンドポイントを使用します。これは
-internalを含むエンドポイントです。例:
oss://oss-cn-beijing-internal.aliyuncs.com/xxx。OSS クラシックネットワークのエンドポイントの詳細については、「OSS のリージョンとエンドポイント」をご参照ください。
データファイルが格納されている OSS リージョンは、MaxCompute プロジェクトが配置されているリージョンと同じにすることをお勧めします。異なるリージョンにある場合、データ接続性の問題が発生する可能性があります。
エンドポイントは省略できます。エンドポイントを指定しない場合、システムはデフォルトで現在のプロジェクトが配置されているリージョンのエンドポイントを使用します。
ファイルストレージがリージョンをまたぐ場合、データ接続性の問題が発生する可能性があるため、この方法は推奨されません。
Bucket name: OSS バケットの名前。
例:
oss://oss-cn-beijing-internal.aliyuncs.com/your_bucket/path/。バケット名の詳細については、「バケットのリスト」をご参照ください。
Directory name: OSS ディレクトリの名前。ディレクトリの後にファイル名を指定しないでください。
例:
oss://oss-cn-beijing-internal.aliyuncs.com/oss-mc-test/Demo1/。不正な例:
-- HTTP 接続はサポートされていません。 http://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/ -- HTTPS 接続はサポートされていません。 https://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/ -- エンドポイントが無効です。 oss://oss-cn-shanghai-internal.aliyuncs.com/Demo1 -- ファイル名を指定しないでください。 oss://oss-cn-shanghai-internal.aliyuncs.com/oss-mc-test/Demo1/vehicle.csv権限仕様 (RamRole):
明示的に指定 (推奨): カスタムロールを作成し、それにアクセスポリシーをアタッチして、その ARN を使用します。詳細については、「STS パターン権限付与」をご参照ください。
デフォルトロールを使用 (非推奨):
aliyunodpsdefaultroleロールの ARN を使用します。
WITH serdeproperties プロパティ
property_name
シナリオ
property_value
デフォルト値
odps.properties.rolearn
セキュリティトークンサービス (STS) 権限付与を使用する場合、このプロパティを追加します。
OSS へのアクセス権限が付与された RAM ロールの Alibaba Cloud リソースネーム (ARN)。ARN は RAM コンソール のロール詳細から取得できます。例:
acs:ram::xxxxxx:role/aliyunodpsdefaultrole。MaxCompute と OSS のオーナーが同じ Alibaba Cloud アカウントの場合:
テーブルを作成するために使用される文で
odps.properties.rolearnを指定しない場合、デフォルトでaliyunodpsdefaultroleロールの ARN が使用されます。カスタムロールの ARN を使用したい場合は、事前にカスタムロールを作成する必要があります。詳細については、「OSS の STS 権限付与 (方法 2)」をご参照ください。
MaxCompute と OSS のオーナーが異なる Alibaba Cloud アカウントの場合、カスタムロールの ARN を指定する必要があります。カスタムロールの作成方法の詳細については、「OSS の STS 権限付与 (方法 3)」をご参照ください。
OSS 外部テーブルにパーティションデータを追加するための構文
パーティション化された OSS 外部テーブルを作成した場合、次のいずれかの方法を使用してパーティションデータを追加する必要があります:
方法 1 (推奨): OSS ディレクトリを自動的に解析してパーティションを識別し、パーティション情報を OSS 外部テーブルに追加する。
この方法は、不足しているすべての履歴パーティションを一度に追加したいシナリオに適しています。MaxCompute は、OSS 外部テーブルを作成したときに指定したパーティションディレクトリに基づいて、OSS 外部テーブルにパーティションを自動的に追加します。パーティションキー列の名前と値に基づいてパーティションを 1 つずつ追加する必要はありません。
MSCK REPAIR TABLE <mc_oss_extable_name> ADD PARTITIONS [ WITH properties (key:VALUE, key: VALUE ...)];この方法は、増分データの処理には適していません。特に、OSS ディレクトリに 1,000 を超えるような多数のパーティションが含まれている場合は適していません。新しいパーティションの数が既存のパーティションの数よりもはるかに少ない場合、
msckコマンドを頻繁に使用すると、OSS ディレクトリの繰り返しスキャンとメタデータの頻繁な更新が発生し、コマンドの実行効率が低下します。増分パーティションを更新する必要があるシナリオでは、方法 2 を使用することをお勧めします。方法 2: 手動でコマンドを実行して、パーティション情報を OSS 外部テーブルに追加する。
この方法は、履歴パーティションがすでに作成されており、新しいパーティションを頻繁に追加する必要があるシナリオに適しています。データ書き込みタスクを実行する前に、パーティションを作成する必要があります。新しいデータが OSS に書き込まれたときにパーティションをリフレッシュする必要はありません。外部テーブルは、OSS ディレクトリから最新のデータを直接読み取ることができます。
ALTER TABLE <mc_oss_extable_name> ADD PARTITION (<col_name>=<col_value>)[ ADD PARTITION (<col_name>=<col_value>)...][location URL];col_name と col_value の値は、パーティションデータファイルが格納されているディレクトリの名前と一致する必要があります。
たとえば、パーティションデータファイルの OSS ディレクトリ構造が次の図のようになっているとします。col_name は
directionに対応し、col_value はN, NE, S, SW, Wに対応します。各add partition文は 1 つのサブディレクトリに対応します。複数の OSS サブディレクトリを追加するには、複数のadd partition文を実行する必要があります。
OSS データの読み取り
注意
OSS 外部テーブルを作成した後、それを使用して OSS からデータを読み取ることができます。MaxCompute でサポートされている OSS データファイル形式と OSS 外部テーブルを作成するための構文の詳細については、「構文」をご参照ください。
SQL 文に複雑なデータ型が含まれている場合は、SQL 文の前に
set odps.sql.type.system.odps2=true;コマンドを追加して、それらを一緒に送信する必要があります。データ型の詳細については、「データ型バージョンガイド」をご参照ください。オープンソースデータにマッピングされている OSS 外部テーブルの場合、OSS からデータを読み取る前に、セッションレベルで
set odps.sql.hive.compatible=true;を設定する必要があります。そうしないと、エラーが返されます。OSS は限られたアウトバウンド帯域幅を提供します。短期間にインスタンスの帯域幅制限をデータ読み取りおよび書き込みトラフィックが超えると、OSS 外部テーブルの読み取りおよび書き込み速度が影響を受けます。OSS の帯域幅の詳細については、「制限とパフォーマンスメトリック」をご参照ください。
構文
<select_statement> FROM <from_statement>;select_statement: 宛先テーブルに挿入されるソーステーブルからデータをクエリするために使用される
SELECT句。from_statement: 外部テーブル名など、データソースを指定する
FROM句。
非パーティションデータ
非パーティション化された OSS 外部テーブルを作成した後、次のいずれかの方法で OSS からデータを読み取ることができます:
方法 1 (推奨): OSS から MaxCompute 内部テーブルにデータをインポートし、その後、内部テーブルをクエリする。
この方法は、データを繰り返し計算する必要がある場合や、計算パフォーマンスに対する要件が高いシナリオに適しています。MaxCompute プロジェクトに OSS 外部テーブルと同じスキーマを持つ内部テーブルを作成し、OSS から内部テーブルにデータをインポートしてから、複雑なクエリを実行できます。この方法により、内部ストレージに対する MaxCompute の最適化メカニズムを最大限に活用して、計算パフォーマンスを向上させることができます。例:
CREATE TABLE <table_internal> LIKE <mc_oss_extable_name>; INSERT OVERWRITE TABLE <table_internal> SELECT * FROM <mc_oss_extable_name>;方法 2: MaxCompute 内部テーブルからデータを読み取るのと同じ方法で、OSS から直接データを読み取る。
この方法は、計算パフォーマンスに対する要件が高くないシナリオに適しています。内部テーブルからデータを読み取るのとは異なり、各読み取り操作は OSS から直接データを取得します。
パーティションデータ
OSS 外部テーブルをクエリすると、MaxCompute はサブディレクトリ内のデータを含む、OSS ディレクトリ内のすべてのデータに対して全表スキャンを実行します。データ量が大きい場合、完全なディレクトリスキャンは不要な I/O 消費を引き起こし、データ処理時間を増加させます。この問題を解決するには、次のいずれかの方法を使用できます:
方法 1 (推奨): 標準パーティションパスまたはカスタムパーティションパス形式のいずれかを使用して OSS にデータを格納する。
OSS 外部テーブルを作成するときは、作成文でパーティションと oss_location 情報を指定する必要があります。OSS データを標準のパーティションディレクトリに格納することをお勧めします。
方法 2: 複数のデータストレージパスを使用する。
複数の OSS 外部テーブルを作成して、異なるパスからデータを読み取ります。各 OSS 外部テーブルは、OSS データのサブセットにマッピングされます。この方法は面倒で、データ管理が不十分になるため、お勧めしません。
標準パーティションディレクトリ形式
oss://<oss_endpoint>/<Bucket name>/<Directory name>/<partitionKey1=value1>/<partitionKey2=value2>/...例: ある会社が、毎日生成されるログファイルを CSV 形式で OSS に格納し、MaxCompute を使用して毎日データを処理しています。OSS データには、次の標準パーティションディレクトリを指定できます:
oss://oss-odps-test/log_data/year=2016/month=06/day=01/logfile
oss://oss-odps-test/log_data/year=2016/month=06/day=02/logfile
oss://oss-odps-test/log_data/year=2016/month=07/day=10/logfile
oss://oss-odps-test/log_data/year=2016/month=08/day=08/logfile
...カスタムパーティションディレクトリ形式
カスタムパーティションディレクトリ形式では、パーティション列の値のみが含まれ、パーティション列名は含まれません。例:
oss://oss-odps-test/log_data_customized/2016/06/01/logfile
oss://oss-odps-test/log_data_customized/2016/06/02/logfile
oss://oss-odps-test/log_data_customized/2016/07/10/logfile
oss://oss-odps-test/log_data_customized/2016/08/08/logfile
...OSS のデータはパーティションごとに格納されますが、パスは標準のパーティションディレクトリ形式ではありません。MaxCompute では、サブディレクトリを異なるパーティションにバインドして、その中のデータにアクセスできます。
解決策: OSS 外部テーブルを作成した後、alter table ... add partition ... location ... コマンドを実行してサブディレクトリを指定し、それらをパーティションにバインドします。例:
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '01')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket-name/oss-odps-test/log_data_customized/2016/06/01/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '06', day = '02')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket-name/oss-odps-test/log_data_customized/2016/06/02/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '07', day = '10')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket-name/oss-odps-test/log_data_customized/2016/07/10/';
ALTER TABLE log_table_external ADD PARTITION (year = '2016', month = '08', day = '08')
location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/bucket-name/oss-odps-test/log_data_customized/2016/08/08/';クエリの最適化
動的統計収集
データは外部データレイクに格納されており、事前に計算された統計情報がないため、クエリオプティマイザーは保守的な戦略を採用し、クエリ効率が低くなる可能性があります。動的統計収集機能により、オプティマイザーはクエリ実行中にテーブル統計を一時的に収集して、小さなテーブルを識別できます。オプティマイザーはこの情報を使用して、ハッシュ結合を積極的に使用し、結合順序を最適化し、データシャッフルを減らし、実行パイプラインを短縮してクエリを最適化できます。
SET odps.meta.exttable.stats.onlinecollect=true; SELECT * FROM <tablename>;外部テーブルの分割の最適化
分割サイズパラメーターを設定することで、クエリ効率を最適化できます。これにより、単一の同時タスクによって処理されるデータ量が調整されます。分割サイズの設定には次の効果があります:
テーブルに大量のデータが含まれており、分割サイズが小さすぎると、作成される分割が多すぎます。これにより、並列処理の次数が高くなり、インスタンスはほとんどの時間をリソースのキューイングに費やします。
テーブルに含まれるデータが少なく、分割サイズが大きすぎると、作成される分割が少なすぎます。これにより、同時実行性が不十分になり、ほとんどのリソースがアイドル状態のままになります。
SET odps.stage.mapper.split.size=<value>; SELECT * FROM <tablename>;
OSS へのデータの書き込み
OSS からのデータの読み取りと同様に、MaxCompute では、内部テーブルからのデータや外部テーブルから処理されたデータを OSS に書き込むことができます。
組み込みのテキストまたはオープンソースデータパーサーを使用して OSS にデータを書き込む: CSV/TSV 外部テーブル、CSV/TSV 外部テーブル、CSV/TSV 外部テーブル、および 組み込みのオープンソースデータパーサーを使用して OSS にデータを書き込む。
カスタムパーサーを使用して OSS にデータを書き込む: 例: カスタムパーサーを使用して OSS 外部テーブルを作成する。
OSS のマルチパートアップロード機能を使用して OSS にデータを書き込む: OSS のマルチパートアップロード機能を使用して OSS にデータを書き込む。
構文
INSERT {INTO|OVERWRITE} TABLE <table_name> PARTITION (<ptcol_name>[, <ptcol_name> ...])
<select_statement> FROM <from_statement>;パラメーター | 必須 | 説明 |
table_name | はい | データを書き込む外部テーブルの名前。 |
select_statement | はい | 宛先テーブルに挿入されるソーステーブルからデータをクエリするために使用される |
from_statement | はい | データソースを指定する |
動的パーティションにデータを挿入するには、「動的パーティションデータの挿入または上書き (DYNAMIC PARTITION)」をご参照ください。
注意
INSERT OVERWRITE ... SELECT ... FROM ...;操作がソーステーブル from_tablename に 1,000 個の Mapper を割り当てた場合、1,000 個の TSV または CSV ファイルが生成されます。MaxCompute が提供する構成を使用して、生成されるファイルの数を制御できます。
Mapper での出力:
odps.stage.mapper.split.sizeを使用して Mapper の同時実行性を制御し、生成されるファイルの数を調整します。Reducer または Joiner での出力:
odps.stage.reducer.numおよびodps.stage.joiner.numを使用して、生成されるファイルの数を調整します。
OSS マルチパートアップロード機能を使用した OSS へのデータ書き込み
オープンソース形式で OSS にデータを書き込むには、オープンソースデータパーサーに基づく OSS 外部テーブルと OSS のマルチパートアップロード機能を使用して INSERT 操作を実行できます。
次の設定を使用して、OSS マルチパートアップロード機能を有効にできます:
シナリオ | コマンド |
プロジェクトレベルで設定 | この設定はプロジェクト全体で有効になります。 |
セッションレベルで設定 | この設定は現在のタスクに対してのみ有効になります。 |
odps.sql.unstructured.oss.commit.mode プロパティのデフォルト値は false です。次の表に、このプロパティの各値の実装原則を示します:
値 | 原則 |
false | MaxCompute が OSS 外部テーブルに書き込むデータは、LOCATION ディレクトリの .odps フォルダに格納されます。.odps フォルダには、MaxCompute データの整合性を確保するために使用される .meta ファイルが含まれています。MaxCompute のみが .odps フォルダ内のコンテンツを正しく処理できます。他のデータ処理エンジンはコンテンツを正しく解析できず、エラーが発生する可能性があります。 |
true | MaxCompute は、他のデータ処理エンジンと互換性のあるマルチパートアップロード機能を使用します。MaxCompute は、 |
エクスポートされたファイルの管理
パラメーター
OSS に書き込まれるデータファイルにプレフィックス、サフィックス、または拡張子を追加する必要がある場合は、次のパラメーターを設定できます。
property_name | シナリオ | 説明 | property_value | デフォルト値 |
odps.external.data.output.prefix (odps.external.data.prefix と互換性あり) | 出力ファイルにカスタムプレフィックスを追加する必要がある場合にこのプロパティを追加します。 |
| 'mc_' などの有効な文字の組み合わせ。 | なし |
odps.external.data.enable.extension | 出力ファイルの拡張子を表示する必要がある場合にこのプロパティを追加します。 | True は出力ファイルの拡張子が表示されることを示します。False は拡張子が表示されないことを示します。 |
| False |
odps.external.data.output.suffix | 出力ファイルにカスタムサフィックスを追加する必要がある場合にこのプロパティを追加します。 | 文字、数字、アンダースコア (a-z、A-Z、0-9、_) のみを含みます。 | '_hangzhou' などの有効な文字の組み合わせ。 | なし |
odps.external.data.output.explicit.extension | 出力ファイルにカスタム拡張子を追加する必要がある場合にこのプロパティを追加します。 |
| "jsonl" などの有効な文字の組み合わせ。 | なし |
使用例
出力 OSS ファイルのカスタムプレフィックスを
test06_に設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムプレフィックスを設定します。 'odps.external.data.output.prefix'='test06_') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルのカスタムサフィックスを
_beijingに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムサフィックスを設定します。 'odps.external.data.output.suffix'='_beijing') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルの拡張子が自動的に生成されます。DDL 文は次のとおりです:
CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- 拡張子を自動的に生成します。 'odps.external.data.enable.extension'='true') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');下の図は、生成されたファイルを示しています。
出力 OSS ファイルのカスタム拡張子を
jsonlに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタム拡張子を設定します。 'odps.external.data.output.explicit.extension'='jsonl') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

出力 OSS ファイルのプレフィックスを
mc_、サフィックスを_beijing、拡張子をjsonlに設定します。DDL 文は次のとおりです:CREATE EXTERNAL TABLE <mc_oss_extable_name> ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongitude DOUBLE, recordTime STRING, direction STRING ) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-beijing-internal.aliyuncs.com/***/' TBLPROPERTIES ( -- カスタムプレフィックスを設定します。 'odps.external.data.output.prefix'='mc_', -- カスタムサフィックスを設定します。 'odps.external.data.output.suffix'='_beijing', -- カスタム拡張子を設定します。 'odps.external.data.output.explicit.extension'='jsonl') ; -- 外部テーブルにデータを書き込みます。 INSERT INTO <mc_oss_extable_name> VALUES (1,32,76,1,63.32106,-92.08174,'9/14/2014 0:10','NW');次の図は、生成されたファイルを示しています。

動的パーティションへの大きなファイルの書き込み
ビジネスシナリオ
先祖テーブルの計算結果をパーティション単位で OSS にエクスポートし、4 GB のファイルなどの大きなファイルとして書き込む必要があります。
odps.adaptive.shuffle.desired.partition.size パラメーター (MB 単位) は、各 Reducer によって処理されるデータ量を制御し、それによって各出力ファイルのサイズが決まります。このパラメーターを使用してより大きな出力ファイルを作成すると、並列処理が減少し、ジョブ全体の実行時間が増加する可能性があります。
パラメーター
-- 動的パーティション機能を有効にする必要があります。
set odps.sql.reshuffle.dynamicpt=true;
-- 各 Reducer が消費するデータの希望量を設定します。各ファイルを 4 GB にすると仮定します。
set odps.adaptive.shuffle.desired.partition.size=4096; 使用例
約 4 GB の JSON ファイルを OSS に書き込みます。
テストデータを準備します。パブリックデータセットから
bigdata_public_dataset.tpcds_1t.web_salesテーブルを使用します。これは約 30 GB です。データは MaxCompute に圧縮形式で格納されており、エクスポート後にサイズが増加します。JSON 外部テーブルを作成します。
-- サンプルテーブル名: json_ext_web_sales CREATE EXTERNAL TABLE json_ext_web_sales( c_int INT , c_string STRING ) PARTITIONED BY (pt STRING) ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS textfile LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/demo-test/';パラメーターを設定せずに、テストテーブルのデータを動的パーティションを使用して JSON 外部テーブルに書き込みます。
-- レイヤー 3 構文スイッチを有効にします。 set odps.namespace.schema=true; -- 動的パーティションを使用して JSON 外部テーブルにデータを書き込みます。 INSERT OVERWRITE json_ext_web_sales PARTITION(pt) SELECT CAST(ws_item_sk AS INT) AS c_int, CAST(ws_bill_customer_sk AS string) AS c_string , COALESCE(CONCAT(ws_bill_addr_sk %2, '_', ws_promo_sk %3),'null_pt') AS pt FROM bigdata_public_dataset.tpcds_1t.web_sales;次の図は、OSS に格納されているファイルを示しています:

大きなファイルを出力するために
odps.adaptive.shuffle.desired.partition.sizeパラメーターを追加し、テストテーブルを動的パーティションで JSON 外部テーブルに書き込みます。-- レイヤー 3 スキーマ構文を有効にします。 set odps.namespace.schema=true; -- 動的パーティション機能を有効にする必要があります。 set odps.sql.reshuffle.dynamicpt=true; -- 各 Reducer が消費するデータの希望量を設定します。各ファイルを 4 GB にすると仮定します。 set odps.adaptive.shuffle.desired.partition.size=4096; -- 動的パーティションで JSON 外部テーブルにデータを書き込みます。 INSERT OVERWRITE json_ext_web_sales PARTITION(pt) SELECT CAST(ws_item_sk AS INT) AS c_int, CAST(ws_bill_customer_sk AS string) AS c_string , COALESCE(CONCAT(ws_bill_addr_sk %2, '_', ws_promo_sk %3),'null_pt') AS pt FROM bigdata_public_dataset.tpcds_1t.web_sales;OSS に格納されているファイルを次の図に示します:
OSS からのデータのインポートまたは OSS へのデータのエクスポート
付録: サンプルデータの準備
OSS ディレクトリの準備
次のサンプルデータが使用されます:
oss_endpoint:
oss-cn-hangzhou-internal.aliyuncs.com、これは中国 (杭州) リージョンのエンドポイントです。バケット名:
oss-mc-test。ディレクトリ名:
Demo1/、Demo2/、Demo3/、およびSampleData/。
非パーティションテーブルデータ
vehicle.csv ファイルは
Demo1/ディレクトリにアップロードされ、次のデータが含まれています。Demo1/ディレクトリは、組み込みのテキストデータパーサーを使用して作成された非パーティションテーブルとのマッピングを確立するために使用されます。1,1,51,1,46.81006,-92.08174,9/14/2014 0:00,S 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00,NE 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00,W 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00,S 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00,S 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00,N 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00,SW 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00,NE 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00,Nパーティションテーブルデータ
Demo2/ディレクトリには、direction=N/、direction=NE/、direction=S/、direction=SW/、およびdirection=W/の 5 つのサブディレクトリが含まれています。ファイル vehicle1.csv、vehicle2.csv、vehicle3.csv、vehicle4.csv、および vehicle5.csv は、それぞれこれらのサブディレクトリにアップロードされ、次のデータが含まれています。Demo2/ディレクトリは、組み込みのテキストデータパーサーを使用して作成されたパーティションテーブルにマッピングするために使用されます。--vehicle1.csv 1,7,53,1,46.81006,-92.08174,9/15/2014 0:00 1,10,31,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle2.csv 1,2,13,1,46.81006,-92.08174,9/14/2014 0:00 1,3,48,1,46.81006,-92.08174,9/14/2014 0:00 1,9,4,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle3.csv 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00 1,5,47,1,46.81006,-92.08174,9/14/2014 0:00 1,6,9,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle4.csv 1,8,63,1,46.81006,-92.08174,9/15/2014 0:00 --vehicle5.csv 1,4,30,1,46.81006,-92.08174,9/14/2014 0:00圧縮データ
vehicle.csv.gz ファイルは
Demo3/ディレクトリにアップロードされます。この圧縮ファイルには、Demo1/ディレクトリのファイルと同じ内容の vehicle.csv が含まれています。このファイルは、圧縮された OSS 外部テーブルへのマッピングを作成するために使用されます。カスタムパーサーデータ
vehicle6.csv ファイルは
SampleData/ディレクトリにアップロードされ、次のデータが含まれています。SampleData/ディレクトリは、オープンソースデータパーサーを使用して作成された OSS 外部テーブルにマッピングするために使用されます。1|1|51|1|46.81006|-92.08174|9/14/2014 0:00|S 1|2|13|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|3|48|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|4|30|1|46.81006|-92.08174|9/14/2014 0:00|W 1|5|47|1|46.81006|-92.08174|9/14/2014 0:00|S 1|6|9|1|46.81006|-92.08174|9/14/2014 0:00|S 1|7|53|1|46.81006|-92.08174|9/14/2014 0:00|N 1|8|63|1|46.81006|-92.08174|9/14/2014 0:00|SW 1|9|4|1|46.81006|-92.08174|9/14/2014 0:00|NE 1|10|31|1|46.81006|-92.08174|9/14/2014 0:00|N
よくある質問
外部テーブルを使用して OSS データを処理する際に「Inline data exceeds the maximum allowed size」エラーを解決するにはどうすればよいですか?
ローカルテストに合格した UDF を使用して MaxCompute の OSS 外部テーブルにアクセスするとメモリ不足エラーが発生する場合、どうすれば解決できますか?
OSS 外部テーブルを読み取る際に「Couldn't connect to server」エラーを解決するにはどうすればよいですか?
OSS 外部テーブルを作成する際に「Network is unreachable (connect failed)」エラーを解決するにはどうすればよいですか?
マルチパートアップロードのシナリオで、古いデータは削除されたが新しいデータが書き込まれない問題を解決するにはどうすればよいですか?
外部テーブルを使用して OSS データを処理する際に「Inline data exceeds the maximum allowed size」エラーを解決するにはどうすればよいですか?
現象
OSS データを処理する際に、
Inline data exceeds the maximum allowed sizeというエラーが報告されます。原因
OSS 内の単一ファイルのサイズが 3 GB を超えることはできません。ファイルがこの制限を超えると、このエラーが報告されます。
解決策
この問題を解決するには、次の 2 つのプロパティを調整できます。目的は、これらのプロパティ値を使用して実行計画を調整し、各 Reducer が OSS 外部テーブルに書き込むデータのサイズを制御して、OSS ファイルが 3 GB の制限を超えないようにすることです。
set odps.sql.mapper.split.size=256; # 各 Mapper が読み取るデータのサイズを調整します (MB 単位)。 set odps.stage.reducer.num=100; # Reduce ステージのワーカー数を調整します。
ローカルテストに合格した UDF を使用して MaxCompute の OSS 外部テーブルにアクセスするとメモリ不足エラーが発生する場合、どうすれば解決できますか?
現象
MaxCompute の OSS 外部テーブルにアクセスする際、ローカルテストに合格した UDF がアップロード後に次のエラーを返します。
FAILED: ODPS-0123131:User defined function exception - Traceback: java.lang.OutOfMemoryError: Java heap space次のパラメーターを設定した後、実行時間は長くなりますが、エラーは解決しません。
set odps.stage.mapper.mem = 2048; set odps.stage.mapper.jvm.mem = 4096;原因
外部テーブルにオブジェクトファイルが多すぎ、テーブルがパーティション化されていないため、過剰なメモリ使用量が発生します。
解決策
より少量のデータをクエリします。
オブジェクトファイルをパーティション化して、メモリ使用量を削減します。
OSS 外部テーブルを使用して複数の小さなファイルを 1 つのファイルにマージするにはどうすればよいですか?
Logview ログをチェックして、SQL 実行計画の最後のステージが Reducer または Joiner であるかどうかを確認します。
Reducer の場合は、
set odps.stage.reducer.num=1;という文を実行します。Joiner の場合は、
set odps.stage.joiner.num=1;という文を実行します。
OSS 外部テーブルを読み取る際に「Couldn't connect to server」エラーを解決するにはどうすればよいですか?
現象
OSS 外部テーブルからデータを読み取る際に、
ODPS-0123131:User defined function exception - common/io/oss/oss_client.cpp(95): OSSRequestException: req_id: , http status code: -998, error code: HttpIoError, message: Couldn't connect to serverというエラーが報告されます。原因
原因 1: OSS 外部テーブルを作成する際、oss_location アドレスの
oss_endpointが内部エンドポイントではなくパブリックエンドポイントを使用していました。原因 2: OSS 外部テーブルを作成する際、oss_location アドレスの
oss_endpointが別のリージョンのエンドポイントを使用していました。
解決策
原因 1 の場合:
OSS 外部テーブルの CREATE TABLE 文の oss_location パラメーターの
oss_endpointが内部ネットワークアドレスであるかどうかを確認します。パブリックネットワークアドレスの場合は、内部ネットワークアドレスに変更する必要があります。パラメーターの詳細については、「パラメーターの説明」セクションをご参照ください。たとえば、インドネシア (ジャカルタ) リージョンのユーザーがアドレス
oss://oss-ap-southeast-5.aliyuncs.com/<bucket>/....を使用して外部テーブルを作成した場合、対応する内部アドレスoss://oss-ap-southeast-5-internal.aliyuncs.com/<bucket>/....に変更する必要があります。原因 2 の場合:
OSS 外部テーブルの `CREATE TABLE` 文の `oss_location` パラメーターの `oss_endpoint` が、アクセスしたいリージョンのエンドポイントであることを確認します。OSS クラシックネットワークのドメイン名の詳細については、「OSS のリージョンとエンドポイント」をご参照ください。
OSS 外部テーブルを作成する際に「Network is unreachable (connect failed)」エラーを解決するにはどうすればよいですか?
現象
OSS 外部テーブルを作成する際に、
ODPS-0130071:[1,1] Semantic analysis exception - external table checking failure, error message: Cannot connect to the endpoint 'oss-cn-beijing.aliyuncs.com': Connect to bucket.oss-cn-beijing.aliyuncs.com:80 [bucket.oss-cn-beijing.aliyuncs.com] failed: Network is unreachable (connect failed)というエラーが報告されます。原因
OSS 外部テーブルを作成する際、oss_location アドレスの
oss_endpointが内部エンドポイントではなくパブリックエンドポイントを使用していました。解決策
OSS 外部テーブルの作成文の `oss_location` パラメーターの
oss_endpointが内部ネットワークアドレスであるかどうかを確認します。パブリックネットワークアドレスの場合は、内部ネットワークアドレスに変更する必要があります。パラメーターの詳細については、「パラメーターの説明」セクションをご参照ください。たとえば、中国 (北京) リージョンのユーザーがアドレス
oss://oss-cn-beijing.aliyuncs.com/<bucket>/....を使用して外部テーブルを作成した場合、対応する内部アドレスoss://oss-cn-beijing-internal.aliyuncs.com/<bucket>/....に変更する必要があります。
OSS 外部テーブルでの SQL ジョブの実行が遅い問題を解決するにはどうすればよいですか?
OSS 外部テーブル内の GZ 圧縮ファイルの読み取りが遅い
現象
OSS 内の 200 GB の GZ 圧縮ファイルをデータソースとして使用する OSS 外部テーブルからのデータ読み取りが遅い。
原因
Map ステージで計算を実行している Mapper が少なすぎるため、SQL 処理が遅くなっています。
解決策
構造化データの場合、次のパラメーターを設定して、単一の Mapper が読み取るデータ量を調整し、SQL の実行を高速化できます。
set odps.sql.mapper.split.size=256; # 各 Mapper が読み取るテーブルデータのサイズを調整します (MB 単位)。非構造化データの場合、OSS 外部テーブルのパスに OSS ファイルが 1 つしかないかどうかを確認します。1 つしかない場合、圧縮形式の非構造化データは分割できないため、Mapper は 1 つしか生成できず、処理が遅くなります。大きな OSS ファイルを、OSS 上の対応する外部テーブルパスにある小さなファイルに分割することをお勧めします。これにより、外部テーブルを読み取る際に生成される Mapper の数が増え、読み取り速度が向上します。
SDK を使用した MaxCompute 外部テーブルでのデータ検索が遅い
現象
SDK を使用して MaxCompute 外部テーブルでデータを検索するのが遅い。
解決策
外部テーブルは全表スキャンのみをサポートしており、これは遅いです。代わりに MaxCompute 内部テーブルを使用することをお勧めします。
マルチパートアップロードのシナリオで、古いデータは削除されたが新しいデータが書き込まれない問題を解決するにはどうすればよいですか?
現象
insert overwrite操作では、ジョブが失敗した場合、極端なケースで予期しない問題が発生する可能性があります。問題は、古いデータが削除されたが、新しいデータが書き込まれないことです。原因
まれなハードウェア障害またはメタデータ更新の失敗により、新しいデータが宛先テーブルに正常に書き込まれませんでした。OSS の削除操作はロールバックをサポートしていないため、削除された古いデータを回復することはできません。
解決策
既存のデータに基づいて OSS 外部テーブルを上書きする場合、たとえば
insert overwrite table T select * from table T;のように、事前に OSS データをバックアップする必要があります。ジョブが失敗した場合、バックアップしたデータを使用して OSS 外部テーブルを上書きできます。insert overwriteジョブを複数回送信できる場合は、ジョブが失敗した場合に再送信できます。