昨年末に公開された Impala Cookbook、先日新しいバージョンに更新されました。昨年末も雑記を書きましたが、改めて読み直し、日本語でまとめてみました。
駆け足で日本語化したので、間違いがあればコメントに書き込むかTwitterでメンションしてください。
本当はスライド全部を日本語化したいところですが、71ページはチト面倒なのでどうしようか悩む。。
原文:
[1] The Impala Cookbook http://www.slideshare.net/cloudera/the-impala-cookbook-42530186
The Impala Cookbook
概要
- Part 1 - 基本
- 物理設計とスキーマ設計
- Impalaでのメモリ使用量
- Part 2 - 実用上の問題
- クラスタのサイジングと推奨ハードウェア
- Impalaでのベンチマーク
- マルチテナントのベストプラクティス
- クエリのチューニングの基本
- Part 3 - Impalaの外部
- Apache Hive, Apache Sentry, Apache Parquetとのやり取り
物理設計とスキーマ設計
物理設計とスキーマ設計 - 概要
- スキーマ設計のベストプラクティス
- データ型
- パーティション設計
- 一般的な質問
- 物理設計
- ファイルフォーマット: いつ何を使うか
- ブロックサイズ(オプション)
物理設計とスキーマ設計 - データ型
- 数値(Numeric)型を使用する(Stringではなく)
- 可能であればString型を避ける
- String => 多くのメモリ消費、多くのディスク領域、計算の遅さ
- Decimal vs Float/Double
- Decimalは容易
- 現在、DecimalはパーティションのキーまたはUDFで使用できない
- Stringは以下の場合のみに使用する:
- HBaseの行キー - 文字列が推奨される型
- タイムスタンプ - 文字列を使うのはOKだが、同様にNumericを使うことも考慮すること!
パーティション設計: 3つのシンプルなルール
- ユースケース、または既存のSQLからアクセスパターンを確認
- 合計パーティション数を見積もる (100k(100000)以下が最適!)
- (オプション)必要であればパーティション数を削減
パーティション設計: アクセスパターンを確認
- WHERE句で一般的に使用されるテーブルの列がパーティションキーの候補
- 日付はたいていの場合に一般的なアクセスパターンであり、最も一般的なパーティションキー
- 複数のパーティションキーを持つことができる!例:
- Select col_1 from store_sales where sold_date between '2014-01-31' and '2016-02-23'
- Select count(revenue) from store_sales where store_group_id in (1,5,10);
- パーティションキー => sold_date, store_group_id
パーティション設計: パーティション数を見積もる
- (必要となるストレージの存続期間のため)各パーティションキー用にNDV(number of distinct values: 明白な数)を推定する。例:
- パーティションが日付で1年分を保存する必要がある場合、日付パーティションキー用のNDVは365になる
- store_groupの数はやがて増えていくが、52を超えることはない(各州にひとつ)
- パーティションの合計数 = パーティションキー1用のNDV * パーティションキー用のNDV * ....* パーティションキー N 用のNDV。例:
- 合計パーティション数 = 365 (日付用パーティション) * 52 (store_group用) ~= 19k (19000)
- パーティション数 <= 100k であることを確認する!
パーティション設計: パーティションが多すぎる?
- いくつかの「重要でない」パーティションキーを削除する
- パーティションキーが決まって使用されない場合、あるいはSLAのインパクトがない場合、削除する!
- パーティションの「bucket」を作成する
- 日付ではなく月を使用する
- 個別の店舗をグループ化するために、人為的なstore_groupを作成する
- テクニック: 接頭子またはハッシュを使用する
- Hash (store_id) % store_group_size => store_groupのためにハッシュする
- Substring(store_id,0,2) => 人為的なstore_groupとして最初の2つの数字を使用
スキーマ設計 - 一般的な問題
- 列の数 - 最大 2k (2000)
- ハードリミットではない: ImpalaとParquetはさらにいっそう扱うことができる、が....
- Hive Metastoreのメタデータ更新と復旧がスローダウンする
- タイムスタンプ
- HiveのParquetはまだタイムスタンプをサポートしていない
- BIGINT (より効率的)または String (可読性が高い)のどちらかを使用する
- BLOB/CLOB - 文字列を使用する
- HiveのParquetはまだタイムスタンプをサポートしていない
- 決定的な上限はないが、1MBは大丈夫と思われる
- 大きなサイズの文字列はImpalaをクラッシュさせうる!
- 慎重に使用する - 全体が1MBの文字列はどこにでも積み込まれる
物理設計 - ファイルフォーマット
- Parquet/Snappy
- 長期間のストレージフォーマット
- いつも可読性が良い
- 書き込みは非常に遅い(Avroよりも10倍遅いとレポートされている)
- Snappy vs Gzip
- Snappyは通常圧縮率とCPU間における良好なトレードオフ
- しかし、確認のためにはあなた自身のベンチマークを実行すること!
- 書き込み一回、読み込み一回の一時的なETLテーブルには、SequenceFile/Snappyを考慮する。なぜなら:
- 書き込みが早い
- Impalaが書き込める
物理設計 - ブロックサイズ
- ブロック数は並列性の度合いを決める
- MapReduceとImpalaの両方に当てはまる
- 各ブロックはひとつのCPUコアで処理される
- クラスタ全体で全てのCPUコアを利用するためには、ブロック数 >= コア数
- 大きなブロックサイズ
- 良好なIOスループット、しかし少数のブロックは並列性が下がる
- 小さなブロックサイズ
- 多くの並列性だが、IOのスループットが下がる
物理設計 - ブロックサイズ
- Apache Parquetでは300MB以上が良好であり、1GB以上にする必要はない
- 64MB以下にしないように!
- (高度)本当にブロックサイズを確認したい場合、以下の方程式を使用する:
- ブロックサイズ <= p* t* c / s
- p - 100MB/secでのディスクスキャンレート
- t - 要求されるクエリのレスポンス時間を秒で
- c - 並列性
- s - 選択された列の割合(%)
- ブロックサイズ <= p* t* c / s
コメント