lars george hbase seminar with o'reilly oct.12 2012
DESCRIPTION
2012年10月12日 オライリー社と共催したセミナー HBase本出版イベントでのLars Georgeの資料です。TRANSCRIPT
HBASE IN JAPAN Overview, Current Status and Future
Lars George Director EMEA Services
自己紹介
• Cloudera EMEAのディレクター • 全地域におけるHadoopプロジェクトのコンサルタント
• Apacheのコミッター • HbaseとWhirr
• O’Reilly 書籍の著者 Hbase -The Definitive Guide • 日本語版も販売中!
• 連絡先 • [email protected] • @larsgeorge
日本語版も出ました!
アジェンダ
• HBaseの紹介 • プロジェクトの現状 • クラスタのサイジング
HBASEの紹介
HBaseとは?
• 分散 • 列指向 • 多次元 • 高可用性
• 高パフォーマンス • ストレージシステム
プロジェクトの目的
数十億の行 * 数百万の列 * 数千のバージョン 数千のコモディティサーバを通じ、ペタバイトのデータ量を処理
HBaseテーブル
HBaseテーブル
HBase テーブル
HBaseテーブル
HBaseテーブル
HBaseテーブル
HBaseテーブル
HBaseのテーブルとは
• テーブルは行の辞書順(アルファベット順)でソートされている • テーブルスキーマは、列ファミリを定義するのみ
• それぞれの列ファミリは、任意の列の数で構成 • それぞれの列は、任意の数のバージョンで構成 • それぞれの列は、挿入時のみに存在 • 一つの列ファミリ内の列は、一緒にソート・格納 • テーブル名を除くすべてはbyte[]
(テーブル、行、列ファミリ:列、タイムスタンプ)->値
Java API
• CRUD • get: 行全体または部分から値を引き出す (R) • put: 行の生成と更新 (CU) • delete: セル、1列、複数列または行の削除 (D)
Result get(Get get) throws IOException; void put(Put put) throws IOException; void delete(Delete delete) throws IOException;
Java API (続き)
• CRUD+SI • scan: 任意の行の数をスキャン (S) • increment: 列の値をインクリメント (I)
ResultScanner getScanner(Scan scan) throws IOException; Result increment(Increment increment) throws IOException ;
Java API (続き)
• CRUD+SI+CAS • アトミックのコンペア・アンド・スワップ (CAS)
• get、check、put操作の組み合わせ • 完全なトランザクション機能がないことを補う
その他の特徴
• I/Oを効率よく利用するバッチ操作 • プッシュダウン式に述部処理するフィルタ
• 強力なコンパレータを用いた行キーや列名のフィルタ • 圧縮アルゴリズムの選択 • ブルームフィルタと時間ベースのストアファイル選択 • アトミックな追記とputs+deletes • マルチオペレーション • サーバーサイドのカスタムコードサポート • …
プロジェクトの状況
最近のプロジェクトの状況
• HBase 0.90.x “進化した概念” • マスターの書き直し – Zookeeper を超える • 行の中でのスキャニング • アルゴリズムとデータ構造のさらなる最適化 CDH3
• HBase 0.92.x “コプロセッサ” • マルチデータセンタレプリケーション • 任意のアクセス制御 • コプロセッサ CDH4
最近のプロジェクトの状況(続)
• HBase 0.94.x “パフォーマンスリリース” • CRC読み込みの改善 • シークの最適化 • WAL圧縮 • プレフィックス圧縮(別名:ブロックエンコーディング) • アトミックな追記 • アトミック put+delete • マルチインクリメントとマルチアペンド • リージョンごとの(つまりローカルの) 複数行トランザクション • WALPlayer
CDH4.x (間もなくリリース)
• HBase 0.96.x “特異性” • Protobuf RPC
• ローリングアップグレード • 複数バージョンのアクセス
• Metrics V2 • プレビュー技術
• スナップショット • PrefixTrieブロックエンコーディング
CDH5 ?
最近のプロジェクトの状況(続)
クラスタのサイジング
リソースの競合
• 読み込み・書き出しで同じ低レベルリソースを奪い合う
• ディスク (HDFS) とネットワークI/O • RPCハンドラとスレッド
• そのほか、完全に別々のコードパスを実行
メモリの共有
• デフォルトでは、各リージョンサーバは(与えられる最大量の)メモリを次のように割り当てる • 40%をインメモリストア (write ops) • 20%をブロックキャッシング (reads ops) • 残りの領域(ここでは40%)を、オブジェクトなど一般的な
Java heapの利用にあてる • メモリの共有には微調整が必要
Reads
• リージョンサーバの適切な配置とリクエストの配分 • より高速な検索のためのクライアントのキャッシュ情報 • クライアントはより高速なルックアップのため情報を
キャッシュする➜ 高速ウォームアップのための先読みオプションを考慮
• 可能ならば、時間の範囲指定かブルームフィルタを利用してストアファイルを削除
• ブロックキャッシュを試し、もしブロックが見つからなければディスクから読み込む
ブロックキャッシュ
• ブロックキャッシュの有効性を確認するため、出力しているメトリクスを使用 • ヒット率と同時に、排除率を満たしているか
確認 ➜ ランダムリードは理想的ではない • 必要に応じて増減させて微調整するが、ヒープ
の全体的な使用量を監視すること • ブロックキャッシュは絶対に必要
• 短時間でのメリットがあるので、少なくとも10%に設定
書き込み
• クラスタサイズは、書き込みパフォーマンスによって決定されることが多い
• Log structured merge tree ベース • 変更処理をインメモリストアと先行書き込みログ
(WAL)の両方に格納 • 負荷が高いとき、一定のしきい値に基づき集約さ
れたソートマップをフラッシュする • ペンディング状態の変更がないログは破棄
• ストアファイルの定期的なコンパクションを実行
書き込みのパフォーマンス
• クラスタ全体の書き込みパフォーマンスにある多数のファクター
• クラスタ全体の書き込みパフォーマンスに影響する様々な要因 • キーの分散 ➜ リージョンのホットスポットを回避 • ハンドラ ➜ すぐに枯渇しないようにする • 先行書き込みログ ➜ 第一のボトルネック • コンパクション ➜ 間違ったチューニングは、増加し続け
るバックグラウンドノイズの原因に
先行書き込みログ(WAL)
• 現在のところ、リージョンサーバに1つ • 全ストア(列ファミリ)間で共有 • ファイル追記の呼び出しで同期
• 次のようなことを緩和するために実行 • WALの負荷軽減のため以下の機能を追加
• WAL圧縮 • リージョンサーバにつき複数のWAL ➜ ノードごとに複数
のリージョンサーバを起動する?
• デフォルトのブロックサイズの95%にサイズ設定 • 64MB または 128MB、configを確認!
• 復旧時間を削減するため、低い数字を保持 • リミットは32まで、増加させることは可能
• ログサイズを大きくするとともにブロッキング前のログの数を増やす(あるいはどちらか)
• 書き込みの分布及びフラッシュの頻度に基づき数値を計算
先行書き込みログ(WAL)-続き
• 書き込みは全ストア間で同期させる
• 1つの列ファミリに巨大なセルがあると、ほかの書き込みすべてが停止する
• この場合RPCハンドラは、動くか全てブロックされるかの二択になる
• 書き込み時にWALを回避することができるが、これは本当の耐障害性やレプリケーションを失うことを意味する
• 依存データセットをリストアするため、コプロセッサを利用することも可能かもしれない (preWALRestore)
先行書き込みログ(WAL)-続き
フラッシュ
• すべての変更のための呼び出し(put、deleteなど)は、フラッシュのチェックの原因になる
• しきい値に達したら、ディスクへのフラッシュとコンパクションのスケジューリングを行う • 新たにフラッシュされたファイルは、迅速に圧縮すること
• コンパクションは、必要ならリージョンを分割すべき場所に返っていく
コンパクションストーム
• ログの数が多すぎる、あるいはメモリ使用量が逼迫することにより早過ぎるフラッシュが発生する • ファイルは設定されたフラッシュサイズより小さくなる
• バックグラウンドでコンパクションを行い、小さいフラッシュを大きなストアファイルにマージするのは大変 • 数百MBのリライトを何度も実行
依存関係
• たった1つのトリガーがあれば、フラッシュは全ストア/列ファミリ間で起こる
• フラッシュサイズは、結合されている全ストアサイズと比較する • 多くの列ファミリはサイズが小さい • 例: 55MB + 5MB + 4MB
数値について
• 一般的なHDFSの書き込みパフォーマンスは 35-50MB/秒
Cell Size OPS 0.5MB 70-100
100KB 350-500
10KB 3500-5000 ??
1KB 35000-50000 ????
競争こそ、実際に高みに至る道!
もう少し数字を書く
• 速度が低い現実の状況下では、15MB/秒かそれ以下 • スレッドによるリソースの奪い合いは、大規模な
速度低下の原因になる
Cell Size OPS 0.5MB 10
100KB 100
10KB 800
1KB 6000
注釈
• リージョンXのフラッシュサイズに基づき、memstoreサイズを計算
• フィルおよびフラッシュの比率に基づき、保存するログの数を計算
• 最終的に、容量は次で決定される • Java Heap • リージョン数とサイズ • キーの分散
Cheat Sheet #1
• 先行書き込みログの実行に十分以上の性能があることを確認
• 利用できるメムストア領域の許容範囲を超えてクライアントが利用しないことを確認
• フラッシュサイズを大きく設定してもいいが、大き過ぎないことを確認
• 先行書き込みログの使用状況を注意して監視
Cheat Sheet #2
• 1ノードにつき、より多くのデータを格納できるよう圧縮を有効にする
• いくつかのレベルでバックグラウンドI/Oを固定するため、コンパクションアルゴリズムを変更
• 別のテーブルに不均一のカラムファミリを置くことを考慮
• ブロックキャッシュ、メムストアやすべてのキューのメトリクスを慎重にチェック
例
• 10GBのJava Xmx heap • メムストアは40%使う(デフォルト)
• 10GB Heap x 0.4 = 4GB
• 推奨するフラッシュサイズは128MB • 4GB / 128MB = 最大 32 リージョン!
• WALサイズは 128MB x 0.95%
• 4GB / (128MB x 0.95) = ~33 部分的にコミットできないログの最大保持量
• 20GBのリージョンサイズ
• 20GB x 32リージョン = 640GBの生ストレージを使用
41
ご清聴いただきまして、 まことにありがとうございました
cloudera.com +1 (3) 6228-7930
twi1er.com/ cloudera
facebook.com/ cloudera
Thank You!