在 DynamoDB 中匯出、匯入和查詢資料的 Hive 命令範例 - Amazon EMR

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 DynamoDB 中匯出、匯入和查詢資料的 Hive 命令範例

下列範例使用 Hive 命令來執行操作,例如將資料匯出至 Amazon S3 或 HDFS、將資料匯入 DynamoDB 、聯結資料表、查詢資料表等。

Hive 資料表上的操作會參考儲存在 DynamoDB 中的資料。Hive 命令需遵守 DynamoDB 資料表的佈建輸送量設定,而其擷取的資料將包含 DynamoDB 在處理 Hive 操作請求時寫入 DynamoDB 資料表的資料。如果資料擷取程序花費的時間較長,Hive 命令傳回的部分資料可能會在 Hive 命令開始後又已於 DynamoDB 內更新。

Hive 命令 DROP TABLECREATE TABLE 僅對 Hive 中的本機資料表有效,因此無法在 DynamoDB 中建立或捨棄資料表。如果您的 Hive 查詢參考的是 DynamoDB 內的資料表,該資料表在您執行查詢前必須已經存在。如需有關在 DynamoDB 中建立和刪除資料表的詳細資訊,請參閱《Amazon DynamoDB 開發人員指南》中的使用 DynamoDB 中的資料表

注意

當您將 Hive 資料表映射至 Amazon S3 中的位置時,請勿將其映射至儲存貯體 s3://amzn-s3-demo-bucket 的根路徑,因為當 Hive 將資料寫入 Amazon S3 時,可能會導致錯誤。而是將資料表對應至儲存貯體的子路徑 s3://amzn-s3-demo-bucket/mypath。

從 DynamoDB 匯出資料

您可以使用 Hive 從 DynamoDB 匯出資料。

將 DynamoDB 資料表匯出至 Amazon S3 儲存貯體
  • 請建立用於參考儲存在 DynamoDB 中的資料的 Hive 資料表。然後,您可以呼叫 INSERTOVERWRITE命令,將資料寫入外部目錄。在下列範例中,s3://bucketname/path/subpath/ 是 Amazon S3 中的有效路徑。調整CREATE命令中的資料欄和資料類型,以符合 DynamoDB 中的值。您可以使用此方法在 Amazon S3 中建立 DynamoDB 資料的存檔。

    CREATE EXTERNAL TABLE hiveTableName (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"); INSERT OVERWRITE DIRECTORY 's3://bucketname/path/subpath/' SELECT * FROM hiveTableName;
使用格式化將 DynamoDB 資料表匯出至 Amazon S3 儲存貯體
  • 建立用於參考 Amazon S3 中的位置的外部資料表。於下方顯示為 s3_export。在CREATE通話期間,指定資料表的資料列格式。然後,當您使用 INSERT OVERWRITE 將資料從 DynamoDB 匯出到 s3_export 時,資料會以指定的格式寫入。在下列範例中,資料會以逗號分隔值 () 形式寫入CSV。

    CREATE EXTERNAL TABLE hiveTableName (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"); CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE s3_export SELECT * FROM hiveTableName;
將 DynamoDB 資料表匯出至 Amazon S3 儲存貯體而不指定資料欄映射
  • 請建立用於參考儲存在 DynamoDB 中的資料的 Hive 資料表。與前述的範例類似,只是不用指定欄位的映射。此資料表必須僅有 map<string, string> 類型的一欄。如果您隨後在 Amazon S3 中建立 EXTERNAL 資料表,即可呼叫 INSERT OVERWRITE 命令,將資料從 DynamoDB 寫入至 Amazon S3。您可以使用此方法在 Amazon S3 中建立 DynamoDB 資料的存檔。由於並未映射欄位,您無法查詢以此方式匯出的資料表。無需指定資料欄映射即可在 Hive 0.8.1.5 或更新版本中使用匯出資料,Amazon EMR AMI 2.2.x 和更新版本支援此功能。

    CREATE EXTERNAL TABLE hiveTableName (item map<string,string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1"); CREATE EXTERNAL TABLE s3TableName (item map<string, string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE s3TableName SELECT * FROM hiveTableName;
使用資料壓縮將 DynamoDB 資料表匯出至 Amazon S3 儲存貯體
  • Hive 提供了多種壓縮轉碼器,您可以在 Hive 工作階段期間設定。如此會將匯出的資料以指定格式壓縮。下列範例使用 (LZO) Lempel-Ziv-Oberhumer演算法壓縮匯出的檔案。

    SET hive.exec.compress.output=true; SET io.seqfile.compression.type=BLOCK; SET mapred.output.compression.codec = com.hadoop.compression.lzo.LzopCodec; CREATE EXTERNAL TABLE hiveTableName (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"); CREATE EXTERNAL TABLE lzo_compression_table (line STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE lzo_compression_table SELECT * FROM hiveTableName;

    可用的壓縮轉碼器為:

    • org.apache.hadoop.io.compress。GzipCodec

    • org.apache.hadoop.io.compress。DefaultCodec

    • com.hadoop.compression.lzo。LzoCodec

    • com.hadoop.compression.lzo。LzopCodec

    • org.apache.hadoop.io.compress。BZip2Codec

    • org.apache.hadoop.io.compress。SnappyCodec

將 DynamoDB 資料表匯出至 HDFS
  • 使用下列 Hive 命令,其中 hdfs:///directoryName 是有效的HDFS路徑,且 hiveTableName 是 Hive 中參考 DynamoDB 的資料表。此匯出操作比將 DynamoDB 資料表匯出至 Amazon S3 更快,因為 Hive 0.7.1.1 會在將資料匯出至 Amazon S3 時使用 HDFS作為中繼步驟。以下範例也說明了如何將 dynamodb.throughput.read.percent 設為 1.0,以提高讀取請求率。

    CREATE EXTERNAL TABLE hiveTableName (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"); SET dynamodb.throughput.read.percent=1.0; INSERT OVERWRITE DIRECTORY 'hdfs:///directoryName' SELECT * FROM hiveTableName;

    您也可以HDFS使用上述格式和壓縮將資料匯出至 ,以匯出至 Amazon S3。若要這麼做,只需將上述範例中的 Amazon S3 目錄取代為HDFS目錄即可。

在 Hive 中讀取不可列印的 UTF-8 字元資料
  • 您可以在建立資料表時使用 STORED AS SEQUENCEFILE子句,透過 Hive 讀取和寫入不可列印的 UTF-8 字元資料。 SequenceFile 是 Hadoop 二進位檔案格式;您需要使用 Hadoop 來讀取此檔案。下列範例顯示如何將資料從 DynamoDB 匯出到 Amazon S3。您可以使用此功能來處理無法列印的 UTF-8 編碼字元。

    CREATE EXTERNAL TABLE hiveTableName (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"); CREATE EXTERNAL TABLE s3_export(a_col string, b_col bigint, c_col array<string>) STORED AS SEQUENCEFILE LOCATION 's3://bucketname/path/subpath/'; INSERT OVERWRITE TABLE s3_export SELECT * FROM hiveTableName;

將資料匯入 DynamoDB

在使用 Hive 將資料寫入 DynamoDB 時,您應確保寫入容量單位數大於叢集中的映射器數量。例如,在 m1.xlarge EC2執行個體上執行的叢集每個執行個體會產生 8 個映射器。而含有 10 個執行個體的叢集,則代表總共會有 80 個映射器。如果您寫入容量單位未超過叢集中的映射器數量,Hive 寫入操作可能會耗用所有寫入輸送量,或企圖使用比所佈建的量更多的輸送量。如需每個EC2執行個體類型產生的映射器數量的詳細資訊,請參閱 設定 Hadoop

Hadoop 中的映射器數量會受到輸入分割的控制。若輸入分割的數量過少,則您的寫入命令可能會無法使用資料表中所有可用的寫入輸送量。

如果目標 DynamoDB 資料表中已存在具有相同金鑰的項目,則會覆寫此項目。如果目標 DynamoDB 資料表中不存在具有金鑰的項目,則會插入此項目。

將資料表從 Amazon S3 匯入 DynamoDB
  • 您可以使用 Amazon EMR(Amazon EMR) 和 Hive 將資料從 Amazon S3 寫入 DynamoDB 。

    CREATE EXTERNAL TABLE s3_import(a_col string, b_col bigint, c_col array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://bucketname/path/subpath/'; CREATE EXTERNAL TABLE hiveTableName (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"); INSERT OVERWRITE TABLE hiveTableName SELECT * FROM s3_import;
將資料表從 Amazon S3 儲存貯體匯入 DynamoDB 而不指定資料欄映射
  • 請建立一個 EXTERNAL 資料表,用於參考先前從 DynamoDB 匯出並儲存在 Amazon S3 中的資料。在開始匯入前,確保 DynamoDB 中已有該資料表,且其具備的索引鍵結構描述與先前匯出的 DynamoDB 資料表相同。此外,該資料表僅能有 map<string, string> 類型的一欄。如果您隨後建立了連結到 DynamoDB 的 Hive 資料表,即可呼叫 INSERT OVERWRITE 命令,將資料從 Amazon S3 寫入至 DynamoDB。由於並未映射欄位,您無法查詢以此方式匯入的資料表。Hive 0.8.1.5 或更新版本中提供了未指定資料欄映射的匯入資料,Amazon EMR AMI 2.2.3 和更新版本支援此資料。

    CREATE EXTERNAL TABLE s3TableName (item map<string, string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' LOCATION 's3://bucketname/path/subpath/'; CREATE EXTERNAL TABLE hiveTableName (item map<string,string>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "dynamodbtable1"); INSERT OVERWRITE TABLE hiveTableName SELECT * FROM s3TableName;
將資料表從 匯入 HDFS DynamoDB
  • 您可以使用 Amazon EMR和 Hive 將資料從 HDFS 寫入 DynamoDB 。

    CREATE EXTERNAL TABLE hdfs_import(a_col string, b_col bigint, c_col array<string>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 'hdfs:///directoryName'; CREATE EXTERNAL TABLE hiveTableName (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"); INSERT OVERWRITE TABLE hiveTableName SELECT * FROM hdfs_import;

查詢 DynamoDB 中的資料

下列範例顯示您可以使用 Amazon EMR查詢儲存在 DynamoDB 中的資料的各種方式。

尋找映射欄 (max) 中的最大值
  • 請使用 Hive 命令,如下所示。在第一個命令中,CREATE陳述式會建立 Hive 資料表,以參考儲存在 DynamoDB 中的資料。然後,陳述SELECT式會使用該資料表來查詢儲存在 DynamoDB 中的資料。以下範例會尋找指定客戶所下的最大訂單。

    CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "Purchases", "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items"); SELECT max(total_cost) from hive_purchases where customerId = 717;
使用 GROUP BY 子句彙總資料
  • 您可以使用 GROUP BY 子句跨多筆記錄收集資料。這通常會用於 sum、count、min 或 max 等彙總函數。下方範例會以購買三次以上的客戶為主,傳回最大訂單清單。

    CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "Purchases", "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items"); SELECT customerId, max(total_cost) from hive_purchases GROUP BY customerId HAVING count(*) > 3;
聯結兩個 DynamoDB 資料表
  • 下列範例會將兩個 Hive 資料表映射至儲存在 DynamoDB 中的資料。然後會呼叫這兩個資料表的聯結。聯結會在叢集上運算並傳回。聯結不會在 DynamoDB 中發生。此範例會傳回下訂兩筆以上訂單的客戶和其購買項目的清單。

    CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "Purchases", "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items"); CREATE EXTERNAL TABLE hive_customers(customerId bigint, customerName string, customerAddress array<String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "Customers", "dynamodb.column.mapping" = "customerId:CustomerId,customerName:Name,customerAddress:Address"); Select c.customerId, c.customerName, count(*) as count from hive_customers c JOIN hive_purchases p ON c.customerId=p.customerId GROUP BY c.customerId, c.customerName HAVING count > 2;
聯節來自不同來源的兩個資料表
  • 在下列範例中,Customer_S3 是 Hive 資料表,可載入存放在 Amazon S3 中的CSV檔案,而 hive_purchases 則是參考 DynamoDB 中資料的資料表。下列範例將存放在 Amazon S3 CSV中的客戶資料與存放在 DynamoDB 中的訂單資料聯結在一起,以傳回一組代表客戶以其名稱「Miller」下達的訂單的資料。

    CREATE EXTERNAL TABLE hive_purchases(customerId bigint, total_cost double, items_purchased array<String>) STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' TBLPROPERTIES ("dynamodb.table.name" = "Purchases", "dynamodb.column.mapping" = "customerId:CustomerId,total_cost:Cost,items_purchased:Items"); CREATE EXTERNAL TABLE Customer_S3(customerId bigint, customerName string, customerAddress array<String>) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION 's3://bucketname/path/subpath/'; Select c.customerId, c.customerName, c.customerAddress from Customer_S3 c JOIN hive_purchases p ON c.customerid=p.customerid where c.customerName like '%Miller%';
注意

在上述範例中,為了清楚和完整起見,每個範例中都包含這些CREATETABLE陳述式。針對指定的 Hive 資料表執行多向查詢或匯出操作時,僅需在 Hive 工作階段開始時建立一次資料表。