Impala Cookbook (非公式)日本語版 (1) 物理設計とスキーマ設計

昨年末に公開された 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 – 文字列を使用する
  • 決定的な上限はないが、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 – 選択された列の割合(%)

 
 

コメント