独断と偏見で選ぶHDFSのファイル形式
HDFSのファイル形式を何にすべきか、というのはRPGの主人公の名前を何にすべきか、と同じぐらい皆さん悩まれるかと思います。
ご多分に漏れず僕も悩みましたので、調べた事をまとめておきます。 なお先に結論だけ言っておきますと、大体のケースではORCをZlib圧縮して使っておけば良いんじゃないかなと考えています。マサカリは歓迎です。
※201701/21追記 EMR5.0以降ではHive + ORCで遅くなるケースがあるとのアドバイスをAWSのサポートの方から伺いました。EMRを使っている方はParquetとの速度比較をしてみたほうが良いかもしれません。
ファイル形式の候補
ファイル形式の候補としては大体以下が挙げられます。
各形式の特徴
それぞれのファイル形式の詳細な説明はここではせず、簡単な特徴だけ記します。なお、以下のサイトを参考にさせていただきました。
How to Choose a Data Format - Silicon Valley Data Science
hadoop - Parquet vs ORC vs ORC with Snappy - Stack Overflow
Mostafa Elzoghbi: Avro vs Parquet vs ORCFile as Hadoop storage files
ORCとParquetは共にカラムナー型でデータを保存でき、クエリの最適化に優れている。 また、圧縮効率も共に高い。
- ORCはrow Indexやbloom filterが使えるので基本的にはORCの方が良い。ただしネストが深いデータ構造の場合はParquetの方が良い。
- ImpalaはORCをサポートしていない
Apache Avroはカラム追加・削除・複数カラムのリネームまでサポートしておりカラム構造の変更に強い。
SequenceFileはMapReduceのジョブに最適化されている。
TextFileは書き込みが早く、人の目で確認できるので管理しやすい。
ユースケースごとの使い分け
上記の特徴を考えると、ユースケースごとの使い分けとしては以下のようになります。
- 単純にクエリを最適化したいならORC
- ネストが深いデータ構造の場合やImpala使うならParquet
- カラム変更に強くしたいならAvro
- MapReduceジョブ最適化ならSequence
- 読み込みのパフォーマンスがどうでも良いならText
ORCのファイル圧縮形式
HDFS上のファイルは圧縮する事で容量が減り、処理も効率的になる事が多いです。
ORCでは圧縮形式としてSnappyかZlibを選べます。昔は圧縮効率ならZlib、書き込み効率ならSnappyという住み分けだったらしいですが、2015年あたりにZlibのアルゴリズムが新しくなってからは書き込み効率にそこまで差が無くなったので無条件でZlibで良いかと思います。
※実際100Gb程度のファイルでSnappyとZlibで書き込み速度を比較した際はほとんど差がありませんでした
参考 Snappy vs. Zlib - Pros and Cons for each compression in Hive/ Orc files - Hortonworks
ORC: 2015 Faster, Better, Smaller
まとめ
Hadoopを使いたいときは大体HiveやPrestoなどのクエリエンジンとセットで使うと思うので、基本的にはZlib+ORCで良いと思います!なおORCフォーマットの性能を活かしきるには設定値やデータ投入時に少し工夫が必要だと思っていますが、それは次回の記事で書こうと思います。