スケーラブルなシステムのためのhbaseスキーマ設計 #hcj13w

92
1 スケーラブルなシステムのための HBaseスキーマ設計 Cloudera株式会社 カスタマーオペレーションズエンジニア 嶋内 翔 2013121

Upload: cloudera-japan

Post on 28-May-2015

9.563 views

Category:

Technology


1 download

DESCRIPTION

Cloudera HBase トレーニング: http://tiny.cloudera.com/jptraininghbase Hadoop Conference Japan 2013 Winter で発表した、HBaseのスキーマ設計に関する資料です。 Cloudera の HBase サポート、Cloudera Enterprise RTD http://tiny.cloudera.com/jpcertd

TRANSCRIPT

Page 1: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

1

スケーラブルなシステムのための  HBaseスキーマ設計  

Cloudera株式会社  カスタマーオペレーションズエンジニア  嶋内  翔  2013年1月21日  

Page 2: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

自己紹介  

•  嶋内 翔(しまうち しょう)  •  2011年4月にClouderaの最初の日本人社員として入

社  •  カスタマーオペレーションズエンジニアとしてテクニ

カルサポート業務を担当  •  email:  [email protected]  •  twi=er:  @shiumachi  

2

Page 3: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

Agenda  

•  Apache  HBase  とは  •  スキーマ設計の話の前に  •  HBase  ストレージアーキテクチャ  •  スキーマ設計のポイント  

3

Page 4: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

セッション概要  

•  Hadoop  上で動作する分散ストレージシステム HBase  を活用するためのスキーマ設計のポイントについて紹介します  

•  ゴール  •  性能が出る、正しいHBaseのスキーマ設計ができるように

なること  •  アンチパターンを知り、誤ったスキーマ設計を避けるよう

になること  

4

Page 5: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

対象者・レベル  

•  対象者  •  HBase  の構築・運用担当者  •  HBase  アプリケーションの開発者  

•  対象レベル:  中級  •  Hadoop  (特に  HDFS)  について、アーキテクチャをある程度

理解している  

5

Page 6: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

本セッションで取り扱わない内容  (1)  HDFSの信頼性  

•  HBaseはデータの信頼性をファイルシステムに依存しています  

•  HDFSは十分信頼性が高いです  •  数年以上の稼動実績  •  HDFS  HA  によるSPOFの排除  

•  詳細は下記スライドを参照してください  •  Cloudera  Manager4.0とNameNode-­‐HAセミナー資料  

•  h=p://www.slideshare.net/Cloudera_jp/cloudera-­‐manager4namenodeha  

•  CDH4.1オーバービュー(HA機能についての説明があります)  

•  h=p://www.slideshare.net/Cloudera_jp/cdh41  

6

Page 7: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

本セッションで取り扱わない内容  (2)  Hadoop/HBaseの運用・チューニング  

Cloudera  Managerを使えば1時間でCDHクラスタの構築ができ、管理も非常に簡単です  

HBaseを使うなら  Cloudera  Enterprise  

(CDH  +  Cloudera  Manager)  を選びましょう  

ダウンロードはこちら  

h=p://www.cloudera.com/downloads/  

7

Page 8: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

8

Apache  HBase  とは  

Page 9: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  

•  HDFS  上で動作する NoSQL  •  Google  の開発した NoSQL  BigTable  に基づいて作成され

ている  •   HDFS  が苦手とする低レイテンシのアクセスや小さいファ

イルの操作を得意とする  

h=p://ja.fotopedia.com/items/flickr-­‐1999559141  

Page 10: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

なぜHBaseを使うのか  

•  シャーディングをサポートしてる  •  自動シャーディング  •  コマンド一発で手動シャーディング  

•  書き込みが高速で、しかもスケールアウト可能  •  データの耐障害性も確保されてる  

•  これはHadoopのファイルシステムHDFSの機能  

Page 11: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseのデータ構造  

キーバリューがソートされて並んでいる  

行キー   値  列ファミリ   列   タイム  スタンプ  

r1   ‘python’  cf1   c1   1000  

r1   ‘php’  cf1   c2   1000  

r1   ‘ruby’  cf2   c1   1000  

r2   ‘java’  cf1   c2   1000  

Page 12: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseのテーブル構造(概要)  

•  行キーの一定範囲ごとに別ファイルに分割  •  この範囲のことをリージョンという  

•  1リージョンには列ファミリの数以上のストアファイルが存在  •  ここではかなり簡略化して説明している。詳細は後述  

ストアファイル   ストアファイル  

ストアファイル   ストアファイル  

ストアファイル   ストアファイル  

リージョン  a  -­‐  c  

リージョン  d  -­‐  f  

リージョン  h  -­‐  j  

列ファミリ1   列ファミリ2  

Page 13: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseの構成図  

データノード  データノード    データノード    データノード  データノード    データノード     データノード  データノード    データノード    

クライアント  

ブロック1   ブロック1   ブロック1  

ブロック2   ブロック2   ブロック2  

ブロック3   ブロック3   ブロック3  

リージョンサーバ  

リージョンc  

リージョンサーバ  

リージョンa  

リージョンサーバ  

リージョンb  

※マスタサーバは存在するが、  データ通信には使わない  

Page 14: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseの動作概要  

データノード  データノード    データノード    データノード  データノード    データノード     データノード  データノード    データノード    

クライアント  

ブロック1   ブロック1   ブロック1  

ブロック2   ブロック2   ブロック2  

ブロック3   ブロック3   ブロック3  

リージョンサーバ  

リージョンc  

リージョンサーバ  

リージョンa  

リージョンサーバ  

リージョンb  

HDFSと同様、クライアントはマスタを介さず直接リージョンサーバと通信する  

リージョンサーバはHDFSのクライアントとして  データノードと通信する  

Page 15: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

15

スキーマ設計の話の前に  

Page 16: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

究極のベストプラクティス、それは……  

16  

Page 17: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

17  

h=p://ja.fotopedia.com/items/flickr-­‐1999559141  

Page 18: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseを使わない  (必要がない限り)  

18  

h=p://ja.fotopedia.com/items/flickr-­‐1999559141  

Page 19: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  にはない機能がいっぱい  

•  JOINがない  •  セカンダリインデックスも当然ない  •  テーブル間トランザクションがない  •  etc.  

19

RDBMSは超優秀だし最近はハードウェアも安いので  必要ない限りはRDBMS使いましょう  

Page 20: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

じゃあどんなときにHBaseを使えばいいの?  

20

Page 21: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

じゃあどんなときにHBaseを使えばいいの?  

21

大量のデータがあるとき!  

Page 22: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

じゃあどんなときにHBaseを使えばいいの?  

•  サーバ1台のメモリに載りきらない  •  サーバ1台のディスクに入りきらない  •  etc.  •  最近のサーバだとメモリ100GB、ディスク10TB(RAID5)ぐ

らいなら余裕のはず  •  Hadoopを既に使っている人は大量データがあるはずな

ので利用の検討はあり  

22

大量のデータがあるとき!  

Page 23: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseとRDBの比較  

•  RDBMSが高機能  •  きちんとDB設計すればほ

ぼどんなクエリにも対応可能  

•  スケールしない  •  ストレージ容量  •  書き込み  

•  非正規化前提  •  特定のクエリに特化して

設計  •  用途を絞ってしまえば、

容量や読み書きがスケールするので非常に強力  

•  Hadoop  との連携がしやすい  

23  

RDB   HBase  

Page 24: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

RDBとHBaseにおけるスキーマ設計の違い  

24

Page 25: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

RDBとHBaseにおけるスキーマ設計の違い  

25

論理設計まではほぼ同じ  

•  論理データモデルが間違ってたらこの先の議論は無意味  

•  RDBとHBaseの違いは物理表現レベルの話  

Page 26: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

しかし、設計段階でも物理表現を知ることは  重要  

•  HBaseはユースケースやアクセスパターンに基づいて自動的に最適化したりしない  

•  HBaseの実装を知らないと正しいスキーマ設計ができない  

•  このセッションではまずHBaseのストレージアーキテクチャを理解し、その上でスキーマ設計の話に移る  

26

Page 27: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

27

HBase  ストレージアーキテクチャ  

Page 28: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

28  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

Page 29: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

•  行と列によるテーブル構造  •  行は一定範囲ごとに「リージョン」という単位で区切られて

いる  •  列は「列ファミリ」という単位でグループ化されている  

•  セル  =  行と列の交点  •  セルはタイムスタンプを持っている  

•  バージョンとタイムスタンプはほぼ同じ意味  

29

Page 30: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

30  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

Page 31: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

31  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

テーブルに対する行、列、そして行と列の交差する部分のセル  

論理的なテーブル構造は基本的にRDBと変わらない  

Page 32: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

32  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  (r3,  A:b)  ver.2  

リー

ジョ

ン1  

リー

ジョ

ン2  

Page 33: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

33  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  (r3,  A:b)  ver.2  (r3,  A:b)  ver.3  

リー

ジョ

ン1  

リー

ジョ

ン2  

Page 34: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBaseテーブル  

34  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  (r3,  A:b)  ver.2  (r3,  A:b)  ver.3  

リー

ジョ

ン1  

リー

ジョ

ン2  

セルには複数のバージョンを格納することができる  

Page 35: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

•  テーブルは複数のリージョンで構成されている  •  リージョン =  一定範囲の行キーの集合  •  リージョンは行キーのスタートキーとエンドキーで区分け

される  •  それぞれのリージョンは別々のリージョンサーバに割り当

てられている  

•  列(カラム)は、列ファミリと列が存在する  •  列ファミリごとに別々の物理ファイルが作成される  •  「列ファミリ:列」の記述を列修飾子というが、これで単に列

ということも多い  

35

Page 36: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

36  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

Page 37: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

37  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

テーブルは複数のリージョンで  構成されている  

Page 38: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

38  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

列ファミリごとに別々の物理ファイルに格納される  

Page 39: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

39  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

Page 40: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

40  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンはスタートキーとエンドキーで範囲を決定する  

エンドキーは含まないので注意  

Page 41: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

41  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

Page 42: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

42  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

リージョンはスレーブノード(リージョンサーバ)に別々に配置される  

Page 43: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

43  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

MemStore1   MemStore2   MemStore3   MemStore4  

Page 44: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

44  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

MemStore1   MemStore2   MemStore3   MemStore4  

列ファミリごとにメモリストア(MemStore)  が作られる  

書き込みを行う場合、先行書き込みログ(WAL)に書き込んだあとはこのMemStoreに書き込まれる  MemStoreはメモリ上にしか存在しない  

メモリストアはリージョン☓列ファミリごとに存在する  

Page 45: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

45  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

MemStore1   MemStore2   MemStore3   MemStore4  

HDFS  

HFile  1  HFile  1  HFile  1   HFile  1  HFile  1  HFile  2  

HFile  1  HFile  1  HFile  3   HFile  1  HFile  1  HFile  4  

Page 46: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

リージョンと列ファミリ  

46  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

リージョンサーバA   リージョンサーバB  

リージョン1   リージョン2  

MemStore1   MemStore2   MemStore3   MemStore4  

HDFS  

HFile  1  HFile  1  HFile  1   HFile  1  HFile  1  HFile  2  

HFile  1  HFile  1  HFile  3   HFile  1  HFile  1  HFile  4  HFileは  HDFS  上に格納される  データブロックの複製や配置は  

全てHDFS側で管理  (図ではHDFSのレプリカは省略)  

MemStoreに対し複数のHFileが存在する  Memstoreからフラッシュされるたびに作成され、  

コンパクションによってまとめられる  

Page 47: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

論理テーブルから物理ファイルへ  

47  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

リージョン1  [r1,  r4)  

リージョン2  [r4,  r6)  

Page 48: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

論理テーブルから物理ファイルへ  

48  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

MemStore  1  

MemStore  3  

MemStore  2  

MemStore  4  

Page 49: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

論理テーブルから物理ファイルへ  

49  

列ファミリA   列ファミリB  列a   列b   列c   列a   列b  

行  r1  

行  r2  

行  r3  

行  r4  

行  r5  

(r3,  A:b)  ver.1  

リー

ジョ

ン1  

リー

ジョ

ン2  

HFile  3-­‐1  

HFile  1-­‐3   HFile  2-­‐2  

HFile  4-­‐5  

Page 50: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  テーブルと物理レイアウト  

•  テーブルでは、辞書順に行をソートしている  •  全ての値は行キー、列ファミリ、列修飾子、タイムス

タンプと一緒に保存される  •  テーブルのスキーマは列ファミリのみ定義している  

•  それぞれの列ファミリは任意の数の列を格納可能  •  列ファミリと異なり、スキーマ定義は不要  

•  それぞれのセル(行と列の交点)は任意の数のバージョンを格納可能  

•  セルは挿入されたときにしか作成されないのでNULLはコストゼロ  

•  テーブル名以外はすべて  byte[]  として格納される  

50

Page 51: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  テーブルと物理レイアウト  

以下のようなテーブルを例に考える  

51

r1  

cf1:c1  

‘python’  ts  =  100  

cf1:c2   cf2:c1   cf1:c2  

‘php’  ts  =  100  

‘ruby’  ts  =  100  

r2   ‘java’  ‘scala’  ts  =  100  

‘scala’  ts  =  100  

‘java’  ts  =  90  

Page 52: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  テーブルと物理レイアウト  

52

ストアファイル  cf1  

r1:cf1:c1:100:‘python’  

r1:cf1:c2:100:‘php’  

r2:cf1:c1:100:‘scala’  

r2:cf1:c1:90:‘java’  

ストアファイル  cf2  

r1:cf2:c1:100:‘ruby’  

ストアファイルにはこのように保存されている  

Page 53: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  テーブルと物理レイアウト  

53

r1:cf1:c1:100:‘python’  

r1:cf1:c2:100:‘php’  

r2:cf1:c1:100:‘scala’  

r2:cf1:c1:90:‘java’  

ストアファイル  cf2  

r1:cf2:c1:100:‘ruby’  

ストアファイル  cf1  

ストアファイルはリージョン☓列ファミリで作る  列ファミリはスキーマ定義時に一緒に定義する  

Page 54: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  テーブルと物理レイアウト  

54

ストアファイル  cf1  

r1:cf1:c2:100:‘php’  

r2:cf1:c1:100:‘scala’  

r2:cf1:c1:90:‘java’  

ストアファイル  cf2  

r1:cf2:c1:100:‘ruby’  r1:cf1:c1:100:‘python’  

行キー:列ファミリ:列:タイムスタンプ:値  これらが全て1つのデータで格納されている  

行キー   列ファミリ  列  

タイムスタンプ  値  

Page 55: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

55

スキーマ設計のポイント  

Page 56: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

スキーマ設計  

•  最高のパフォーマンスを得るのに正しいスキーマ設計は不可欠  

•  HBaseでの正しいスキーマ設計にはストレージアーキテクチャの知識が不可欠  

•  これまでのアーキテクチャの説明を踏まえて、スキーマ設計のポイントを説明します  

56

Page 57: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

スキーマ設計の前に(再)  

•  論理設計までは同じです  •  設計する前に、「どういう問い合わせをしたいか」を

きちんと考えましょう  •  ユーザ同士のソーシャルグラフを見たい  •  ユーザ単位のメッセージを一括取得したい  •  etc.  

57

Page 58: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

DDI(でぃーでぃーあい)  

•  Denormalizajon(非正規化)  •  複数のエンティティのリレーションを一つのテーブルで表現する  •  一回の読み込みでそのリレーションに関するデータ取得が可能  

•  Duplicajon(複製)  •  Intelligent  Keys(インテリジェントキー)  

•  属性の組み合わせを行キーとすることで検索を容易にする  •  RDBにおける複合キーのようなもの  

•  の略  •  詳細は 「Cloud  Data  Structure  Diagramming  Techniques  and  

Design  Pa=erns」を参照  •  h=ps://www.data-­‐tacjcs-­‐corp.com/index.php/component/

jdownloads/finish/22-­‐white-­‐papers/68-­‐cloud-­‐data-­‐structure-­‐diagramming  

58

Page 59: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

非正規化  

•  HBaseにはJOINがない  •  JOINなしでエンティティ間のリレーションを表現する

方法は2つ  •  自力でJOINを実装する  

•  極めて困難。ていうか無理  

•  データを非正規化する  

•  非正規化  =  2つの論理エンティティで1つの物理表現を共有すること  

59

Page 60: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

非正規化の例  

60  

Order  

id  amount  customer_id  item_id  

Item  

id  name  price  

Customer  

id  name  

普通のリレーショナルモデルの設計  これを……  

Page 61: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

全部くっつける!  

61  

Order  

id  amount  customer_id  item_id  

Item  

id  name  price  

Customer  

id  name  

Order  order_id  order_amount  customer_id  customer_name  item_id  item_name  item_price  

Page 62: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

非正規化のメリットとデメリット  

•  メリット  •  あらかじめ非正規化しておいたリレーションに関するクエ

リは、たとえ大量のデータであっても超高速に結果が返ってくる  

•  デメリット  •  更新が大変  •  非正規化していないエンティティ同士のリレーションに関

するクエリは、JOINがないので結局できない  

•  ユースケースの絞り込みが重要  

62

Page 63: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

パフォーマンスとカーディナリティ  

63

行キー   値  列ファミリ   列   タイム  スタンプ  

パフォーマンスが高い  

カーディナリティが高い  

行単位でのスキップが可能  

ストアファイル単位でのスキップが可能  

Page 64: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

パフォーマンスとカーディナリティ  

•  行キーを使うときが一番パフォーマンスが高い  •  列ファミリの選択はスキャン対象のデータの数を減

らす  •  値だけのフィルタはフルスキャンと同じ  

•  要するに重い(ネットワーク負荷は減るかもしれないが)  

64

Page 65: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

値のシフト  

•  一つのキーと値は、列ファミリー・列の名前も込みで格納されている  

•  だから値を列や行キーにシフトしてもデータサイズは変わらない  

•  値を空にして、意味のある情報を列や行キーに含めるという手法もある  

65

r1:cf1:c1:100:‘python’¥x00  

r1:cf1:c1‘python’:100:¥x00  

r1‘python’:cf1:c1:100:¥x00  

Page 66: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

Tall  vs.  Wide  

66

Tall   Wide  

Page 67: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

Tall  vs.  Wide  

•  Tall:  行が多く、列が少ない  •  Wide:  行が少なく、列が多い  •  Tall  の特長  

•  Scan  に向いている  

•  Wide  の特長  •  Get  (特定の行のみ取得)に向いている  •  HBaseは行単位ならアトミックに処理可能なので、アトミッ

クな処理をしたい場合に有効  

67

Page 68: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

キー設計  

68

シーケンシャルキー   Saltedキー   フィールド昇格キー   ランダムキー  

シーケンシャルリードのパフォーマンスが高い  

書き込みパフォーマンスが高い  

Page 69: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

キー設計  

•  アクセスパターンに基づき、シーケンシャルキーかランダムキーのいずれかを選択  

•  両方使う場合もある  •  アーキテクチャの限界を乗り越える  

•  どちらも使いどころを間違えなければ有用  •  シーケンシャルキーにはバルクインポートを使う  •  ランダムアクセスをしたい場合にはランダムキーを使う  

69

Page 70: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

具体的なキー設計の手法  

•  リバースドメイン  •  com.cloudera.www,  com.cloudera.blog,  etc.  •  サイトごとの行キーが近くなる、つまりレンジスキャンがしやすくなる  

•  ハッシュ付与  •  データをばらつかせるのに有効  •  例:  MD5(逆ドメイン)  +  逆ドメイン  

•  ソルト  •  単にハッシュをとるのではなく、リージョンサーバの数で割ってmodを

とる  •  リージョンサーバ単位で正確に均等にしたい場合に便利  

•  リバースタイムスタンプ  •  LONG_MAX  -­‐  タイムスタンプ  •  降順にすることで、一番最近のデータが一番上に来るようにする  

70

Page 71: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

具体的なキー設計の手法  

71

元データ  (ドメイン名)  

リバースドメイン   ハッシュ付与   ソルト  

www.cloudera.com   com.cloudera.www   276e_com.cloudera.www  

4_com.cloudera.www  

blog.cloudera.com   com.cloudera.blog   c75d_com.cloudera.blog   1_com.cloudera.blog  

元データ  (タイムスタンプ)  

リバースタイムスタンプ  

1358736114   2936231182  

1358736150   2936231146  

Page 72: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

具体的なキー設計の手法  

72

元データ  (ドメイン名)  

リバースドメイン   ハッシュ付与   ソルト  

www.cloudera.com   com.cloudera.www   276e_com.cloudera.www  

4_com.cloudera.www  

blog.cloudera.com   com.cloudera.blog   c75d_com.cloudera.blog   1_com.cloudera.blog  

元データ  (タイムスタンプ)  

リバースタイムスタンプ  

1358736114   2936231182  

1358736150   2936231146  ハッシュを付与することで配置を分散させる  ソルトを使うことでリージョンサーバ間でより均等になる

ように分散させることも可能  

Page 73: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

具体的なキー設計の手法  

73

元データ  (ドメイン名)  

リバースドメイン   ハッシュ付与   ソルト  

www.cloudera.com   com.cloudera.www   276e_com.cloudera.www  

4_com.cloudera.www  

blog.cloudera.com   com.cloudera.blog   c75d_com.cloudera.blog   1_com.cloudera.blog  

元データ  (タイムスタンプ)  

リバースタイムスタンプ  

1358736114   2936231182  

1358736150   2936231146  

これは未ソートの状態  実際にはソートされ、元データと逆になる  (新しいタイムスタンプが一番上に来る)  

Page 74: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

キー設計の例:  カウンタ  

•  ドメイン毎、URL毎のカウンタを保存する  •  HBase  のインクリメント(アトミックな  read-­‐modify-­‐write  )機

能を使う  •  それぞれの行は一つのドメインあるいはURL  •  列は特定のメトリクスのカウンタ  •  列ファミリは時間範囲のグループカウンタとして使う  

•  列ファミリレベルでTTL(生存期間)を設定して、一定期間経過後にメトリクスが削除されるようにしてストレージ領域を節約  

•  例:  “Daily  Counters”  (日次カウンタ)  列ファミリには2週間のTTLを設定  

74

Page 75: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

キー設計の例:  カウンタ  

•  ドメインの行キー  =  MD5(リバースドメイン)  +  リバースドメイン  •  行キーを分散させ、バラバラのリージョンに配置されるよ

うにする  •  ロードバランシングの方法として有効  

•  URLの行キー  =  MD5(リバースドメイン)  +  リバースドメイン  +  URL  ID  •  行キーのサイズ節約のため、URL  ID  を作っておいてそれ

を使った方がいい  

75

Page 76: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

列修飾子設計  (1)  列ファミリ  

•  データは複数のストレージファイルに保存されることを考慮する  

•  列ファミリは少なめにする  •  HFileの数  =  リージョン  *  列ファミリ  *  (3〜6ぐらい)  •  HBase  は全ての HFile  をオープンする  •  つまり列ファミリが多いと必要なファイルディスクリプタの数が

増大する  •  多くても3つぐらい。1つだけで運用する場合もあり  

•  アクセスパターンが全く異なるデータがあるときに使うのが◯  •  例1:  メタデータ  +  実データ  •  例2:  日次データ  +  週次データ  +  月次データ  

76

Page 77: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

列修飾子設計 (2)  名前  

•  列ファミリ・列の名前は短い方がいい  •  列修飾子全体が1行ごとに保存されるため、ここが長いと

データ量が大幅に増加する  

77

Page 78: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

列修飾子設計の例:  カウンタ  

•  列ファミリ  •  1時間毎のカウンタ    •  日次カウンタ  •  総計カウンタ  

•  列名は分かりやすく日本語にしているのでそのまま使わないように  

78

時間毎   日次   総計  

h  (hourlyの略)   d  (dailyの略)   t  (totalの略)  

実際にはこんな感じでいい  

Page 79: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

列修飾子設計の例:  カウンタ  

•  単位時間のメトリックのカウンタを配置  •  <時間><メトリック>  

79

時間毎  18時合計   18時東京   18時大阪   19時合計   19時東京  

日次  1/1合計   1/1東京   1/1大阪   1/2合計   1/2東京  

……  

……  

Page 80: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

ホットスポット  

•  HBaseは1リージョンは1リージョンサーバが担当する  •  だから特定のリージョンだけにアクセスが集中する

ということがありうる(ホットスポット)  •  シーケンシャルキーだとホットスポットができるかも

しれない  •  午前中のキーノートでもNHN  Japanの中村さんがLINEでホットスポットが発生していたという事例を紹介していた  •  h=p://www.slideshare.net/naverjapan/storage-­‐infrastructure-­‐using-­‐hbase-­‐behind-­‐line-­‐messages  

 80

Page 81: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

ホットスポットの例:タイムスタンプを使う  

•  <タイムスタンプ><他のキー>:  {  列ファミリ:  {  列修飾子:  {  タイムスタンプ  :  値  }}}  •  これはダメな例  •  ホットスポットが発生する  

81

cf1  cf1:c1   cf1:c2  

1358682406_metricA  

1358682406_metricB  

1358682407_metricA  

1358682410_metricA  

行キーの頭がほとんど同じ  これだと、ある時間帯に1つのRSだけが  

処理をすることになる  

Page 82: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

ホットスポットの例:タイムスタンプを使う  

解決策1:  タイムスタンプをソルトする  (事前にリージョンを分割して別々のRSに割り当てておく)  

82

cf1  cf1:c1   cf1:c2  

0_1358682406_metricA  

1_1358682200_metricA  

4_1358672200_metricB  

9_1358662211_metricA  

Page 83: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

ホットスポットの例:タイムスタンプを使う  

解決策2:  <他のキー>を前に持ってくる  

83

cf1  cf1:c1   cf1:c2  

metricA_1358682406  

metricA_1358682407  

metricA_1358682410  

metricB_1358682406  

Page 84: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

例:  OpenTSDB  

•  OpenTSDB  は、メトリクスを保存するための時系列データベース  •  h=p://opentsdb.net/  

•  スキーマは以下のようになっている  •  メトリックの種類とタグは行キーに保存されている  •  新しいタイムスタンプによる行キーは定期的に作成  

•  ホットスポットの解決策2の典型例  

84

メトリクス(列ファミリ)  <時間差分><フラグ>   <時間差分><フラグ>  

<メトリック><タイムスタンプ><タグ>   値   値  

Page 85: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

例:  OpenTSDB  

詳細は h=p://opentsdb.net/misc/opentsdb-­‐hbasecon.pdf  

 

85

+1   +2   +4  

metricA_1358600000   10   12   15  metricA_1358600600   11   17  metricB_1358600000   100   105  

時間の差分を列にとる  例)  1358600000  +  1  =  1358600001  

一定時間ごとに新しい行を作成  

Page 86: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

86

まとめ  

Page 87: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

まとめ  

•  HBaseにおける正しいスキーマ設計には、ユースケースやアクセスパターンと、HBaseの内部構造を知ることが不可欠です  

•  非正規化・インテリジェントキーなど、RDBと異なるテクニックを駆使することで、性能をスケールさせることができます  

•  正しくスキーマを設計して、快適なHBaseライフを満喫しましょう!  

87

Page 88: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

HBase  本日本語訳出ました  

•  Cloudera  の  Lars  George  が書いた HBase  のバイブル  

•  訳は安心の玉川さん  •  レビュー手伝ってました  

Page 89: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

Cloudera  の HBase  トレーニング  

HBase  トレーニングではスキーマ設計もあります  今日の話だけでは物足りないという方は今すぐ登録を!  次回は3/25  -­‐  26  開催です    申し込みはこちら  h=p://www.cloudera.co.jp/university/hbase.html      

Page 90: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

CDHコミュニティ・MLの紹介  

CDH  ユーザ メーリングリスト(日本語)  cdh-­‐user-­‐[email protected]  CDH  の質問についてはこちら    Cloudera  ニュースレター  h=p://www.cloudera.co.jp/newsle=er  Cloudera  に関するニュースをお届けします  CDHの最新情報・使い方なども紹介します        

90

Page 91: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

宣伝  

Cloudera  Managerを使えば1時間でCDHクラスタの構築ができ、管理も非常に簡単です  

HBaseを使うなら  Cloudera  Enterprise  

(CDH  +  Cloudera  Manager)  を選びましょう  

ダウンロードはこちら  

h=p://www.cloudera.com/downloads/  

91

Page 92: スケーラブルなシステムのためのHBaseスキーマ設計 #hcj13w

92