HBaseRowkeyデザインガイド
Hbase Rowkey Design Guide
HBaseRowkeyデザインガイド
Rowkeyが非常に重要な理由
RowKeyとは正確には何ですか?
HBaseテーブルのデザインを見るのは良いことだとよく言われますが、RowKeyのデザインを見るだけでもいいのです。 HBaseのRowKeyのステータスを確認できます。では、RowKeyとは正確には何ですか? RowKeyの特徴は次のとおりです。
-
MySQLの主キーと同様に、Oracleは一意の行をマークするために使用されます
-
ユーザーが完全に指定した繰り返しのない文字列の文字列
-
HBaseのデータは、常にRowkeyの辞書の順序に従って並べ替えられます。
RowKeyの役割
-
データの読み取りおよび書き込み時に、RowKeyを介して対応するリージョンを検索します
-
MemStoreのデータは、RowKey辞書式順序で並べ替えられます
-
HFileのデータは、RowKey辞書式順序で並べ替えられます。
クエリに対するRowkeyの影響
RowKeyが次のように設計されている場合 uid + phone + name の場合、この設計は次のシナリオを非常によくサポートできます。
-
uid = 111 AND phone = 123 AND name = iteblog
-
uid = 111 AND phone = 123
-
uid = 111 AND phone = 12?
-
uid = 111
サポートが難しいシーン:
-
電話= 123AND名前= iteblog
-
電話= 123
-
名前= iteblog
Rowkeyの地域分割への影響
HBaseテーブルのデータは、Rowkeyに従ってさまざまなリージョンに分散され、不合理なRowkeyの設計は次のようになります。 ホットな問題 。ホットな問題は、クラスター内の他のノードが比較的アイドル状態であるのに、多数のクライアントがクラスターの1つまたはいくつかのノードに直接アクセスすることです。
Spark、Hadoop、またはHbase関連の記事について詳しく知りたい場合は、WeChatパブリックアカウントに注意してください。 iteblog_hadoop
上に示したように、Region1のデータはRegion 2の5倍であるため、Region1のアクセス頻度が高くなり、Regionが配置されているマシンの他のRegionに影響します。
RowKeyの設計スキル
上記のホットな問題をどのように回避できますか?これは、この章で説明する3つの方法です。
ホットスポットを回避する方法-塩漬け
ここでのソルトの追加は、暗号化のソルトではなく、行キーの前の乱数です。具体的には、rowkeyにはランダムなプレフィックスが割り当てられ、前の並べ替えとは異なります。割り当てられるプレフィックスタイプの数は、データをさまざまなリージョンに分散するリージョンの数と同じである必要があります。ソルトを追加すると、他の均等に分散されたrwokeyに繰り返し表示されるホットスポットの行キーがある場合に役立ちます。次の例を考えてみましょう。書き込み要求を複数のRegionServerに分散しますが、読み取りに悪影響を及ぼします。
次の行キーがある場合、テーブルの各領域はアルファベットのすべての文字に対応します。 'a'で始まるのは同じ領域であり、 'b'は同じ領域で始まります。表では、「f」で始まるものはすべて同じ領域にあり、それらの行キーは次のようになります。
foo0001 foo0002 foo0003 foo0004
ここで、上記の領域を4つの領域に広げる必要がある場合。 'a'、 'b'、 'c'、 'd'の4つの異なる塩を使用できます。このスキームでは、各文字の接頭辞は異なる地域にあります。塩を追加すると、次の行キーが表示されます。
a-foo0003 b-foo0001 c-foo0004 d-foo0002
したがって、4つの異なるリージョンに書き込むことができます。理論的には、全員が同じリージョンに書き込む場合、スループットは4倍になります。
ここで、別の行を追加すると、a、b、c、dのいずれかがプレフィックスとしてランダムに割り当てられ、既存の行がテールとして終了します。
a-foo0003 b-foo0001 c-foo0003 c-foo0004 d-foo0002
割り当てはランダムであるため、辞書式順序でデータを取得する場合は、さらに多くのことを行う必要があります。この方法でソルトを追加すると、書き込み時のスループットが向上しますが、読み取り時に追加のコストが発生します。
ホットスポットを回避する方法-ハッシュ
ハッシュの原則は、RowKeyのハッシュ値を計算し、ハッシュの部分的な文字列を元のRowKeyとスプライスすることです。ここで説明するハッシュには、MD5、sha1、sha256、sha512などのアルゴリズムが含まれています。たとえば、次のRowKeyがあります。
foo0001 foo0002 foo0003 foo0004
md5を使用してこれらのRowKeyのハッシュ値を計算し、最初の6ビットと元のRowKeyを使用して新しいRowKeyを取得します。
95f18cfoo0001 6ccc20foo0002 b61d00foo0003 1a7475foo0004
長所と短所:データセット全体がある程度破損する可能性がありますが、スキャンには役立ちません。たとえば、md5アルゴリズムを使用してRowkeyのmd5値を計算し、最初のいくつかの文字列をインターセプトします。 subString(MD5(デバイスID)、0、x)+デバイスID。xは通常5または6です。
ホットスポットを回避する方法-逆転
反転の原則は、固定長またはすべてのキーを反転することです。たとえば、次のURLとRowKeyがあります。
flink.iteblog.com www.iteblog.com carbondata.iteblog.com def.iteblog.com
これらのURLは実際には同じドメイン名に属していますが、前のURLは異なるため、データは一緒に保存されません。次のように逆にすることができます。
moc.golbeti.knilf moc.golbeti.www moc.golbeti.atadnobrac moc.golbeti.fed
この後、これらのURLのデータをまとめることができます。
RowKeyの長さ
RowKeyは、最大長が64KBの任意の文字列にすることができます(Rowlengthは2バイトを占めるため)。次の理由により、推奨値は短いほど良いです。
-
データ永続性ファイルHFileは、KeyValueに従って保存されます。行キーが長すぎる場合(100バイトを超える、1000w行のデータなど)、明るい行キーは100 * 1000w = 10億バイトを占有し、1Gデータに近くなります。 HFileのストレージ効率に大きな影響
-
MemStoreは一部のデータをメモリにキャッシュします。行キーフィールドが長すぎると、メモリの有効利用率が低下し、システムはそれ以上のデータをキャッシュできなくなり、検索効率が低下します。
-
現在、オペレーティングシステムは64ビットシステムであり、8バイトのメモリが整列され、16バイトで制御され、8バイトの整数倍がオペレーティングシステムの最高の機能を利用しています。
RowKeyデザインケースの分析
トレーディングクラスRowkeyデザイン
-
一定期間の売り手の取引履歴を照会する
SellerId +タイムスタンプ+ orderId -
一定期間の購入者の取引履歴を照会する
BuyerId +タイムスタンプ+ orderId -
注文番号によるクエリ
注文番号 -
マーチャントが多くの製品を販売している場合は、すばやく検索できるようにRowkeyを設計できます。
ソルト+セラーID +タイムスタンプ ここで、saltは乱数です。
シーンをサポートできます:-
全表スキャン
-
SellerIdによるクエリ
-
SellerId +タイムスタンプによるクエリ
-
財務リスク管理Rowkeyの設計
ユーザーのユーザー画像データを照会する
-
プレフィックス+ uid
-
プレフィックス+ idcard
-
プレフィックス+テレ
prefix = substr(md5(uid)、0、x)の場合、xは5〜6を取ります。 Uid、idcard、teleは、それぞれユーザーの一意の識別子、IDカード、携帯電話番号を表します。
カーネットワーキングRowkeyデザイン
-
特定の時間範囲での自動車の取引履歴を照会する
carId +タイムスタンプ -
バッチに車が多すぎるため、ホットスポットが発生します
プレフィックス+ carId +タイムスタンプ ここで、prefix = substr(md5(uid)、0、x)
最近のデータを照会する
ユーザーの最新の操作レコードを照会するか、特定の期間のユーザーの操作レコードを照会します。 RowKeyの設計は次のとおりです。
uid + Long.Max_Value-タイムスタンプ
サポートされているシーン
-
ユーザーの最新の操作レコードを照会する
スキャン[uid] startRow [uid] [000000000000] stopRow [uid] [Long.Max_Value-タイムスタンプ] -
一定期間のユーザーの操作記録を照会する
スキャン[uid] startRow [uid] [Long.Max_Value – startTime] stopRow [uid] [Long.Max_Value-endTime]