読者です 読者をやめる 読者になる 読者になる

heki1224の適当な日記

技術知識を忘れないように書き留めておくブログ

『HBase』刊行記念 著者Lars George氏 来日特別セミナーに行ってきました

昨日、『HBase』刊行記念 著者Lars George氏 来日特別セミナーに行ってきました。

会場で書いたメモアップしておきます。
スライド丸写し&意味の取り違えなどあると思いますが
その場合はほかの方の記事参考にしてくださいませ。

セミナー

演題

HBASE IN JAPAN
Overview, Curent Status and Future

講演者

Lars George

日時

2012/10/12 19:10-19:50

自己紹介

・Cloudera EMEA Director(ドイツ)
Apacheのコミッタ
HBaseとWhirr

Agenda

・HBaseの紹介
・Projectの現状
current, future, versioning, history
クラスタのサイジング

HBaseの紹介

HBaseとは

・分散
・列指向
・多次元
・高可用性
・高パフォーマンス
・ストレージシステム
=データストア(データベースではない)

プロジェクトの目的

数十億の行、数百万の列、数千のバージョン、数千のコモディティサーバを通じ、ペタバイトのデータ量を処理
⇒初期の目的は達成した

HBaseテーブル

⇒Spreadsheetとだいたい同じ
 行と列がある
 ソート済み列
 各項目にはバージョンがある
  過去のバージョンを履歴として持つ
 カラムファミリ
  列の論理グルーピング
 リージョン
  行の論理グルーピング
 カラムファミリ、リージョンを基準として物理的に分割されて保存される。

HBaseのテーブルとは

・行の辞書順にソートされている
・テーブルスキーマはカラムファミリを定義するのみ
 それぞれのカラムファミリは任意の列の数で構成
 それぞれのカラムは、任意の数のバージョンで構成
 それぞれのカラムは挿入時のみに存在する
 ひとつの列ファミリ内の列は一緒にソート・格納
 テーブル名を除くすべてはbyte[]
  [テーブル、行、列ファミリ:列、タイムスタンプ] -> 値

Java API

CRUD
  get (R)
 put (CU)
 delete (D)
CRUD+SI
 scan:任意の行数をスキャン(S)
 increment:列の値をインクリメント(I)
CRUD+SI+CAS
 ・CAS(コンペアアンドスワップ)
・get,check,putの組み合わせ

その他の特徴

・I/Oを効率よく利用するバッチ操作
・プッシュダウン式に述部処理するフィルタ
 ・強力なコンパレータを用いた行基ーや列名のフィルタ
・圧縮アルゴリズムの選択
・ブルームフィルタと時間ベースのストアファイル選択
・アトミックな追記 puts + delete
・マルチオペレーション
・サーバサイドのカスタムコードサポート 

プロジェクトの現状

・HBase 0.90.x 進化した概念(CDH3)
 マスタ書き直し
 行の中でのスキャン具
 アルゴリズムとデータ構造の最適化

・HBase 0.92.x コプロセッサ(CDH4)
 マルチデータセンタレプリケーション
 任意のアクセス制御
 コプロセッサ
 
・HBase 0.94.x パフォーマンスリリース(CDH4.2 or 4.3-
 CRC読み込みの改善
 シークの最適化
 WAL圧縮
 プレフィックス圧縮
 アトミックな追記
 アトミック put+delete
 マルチインクリメントとマルチアベンド
 リージョンごとの複数行トランザクション
  ⇒つまりローカルでの複数行トランザクション
 WALPlayer
 
・HBase 0.96.x 特異点(CDH5?)
 Protobuf RPC
  ローリングアップグレード
  複数バージョンのアクセス
 Metrics V2
  HadoopでUpdateされたものを導入する
 プレビュー
  スナップショット(バックアップ用)
  PrefixTrieブロックエンコーディング(メモリデータ圧縮)

クラスタのサイジング

リソースの競合

・読み込み・書き出しで同じ低レベルリソースを奪い合う
・ディスク(HDFS)とネットワークI/O
 RPCハンドラとスレッド
・そのほか、完全に別々のコードバスを実行

メモリの共有

・デフォルトでは、各リージョンサーバは次のようにメモリを割り当てる
 ・40%をインメモリストア
 ・20%をブロックキャッシング
 ・残りの領域(ここでは40%)を、JavaHeapの利用にあてる
・メモリの共有には微調整が必要

Reads

・リージョンサーバの適切な配置とリクエストの配分
 ・より高速なけんさくのためのクライアントのキャッシュ情報
 ・クライアントはより高速なルックアップのため情報をキャッシュする
  ⇒高速ウォームアップのための先読みオプションを考慮
・可能ならば、時間の範囲指定かブルームフィルタを利用してストアファイルを削除
・ブロックキャッシュを試し、もしブロックが見つからなければディスクから読み込む

ブロックキャッシュ

・ブロックキャッシュの有効性をかくにんするため、出力しているメトリクスを使用
 ・ヒット率と同時に、排除率を満たしているか確認
  ⇒ランダムリードは理想的ではない
・必要に応じて増減させて微調整するが、ヒープの全体的な使用量を監視すること
・ブロックキャッシュは絶対に必要
 ・短時間でのメリットがある

書き込み

クラスタサイズは、書き込みパフォーマンスによって決定されることが多い
・Log structured merge treeベース
 ・変更処理をインメモリストアと先行書き込みログ(WAL)の両方に格納
 ・負荷が高いとき、一定の閾値に基づき集約されたソートマップをフラッシュする
 ・ペンディング状態の変更がないログは破棄
 ・ストアファイルの定期的なコンパクションを実行

書き込みのパフォーマンス

クラスタ全体の書き込みパフォーマンスにある多数のファクタ
クラスタ全体の書き込みパフォーマンスに影響する様々な要因
 ・キーの分散⇒リーションのホットスポットを回避
 ・ハンドラ⇒すぐに枯渇しないようにする
 ・先行書き込みログ⇒第一のボトルネック
 ・コンパクション⇒間違ったチューニングは、増加し続けるバックグラウンドノイズの原因に

先行書き込みログ(WAL)

・現在のところ、リージョンサーバに1つだけ ⇒ボトルネックの原因
 ・全ストア間で共有
 ・ファイル追記の呼び出しで同期
・次のようなことを緩和するために実行
・WALの負荷軽減のため以下の機能を追加 ⇒新しいバージョンで解決する
 ・WAL圧縮
 ・リージョンサーバにつき複数のWAL
  ⇒ノードごとに複数リージョンサーバを起動する?
・デフォルトのブロックサイズの95%にサイズ設定
 ・64MBまたは128MB、configを確認する
・復旧時間を削減するため、低い数字を維持
 ・リミットは32まで、増加させることは可能
・ログサイズを大きくするとともにブロッキング前のログの数を増やす(あるいはどちらか)
・書き込みの分布およびフラッシュの頻度に基づき数値を計算⇒ログファイルの数を割り出す時
・書き込みは全ストア間で同期させる
 ・1つの列ファミリに巨大なセルがあると、ほかの書き込みすべてが停止する
 ・この場合RPCハンドラは、動くか全てブロックされるかの二択になる
・書き込み時にWALを回避する事ができるが、これは本当の耐障害性やレプリケーションを失う事を意味する⇒勧めない
・依存データセットをリストアするため、コプロセッサを利用することも可能かもしれない(preWALRestore)

フラッシュ

・すべての変更のための呼び出しはフラッシュのチェックの原因になる
・閾値に達したら、ディスクへのフラッシュとコンパクションのスケジューリングを行う
・コンパクションは、必要ならリージョンを分割すべき判断がはいる

コンパクションストーム

・ログの数が多すぎる、あるいはメモリ使用量が逼迫することにより早すぎるフラッシュが発生する
・バックグラウンドでコンパクションを行い、小さいフラッシュを大きなストアファイルにマージするのは大変
 ・数百MBのリライトを何度も実行

依存関係

・たった一つのトリガーがあれば、フラッシュは全ストア・列ファミリ間で起こる
・フラッシュサイズは、結合されている全ストアサイズが基準となる。
・列ファミリが小さすぎてもフラッシュが起こる
 ・多くの列ファミリはサイズが小さい

数値について

・一般的なHDFSの書き込みパフォーマンスは、35-50MB/秒
・速度が低い状況下では15MB/秒かそれ以下
 ・スレッドによるリソースの奪い合いは、大規模な速度低下の原因になる

appendix

・リージョンXのフラッシュサイズに基づき、memstoreサイズを計算
・フィルおよびフラッシュの比率に基づき、保存するログの数を計算
・最終的なサーバクラスタの容量は以下の要素で決定される
 ・JavaHeap
 ・リーション数とサイズ
 ・キーの分散

まとめ

・WALの実行に十分以上の性能があることを確認
・利用できるmemstore領域の許容量を超えてクライアントが利用しないことを確認
・フラッシュサイズを大きく設定してもいいが、大きくしすぎない
・WALの使用状況を監視
・1ノードにつき、より多くのデータを格納できるように圧縮を有効にする
・いくつかのレベルでバックグラウンドI/Oを固定するため、コンパクションアルゴリズムを変更する
⇒なにに?
・別のテーブルに不均一のカラムファミリを置くことを考慮
・ブロックキャッシュ、memstoreやすべてのキューのメトリクスをチェックする

例)

・10GBのJava xmx heap
・memstoreは40% 4GB
・推奨するフラッシュサイズは128MB 最大32リージョン
・WALサイズは128MB x0.95 部分的にコミットできないログの最大保持量 32個まで
・20GBのリージョンサイズ
 ・20GB x32リージョン=640GBのストレージを使用

質疑応答

Q. OpenTSDBを使ってみたいんだけど、いけてる?
A. おすすめだよ。デザインがいけてると思う。
しかも、OpenTSDBのメイン開発者がこの前Clouderaに入社したんだ。

Q. パフォーマンスチューニングどうするの?
WAL書き込み処理ってパフォーマンスいいんだけど
リカバリ処理が面倒になったりするんだけどどうなの?
A. 確かにその通り。
でも、GoogleBigTableとかでも2〜4個のWAL使ってるんだよねぇ。
で、やっぱりパフォーマンス良くなるから試してみる価値あると思うんだよ。

Q. 0.94で出てきたシークオプティマイゼイションって何よ?
HDFS上で動いてるから何かファイルシステムに対して
直接読み込みしたりしてるの?
A. それはHBaseの中だけでやってる最適化なんだよね。
フラッシュファイルとか全てのディスクから
どうやってデータを読み込もうかっていうところを調節する仕組みだよ。
⇒不必要な行を読み込まない仕組み。
[lazy block load]って名前がいいと思ってるんだよね。


詳しくはこちらの本に書いてあります。

HBase

HBase