CERNで実施したベンチマークが公開されています

CERNが公開した、

「Apache Hadoopエコシステムにおける、異なるファイル形式とストレージエンジンのパフォーマンス比較」

を日本語化して公開しました。

Apache Avro, Apache Parquet, Apache HBase, Apache Kuduそれぞれの特性が興味深いです。取り込み重視なのか分析重視なのか、長期保存目的か、はたまた折衷なのかによって何を選択するべきかの参考になります。

これは必読です!

 

 

RDBMSからSqoopを用いてParquet形式でデータを取り込む

Hadoop上、または SQL on Hadoopで分析を行う場合、テキストファイル(CSVやJSONなど)をそのまま使うとパフォーマンス的に不利になる場合が多いです。(ファイルから改行文字や区切り文字を探して都度都度処理をすれば、当然遅くなりますよね、、、)

Hadoopでは複数のバイナリ形式のファイルフォーマット(SequenceFile, Avroなど)が利用できるようになっていますが、対象が分析用途なら、カラムナ(列指向)フォーマットのフォーマットを利用すると効率的です。これは、バイナリ形式で保存するだけでなく、データを列単位で保存することで、必要な列に効率良くアクセスできるためです。

Apache Parquet

カラムナフォーマットとして広く使われているApache Parquet(パーケィ、と発音)は、Hadoopだけではなく、Spark、Impala等多くのエコシステムで利用できるフォーマットです。(Apache Kuduも列指向ですが、ファイルではなく、独自の形式でデータを扱います)

#Apache Parquetの説明は別の機会に

RDBMSからHadoopにデータを取り込み場合、Sqoopを使ってデータを取り込むことが一般的ですが、この際にParquetファイルとして取り込むことができます。多くのエコシステムがParquetに対応している一例ですね。

Quickstart VMを使ってHadoopに(というかHDFSに)取り込んでみましょう。



sqoop import-all-tables     -m 1     --connect jdbc:mysql://quickstart:3306/retail_db     --username=retail_dba     --password=cloudera     --compression-codec=snappy     --as-parquetfile     --warehouse-dir=/user/hive/warehouse     --hive-import

 

これだけです。

これは、RDBMS(MySQL)のretail_dbデータベースにある全てのテーブルを、 Parquet のファイルとして、HDFSの /user/hive/warehouse にインポートします。(さらに、Hiveのメタストアに登録までを行います)。-m 1 というのは並列数です。今回「1」にしているのは、Quickstart VMが1ノードの疑似分散環境だからです。

Sqoopはインポート時にMapReduceを使用し、複数のノードから分散して並列でインポートを行います。MapReduceを起動しておいてください。(また、今回はHiveのメタストアに登録も行うため、Hiveも起動しておく必要があります)

以下実行結果です。Hiveのbeelineシェルで確認してみました。

<br data-mce-bogus="1">

[cloudera@quickstart ~]$ beeline -u jdbc:hive2://quickstart:10000 -n cloudera

(略)
0: jdbc:hive2://quickstart:10000> SHOW TABLES;
INFO  : OK
+--------------+--+
|   tab_name   |
+--------------+--+
| categories   |
| customers    |
| departments  |
| order_items  |
| orders       |
| products     |
+--------------+--+
6 rows selected (0.139 seconds)
0: jdbc:hive2://quickstart:10000> SELECT COUNT(*) FROM categories;
(略)
+------+--+
| _c0  |
+------+--+
| 58   |
+------+--+
1 row selected (19.011 seconds)


Parquetファイルとして保存されていることを確認してみます。

0: jdbc:hive2://quickstart:10000>; DESCRIBE FORMATTED ORDERS;
INFO : Compiling command(queryId=hive_20161211152525_107ba790-aab1-414c-a5d3-d4a1d1b499d1): DESCRIBE FORMATTED ORDERS
INFO : Semantic Analysis Completed
INFO : Returning Hive schema: Schema(fieldSchemas:[FieldSchema(name:col_name, type:string, comment:from deserializer), FieldSchema(name:data_type, type:string, comment:from deserializer), FieldSchema(name:comment, type:string, comment:from deserializer)], properties:null)
INFO : Completed compiling command(queryId=hive_20161211152525_107ba790-aab1-414c-a5d3-d4a1d1b499d1); Time taken: 0.037 seconds
INFO : Executing command(queryId=hive_20161211152525_107ba790-aab1-414c-a5d3-d4a1d1b499d1): DESCRIBE FORMATTED ORDERS
INFO : Starting task [Stage-0:DDL] in serial mode
INFO : Completed executing command(queryId=hive_20161211152525_107ba790-aab1-414c-a5d3-d4a1d1b499d1); Time taken: 0.016 seconds
INFO : OK
+-------------------------------+-----------------------------------------------------------------+--------------------------------------------------------------------------------------+--+
| col_name | data_type | comment |
+-------------------------------+-----------------------------------------------------------------+--------------------------------------------------------------------------------------+--+
| # col_name | data_type | comment |
| | NULL | NULL |
| order_id | int | |
| order_date | bigint | |
| order_customer_id | int | |
| order_status | string | |
| | NULL | NULL |
| # Detailed Table Information | NULL | NULL |
| Database: | default | NULL |
| Owner: | null | NULL |
| CreateTime: | Sun Dec 11 15:19:11 PST 2016 | NULL |
| LastAccessTime: | UNKNOWN | NULL |
| Protect Mode: | None | NULL |
| Retention: | 0 | NULL |
| Location: | hdfs://quickstart.cloudera:8020/user/hive/warehouse/orders | NULL |
| Table Type: | MANAGED_TABLE | NULL |
| Table Parameters: | NULL | NULL |
| | COLUMN_STATS_ACCURATE | false |
| | avro.schema.url | hdfs://quickstart.cloudera:8020/user/hive/warehouse/orders/.metadata/schemas/1.avsc |
| | kite.compression.type | snappy |
| | numFiles | 0 |
| | numRows | -1 |
| | rawDataSize | -1 |
| | totalSize | 0 |
| | transient_lastDdlTime | 1481498351 |
| | NULL | NULL |
| # Storage Information | NULL | NULL |
| SerDe Library: | org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe | NULL |
| InputFormat: | org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat | NULL |
| OutputFormat: | org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat | NULL |
| Compressed: | No | NULL |
| Num Buckets: | -1 | NULL |
| Bucket Columns: | [] | NULL |
| Sort Columns: | [] | NULL |
+-------------------------------+-----------------------------------------------------------------+--------------------------------------------------------------------------------------+--+
34 rows selected (0.091 seconds)
0: jdbc:hive2://quickstart:10000>


 

 

参考情報
https://parquet.apache.org/documentation/latest/

Introducing Parquet: Efficient Columnar Storage for Apache Hadoop
http://blog.cloudera.com/blog/2013/03/introducing-parquet-columnar-storage-for-apache-hadoop/

Choosing an HDFS data storage format- Avro vs. Parquet and more – StampedeCon

Dremel made simple with Parquet
https://blog.twitter.com/2013/dremel-made-simple-with-parquet