Hive コマンドを実行するように Hive テーブルをセットアップする - Amazon EMR

Hive コマンドを実行するように Hive テーブルをセットアップする

Apache Hive は、SQL のような言語を使用して、Amazon EMR クラスターに含まれるデータに対してクエリを実行する際に使用できるデータウェアハウスアプリケーションです。Hive の詳細については、http://hive.apache.org/ を参照してください。

次の手順は、既にクラスターを作成し、Amazon EC2 キーペアを指定したことを前提にしています。クラスターの作成を開始する方法については、「Amazon EMR 管理ガイド」の「Amazon EMR の開始方法」を参照してください。

MapReduce を使用するように Hive を設定する

Amazon EMR で Hive を使用して DynamoDB テーブルに対してクエリを実行する場合、デフォルトの実行エンジンである Tez を Hive が使用していると、エラーが発生する可能性があります。このため、このセクションで説明しているように、DynamoDB と統合される Hive でクラスターを作成するときには、MapReduce を使用するように Hive を設定する設定分類を使用することをお勧めします。詳細については、「アプリケーションの設定」を参照してください。

次のスニペットは、Hive の実行エンジンとして MapReduce を設定するために使用する分類設定とプロパティを示しています。

[ { "Classification": "hive-site", "Properties": { "hive.execution.engine": "mr" } } ]
Hive コマンドをインタラクティブに実行するには
  1. マスターノードに接続します。詳細については、「Amazon EMR 管理ガイド」の「SSH を使用してマスターノードに接続する」を参照してください。

  2. 現在のマスターノードの コマンドプロンプトで、hive と入力します。

    hive> という Hive プロンプトが表示されます。

  3. Hive アプリケーションのテーブルを DynamoDB のデータにマップする Hive コマンドを入力します。このテーブルは、Amazon DynamoDB に格納されているデータの参照として機能します。データは Hive のローカルに保存されておらず、このテーブルを使用するクエリは、DynamoDB 内のライブデータに対して実行されます。また、コマンドを実行するたびに、テーブルの読み取り容量と書き込み容量が消費されます。同じデータセットに対して複数の Hive コマンドを実行する予定がある場合は、まずエクスポートすることをお勧めします。

    次に、Hive テーブルを DynamoDB テーブルにマッピングする構文を示します。

    CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...");

    DynamoDB から Hive にテーブルを作成する場合、EXTERNAL というキーワードを使用して外部テーブルとして作成する必要があります。外部テーブルと内部テーブルの違いは、内部テーブルの drop が実行されると内部テーブルのデータが削除される点です。Amazon DynamoDB に接続する場合、この動作は望ましくないため、外部テーブルのみがサポートされます。

    たとえば、次の Hive コマンドでは、dynamodbtable1 という DynamoDB テーブルを参照する hivetable1 というテーブルが Hive に作成されます。DynamoDB テーブル dynamodbtable1 には、ハッシュおよび範囲プライマリキースキーマがあります。ハッシュキー要素は name(文字列型)、範囲キー要素は year(数値型)です。各項目には、holidays(文字列セット型)の属性値があります。

    CREATE EXTERNAL TABLE hivetable1 (col1 string, col2 bigint, col3 array<string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1", "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays");

    行 1 では、HiveQL CREATE EXTERNAL TABLE ステートメントを使用しています。hivetable1 の場合、DynamoDB テーブルの属性名と値の各ペアについて、列を設定し、データ型を指定する必要があります。これらの値は大文字と小文字が区別されません。列には、(予約語を除き)任意の名前を付けることができます。

    行 2 では、STORED BY ステートメントを使用しています。STORED BY の値は、Hive と DynamoDB 間の接続を処理するクラス名です。'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' のように設定する必要があります。

    行 3 では、TBLPROPERTIES ステートメントを使用して、"hivetable1" を DynamoDB 内の正しいテーブルとスキーマに関連付けています。TBLPROPERTIES に、dynamodb.table.name パラメータと dynamodb.column.mapping パラメータの値を指定します。これらの値は、大文字と小文字が区別されます

    注記

    テーブルのすべての DynamoDB 属性名には、Hive テーブルに対応する列が存在する必要があります。Amazon EMR のバージョンに応じて、1 対 1 のマッピングが存在しない場合は、次のシナリオが発生します。

    • Amazon EMR のバージョン 5.27.0 以降では、コネクターは、DynamoDB の属性名と Hive テーブル内の列間で 1 対 1 のマッピングを確実にするための検証を行います。1 対 1 のマッピングが存在しない場合は、エラーが発生します。

    • Amazon EMR バージョン 5.26.0 以前では、Hive テーブルには DynamoDB からの名前と値のペアは含まれません。DynamoDB プライマリキー属性をマップしない場合、Hive からエラーが生成されます。プライマリキー以外の属性をマップしない場合、エラーは生成されませんが、Hive テーブルのデータは表示されません。データ型が一致しない場合、値は null です。

次に、hivetable1 で Hive 操作の実行を開始できます。hivetable1 に対して実行されるクエリは、DynamoDB アカウントの DynamoDB テーブル dynamodbtable1 に対して内部的に実行され、実行するたびに読み取り単位または書き込み単位が消費されます。

DynamoDB テーブルに対して Hive クエリを実行する際には、十分な量の読み込み容量単位をプロビジョニングしておく必要があります。

たとえば、DynamoDB テーブルに対して 100 ユニットの読み込みキャパシティーをプロビジョニングしているとします。この場合、1 秒間に 100 の読み込み(409,600 バイト)を実行できます。そのテーブルに 20 GB(21,474,836,480 バイト)のデータが含まれており、Hive クエリがフルテーブルスキャンを実行する場合、クエリの実行にかかる時間は次のように見積もられます。

21,474,836,480 / 409,600 = 52,429 秒 = 14.56 時間

必要な時間を短縮するには、ソース DynamoDB テーブルで読み込みキャパシティーユニットを調整する以外に方法はありません。Amazon EMR ノードを追加しても、役に立ちません。

Hive 出力では、1 つ以上のマッパープロセスが終了すると、完了のパーセンテージが更新されます。プロビジョニングされた読み込みキャパシティーが小さく設定された大きな DynamoDB テーブルでは、完了のパーセンテージ出力が長時間更新されない場合があります。上記のような場合、ジョブは数時間にわたって 0% 完了として表示されます。ジョブの進行状況の詳細なステータスについては、Amazon EMR コンソールに移動してください。ここで、個別のマッパータスクのステータスおよびデータ読み込みの統計を表示できます。また、マスターノードの Hadoop インターフェイスにログオンし、Hadoop 統計を表示することもできます。ここには、個別のマップタスクのステータスおよびいくつかのデータ読み込み統計が表示されます。詳細については、以下の各トピックを参照してください。

DynamoDB からのデータのエクスポートやインポート、テーブルの結合などのタスクを実行するその他の HiveQL ステートメントの例については、「DynamoDB 内データのエクスポート、インポート、クエリを行う Hive コマンドの使用例」を参照してください。

Hive リクエストをキャンセルするには

Hive クエリを実行すると、サーバーから返される最初の応答には、リクエストをキャンセルするコマンドが含まれます。プロセスの任意の時点でリクエストをキャンセルするには、サーバーの応答に含まれる Kill Command を使用します。

  1. Ctrl+C を入力して、コマンドラインクライアントを終了します。

  2. シェルプロンプトで、リクエストに対するサーバーからの最初の応答に含まれていた Kill Command を入力します。

    または、マスターノードのコマンドラインから次のコマンドを実行して、Hadoop ジョブをキルします。この job-id は、Hadoop ジョブの識別子であり、Hadoop ユーザーインターフェイスから取得できます。

    hadoop job -kill job-id

Hive と DynamoDB のデータ型

次の表は、使用可能な Hive データ型、対応するデフォルトの DynamoDB 型、およびそれらもマッピングできる代替 DynamoDB 型を示しています。

Hive の型 デフォルトの DynamoDB 型 代替 DynamoDB 型
string

文字列(S)

bigint または double

数値(N)

バイナリ

バイナリ(B)

ブール値

boolean (BOOL)

array list (L)

数値セット(NS)、文字列セット(SS)、またはバイナリセット(BS)

map<string,string> item

map (M)

map<string,?> map (M)
null (NULL)

Hive データを対応する代替 DynamoDB 型として書き込む場合、または DynamoDB データに代替 DynamoDB 型の属性値が含まれる場合、dynamodb.type.mapping パラメータを使用して列と DynamoDB 型を指定できます。次の例は、代替型マッピングを指定する構文を示しています。

CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...", "dynamodb.type.mapping" = "hive_column1_name:dynamodb_attribute1_datatype");

型マッピングパラメータはオプションで、代替型を使用する列に対してのみ指定する必要があります。

たとえば、次の Hive コマンドでは、DynamoDB テーブル dynamodbtable2 を参照する hivetable2 というテーブルが作成されます。これは、col3 列を文字列セット (SS) 型にマッピングする点を除いて、hivetable1 に似ています。

CREATE EXTERNAL TABLE hivetable2 (col1 string, col2 bigint, col3 array<string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable2", "dynamodb.column.mapping" = "col1:name,col2:year,col3:holidays", "dynamodb.type.mapping" = "col3:SS");

Hive では、hivetable1hivetable2 は同一です。ただし、これらのテーブルからのデータが対応する DynamoDB テーブルに書き込まれる際、dynamodbtable2 には文字列セットが含まれますが dynamodbtable1 にはリストが含まれます。

Hive null 値を DynamoDB null 型の属性として書き込む場合は、dynamodb.null.serialization パラメータを使用して実行できます。次の例は、null シリアル化を指定する構文を示しています。

CREATE EXTERNAL TABLE hive_tablename (hive_column1_name column1_datatype, hive_column2_name column2_datatype...) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodb_tablename", "dynamodb.column.mapping" = "hive_column1_name:dynamodb_attribute1_name,hive_column2_name:dynamodb_attribute2_name...", "dynamodb.null.serialization" = "true");

null シリアル化パラメータはオプションであり、指定しない場合は false に設定されます。パラメータ設定に関係なく、DynamoDB null 属性は Hive で null 値として読み取られることに注意してください。null 値を持つ Hive コレクションは、null シリアル化パラメータが true として指定されている場合にのみ DynamoDB に書き込むことができます。指定されない場合、Hive エラーが発生します。

精度の点で、Hive の bigint 型は Java の long 型と同じであり、Hive の double 型は Java の double 型と同じです。つまり、エクスポート、インポート、または参照する Hive を使用して、Hive のデータ型で使用できる精度よりも高い精度の数値データが DynamoDB に格納される場合、DynamoDB データの精度が低下したり、Hive クエリが失敗したりする可能性があります。

DynamoDB から Amazon Simple Storage Service (Amazon S3) または HDFS にバイナリ型をエクスポートすると、Base64 のエンコード文字列として格納されます。Amazon S3 または HDFS のデータを DynamoDB のバイナリ型にインポートする場合、Base64 文字列としてエンコードされます。

Hive のオプション

次の Hive オプションを設定して、Amazon DynamoDB のデータの転送を管理できます。これらのオプションは、現在の Hive セッションの間のみ、有効です。Hive コマンドプロンプトを終了した後で、クラスターでこのプロンプトを再び開いた場合、この設定はデフォルト値に戻ります。

Hive のオプション 説明
dynamodb.throughput.read.percent

DynamoDB のプロビジョニングされたスループットレートが、表の割り当てられた範囲内に収まるように、読み取りオペレーションのレートを設定します。値は 0.11.5 以内にします。

0.5 の値がデフォルトの読み取りレートです。つまり、Hive は、表に記載されている読み取りのプロビジョニングされた全体のリソースの半分を消費しようと試みます。値を 0.5 から増やすと、読み取りリクエストレートも増えます。0.5 未満に減らすと、読み取りリクエストレートも減ります。この読み取りレートは概算です。実際の読み取りレートは、DynamoDB に統一ディストリビューションのキーがあるかどうかなどの要因によって変わります。

Hive 操作によって、プロビジョニングされたスループットを頻繁に超える場合、またはライブの読み取りトラフィックがスロットリングされる回数が多い場合、この値を 0.5 未満に減らします。十分な容量があり、Hive 操作を高速にする場合は、この値を 0.5 より増やします。また、使用できる未使用の入力/出力操作があると考えられる場合、最大 1.5 に設定してオーバーサブスクライブを実行することもできます。

dynamodb.throughput.write.percent

DynamoDB のプロビジョニングされたスループットレートが、表の割り当てられた範囲内に収まるように、書き込みオペレーションのレートを設定します。値は 0.11.5 以内にします。

0.5 の値がデフォルトの書き込みレートです。つまり、Hive は、表に記載されている書き込みのプロビジョニングされた全体のリソースの半分を消費しようと試みます。値を 0.5 から増やすと、書き込みリクエストレートも増えます。0.5 未満に減らすと、書き込みリクエストレートも減ります。この書き込みレートは概算です。実際の書き込みレートは、DynamoDB に統一ディストリビューションのキーがあるかどうかなどの要因によって変わります。

Hive 操作によって、プロビジョニングされたスループットを頻繁に超える場合、またはライブの書き込みトラフィックがスロットリングされる回数が多い場合、この値を 0.5 未満に減らします。十分な容量があり、Hive 操作を高速にする場合は、この値を 0.5 より増やします。また、使用できる未使用の入力/出力操作があると考えられる場合、または、テーブルに対する最初のデータアップロードであり、ライブトラフィックがまだない場合は、最大 1.5 に設定してオーバーサブスクライブを実行することもできます。

dynamodb.endpoint

DynamoDB サービスのエンドポイントを指定します。使用できる DynamoDB エンドポイントの詳細については、「リージョンとエンドポイント」を参照してください。

dynamodb.max.map.tasks

DynamoDB からデータを読み取るときは、マップタスクの最大数を指定します。この値は、1 以上にする必要があります。

dynamodb.retry.duration

Hive コマンドの再試行のタイムアウト期間として使用する分数を指定します。この値は、0 以上の整数にする必要があります。デフォルトのタイムアウト期間は 2 分です。

これらのオプションは、次の例に示すように、SET コマンドを使用して設定されます。

SET dynamodb.throughput.read.percent=1.0; INSERT OVERWRITE TABLE s3_export SELECT * FROM hiveTableName;