あまりにも多くの列の家族の影響力
各MemoryStoreが過剰合併につながる、より少ないメモリを割り当て、パフォーマンスへの影響
それが適切であるいくつかの列の家族
推奨されます:1-3
分類欄ファミリーの原則:
図1に示すように、データ形式類似するかどうか
図2に示すように、アクセスの同様のタイプかどうか
例1:のrowKey同じ、テキストデータを格納するための大きな必要性がある、画像データを格納する必要があります
大規模なテキストデータのために我々は確かにそれは貯蔵後に圧縮したいです
バイナリデータ圧縮のこの種のためのスペースを節約していないため、画像データは、まだ、私たちは、圧縮されたストレージに彼をしたくありません
そこで、我々は2人の列の家族にこれらの二つのデータが格納されていることができます
'テーブル'、{NAME => 'T'、COMPRESSION => 'スナッピー' を}作成し、
{NAME => 'P'}
それが適切であるいくつかの列の家族
例2:HBaseのテーブルがあり、各ユーザーの情報を保存する必要があり、ユーザー情報(氏名、年齢、など)は、毎日Webサイトを参照してください。
ユーザーの情報が頻繁に変更し、あまりされていません
ユーザーのアクセスについては常に毎日大量のデータのサイトを変更しています
同じ列の家族の中でこれら二つの言葉の情報であれば、日々の情報データがメモリストアにフラッシュをリードする、その後、圧縮は、列ファミリレベルであるので、コンパクト化につながる、そうするすべてのサイトへのユーザーアクセスを増やします(などの名前、年齢、など)のユーザ情報とユーザ情報は、Webサイトを参照してください。毎日のファイルにマージされています
実際には、利用者の情報はないが、多くの場合、変更されません、圧縮は資源の無駄で、その結果、各ユーザの情報がディスクに書き込まれている必要はなく、
だから、その日にユーザーの情報とユーザ情報は、2人の列の家族を保存するためにサイトを訪問することができます
表スキーマ設計
1、50G〜10の各領域の大きさ
図2に示すように、制御領域50〜100の各テーブル
図3に示すように、制御表1-3列ファミリーの各
列ファミリは、データファイルに格納されているため4、最高の名前の各カラムファミリは、短いもの
rowKeyをデザイン
長さの原則:
rowKeyは一般的に10〜100バイトの長さを推奨しているが、より良い勧告短いです
図1に示すように、データは、意志、= 1億バイト、ほぼ1Gのデータを100×10万人に占有する、のrowKey長すぎる場合HFILEファイルは、キー値に応じて格納されているような100のバイト1000万の光のrowKeyデータを永続します大幅HFILEのストレージ効率に影響を与えます
2は、のrowKeyフィールドの有効利用がある場合は、キャッシュメモリへのデータのMemStore部分は、長すぎるメモリが削減されると、システムは、検索効率が低下しますより多くのデータを、キャッシュしません。したがってのrowKeyバイト長はできるだけ短く。
図3は、64ビットオペレーティングシステムは、システムメモリ8バイト整列です。rowKeyは、8バイトの整数倍である場合には、オペレーティング・システムの最高の機能を使用します。
rowKeyデザイン2
特徴:のrowKeyが保存されている辞書順
同様のrowKeyは、同じ領域に格納されます
たとえば、次のように私たちのrowKeyは、サイトのドメイン名は、次のとおりです。
www.apache.org
mail.apache.org
jira.apache.org
次のように優れたポイントのrowKeyとして逆ドメイン名は、その後、次のとおりです。
org.apache.www
org.apache.mail
org.apache.jira
rowKeyデザイン3
rowKeyが辞書順で保管され、そうでないのrowKey良いデザインならば、それはにつながるため。
Hotspotting:地域に送信されたリクエストのだけ多数
解決するための3つの方法のHotspotting:
1、(スプレッド、塩のような(塩))塩漬け
'F'、 'test_salt' を作成、分割=> [ 'B'、 'C'、 'D']
オリジナルのrowKey:
boo0001
boo0002
boo0003
boo0004
boo0005
boo0003
塩漬けのrowKey:
-boo0001
B-boo0002
C-boo0003
D-boo0004
-boo0005
D-boo0003
輸入はjava.util.ArrayList; 輸入はjava.util.List; 輸入java.util.concurrent.atomic.AtomicInteger。 パブリッククラスKeySalter { プライベートのAtomicInteger指数=新しいのAtomicInteger(0); プライベート文字列[]プレフィックス= { "A"、 "B"、 "C"、 "D"}。 パブリック文字列getRowKey(文字列originalKey){ StringBuilderのSB =新しいStringBuilderの(接頭辞[index.incrementAndGet()%4])。 sb.append( " - ")(originalKey)を追加します。; sb.toStringを返します(); } パブリックリストの<string> getAllRowKeys(文字列originalKey){ リストの<string> allKeys =新規のArrayList <>(); 用(文字列の接頭辞:接頭辞){ sb.append( " - ")(originalKey)を追加します。; allKeys.add(sb.toString())。 } -boo0001 // // B-boo0001 // C-boo0001 // D-boo0001 戻りallKeys。 } }
輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client.Connection。 輸入org.apache.hadoop.hbase.client.ConnectionFactory; 輸入org.apache.hadoop.hbase.client.Put; 輸入org.apache.hadoop.hbase.client.Table; 輸入org.apache.hadoop.hbase.util.Bytes。 インポートにjava.io.IOException; 輸入はjava.util.ArrayList; 輸入java.util.Arrays。 輸入はjava.util.List; パブリッククラスSaltingTest { 公共の静的な無効メイン(文字列[] argsが){IOExceptionがスロー 構成設定= HBaseConfiguration.create()。 (接続の接続= ConnectionFactory.createConnection(設定);試みる 表表= connection.getTable(TableName.valueOf( "test_salt"))){ KeySalter keySalter =新しいKeySalter()。 リストの<string> rowkeys =は、Arrays.asList( "boo0001"、 "boo0002"、 "boo0003"、 "boo0004")。 一覧<入れ>は置く=新しいArrayListを<>(); (キー文字列:rowkeys)のために、{ =新しいのPut(Bytes.toBytes(keySalter.getRowKey(キー)))入れて置きます。 put.addColumn(Bytes.toBytes( "F")、NULL、Bytes.toBytes( "値" +キー))。 puts.add(置きます)。 } table.put(プット)。
輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client *。; 輸入org.apache.hadoop.hbase.util.Bytes。 インポートにjava.io.IOException; 輸入はjava.util.ArrayList; 輸入java.util.Arrays。 輸入はjava.util.List; パブリッククラスSaltingGetter { 公共の静的な無効メイン(文字列[] argsが){IOExceptionがスロー 構成設定= HBaseConfiguration.create()。 試みる(接続の接続= ConnectionFactory.createConnection(設定); 表テーブル= connection.getTable(TableName.valueOf( "test_salt"))){ KeySalter keySalter =新しいKeySalter(); 一覧<文字列> allKeys = keySalter.getAllRowKeys( "boo0001"); //读取boo001 一覧は<こちら>を取得=新しいArrayListを<>(); (文字列のキー:allKeys)について{ ゲット=新しい取得(Bytes.toBytes(キー)); gets.add(取得)。 } []結果= table.get(取得)の結果。 {:(結果結果結果)のため であれば(結果= nullを!){ //何かを行います } } } } }
rowKeyデザイン3
2、ハッシング
'F'、 'test_hash' を作成し、{NUMREGIONS => 4、SPLITALGO => 'HexStringSplit'}
オリジナルのrowKey:
boo0001
boo0002
boo0003
boo0004
MD5ハッシュのrowKey:
4b5cdf065e1ada3dbc8fb7a65f6850c4
b31e7da79decd47f0372a59dd6418ba4
d88bf133cf242e30e1b1ae69335d5812
f6f6457b333c93ed1e260dc5e22d8afa
輸入org.apache.hadoop.hbase.util.MD5Hash; パブリッククラスKeyHasher { 公共の静的な文字列getRowKey(文字列originalKey){ MD5Hash.getMD5AsHex(originalKey.getBytes())を返します。 } }
パッケージcom.twq.hbase.rowkey.hash。 輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client.Connection。 輸入org.apache.hadoop.hbase.client.ConnectionFactory; 輸入org.apache.hadoop.hbase.client.Put; 輸入org.apache.hadoop.hbase.client.Table; 輸入org.apache.hadoop.hbase.util.Bytes。 インポートにjava.io.IOException; 輸入はjava.util.ArrayList; 輸入java.util.Arrays。 輸入はjava.util.List; パブリッククラスHashingTest { 公共の静的な無効メイン(文字列[]引数)はIOExceptionが{スロー 構成設定= HBaseConfiguration.create()。 試みる(接続の接続= ConnectionFactory.createConnection(設定); 表テーブル= connection.getTable(TableName.valueOf( "test_hash"))){ リストの<string> rowkeys =は、Arrays.asList( "boo0001"、 "boo0002"、「boo0003 」、 "boo0004"); 一覧<入れ>は置く=新しいArrayListを<>(); (キー文字列:rowkeys)のために、{ =新しいのPut(Bytes.toBytes(KeyHasher.getRowKey(キー)))入れて置きます。 put.addColumn(Bytes.toBytes( "F")、NULL、Bytes.toBytes( "値" +キー))。 puts.add(置きます)。 } table.put(プット)。 } } }
輸入com.twq.hbase.rowkey.salt.KeySalter。 輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.hbase.Cell; 輸入org.apache.hadoop.hbase.CellUtil; 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client *。; 輸入org.apache.hadoop.hbase.util.Bytes。 インポートにjava.io.IOException; 輸入はjava.util.ArrayList; 輸入はjava.util.List; パブリッククラスHashingGetter { 公共の静的な無効メイン(文字列[] argsが){IOExceptionがスロー 構成設定= HBaseConfiguration.create()。 (接続の接続= ConnectionFactory.createConnection(設定)してみてください。 表table = connection.getTable(TableName.valueOf( "test_hash"))){ ゲット=新しい取得(Bytes.toBytes(KeyHasher.getRowKey( "boo0001"))); 結果結果= table.get(取得)。 //処理結果... (セルCELL:results.listCells()){ため のSystem.out.println(Bytes.toString(CellUtil.cloneRow(セル))+ "===>" + Bytes.toString(CellUtil。 cloneFamily(セル))+ ":" + Bytes.toString(CellUtil.cloneQualifier(セル))+ "{" + Bytes.toString(CellUtil.cloneValue(セル))+ "}")。 } } } }
rowKeyデザイン3
3、逆のrowKey
'test_reverse' を作成、 'F' は、=> [ '0'、 '1'、 '2'、 '3'、 '4'、 '5'、 '6'、 '7'、 '8'、」を分割します9' ]
rowKeyのタイムスタンプの種類:
1524536830360
1524536830362
1524536830376
リバースのrowKey:
0630386354251
2630386354251
6730386354251
![](https://img2018.cnblogs.com/blog/1598893/201909/1598893-20190909120057065-955343583.png)
輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.fs.Path。 輸入org.apache.hadoop.hbase.Cell; 輸入org.apache.hadoop.hbase.CellUtil; 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client *。; 輸入org.apache.hadoop.hbase.filter *。; 輸入org.apache.hadoop.hbase.util.Bytes。 インポートにjava.io.IOException; パブリッククラスDataFilter { 公共の静的な無効メイン(文字列[] argsが){IOExceptionがスロー 構成設定= HBaseConfiguration.create()。 //必要な設定ファイルを追加します(HBaseの-site.xmlに、コア-site.xmlの) config.addResource(新しいパス( "SRC /メイン/リソース/ HBaseの-site.xmlの")); config.addResource(新しいパス( "SRC /メイン/リソース/コア-site.xmlの")); 試みる(接続の接続= ConnectionFactory.createConnection(設定)){ テーブルのテーブルは= connection.getTable(TableName.valueOf() "音")。 スキャンスキャン=新しいスキャン(); scan.setStartRow(Bytes.toBytes( "00000120120901")); scan.setStopRow(Bytes.toBytes( "00000120121001")); SingleColumnValueFilter nameFilter =新しいSingleColumnValueFilter(Bytes.toBytes( "F")、Bytes.toBytes( "N")、 CompareFilter.CompareOp.EQUAL、新しいSubstringComparator( "中国好声音"))。 SingleColumnValueFilter categoryFilter =新しいSingleColumnValueFilter(バイト数。 CompareFilter.CompareOp.EQUAL、新しいSubstringComparator( "综艺")); FilterList filterList =新しいFilterList(FilterList.Operator.MUST_PASS_ALL)。 filterList.addFilter(nameFilter)。 filterList.addFilter(categoryFilter)。 scan.setFilter(filterList)。 ResultScanner RS = table.getScanner(スキャン)。 {しようと ために(結果R = rs.next(); R = NULL; R = rs.next()!){ //処理結果... のための(セルCELL:r.listCells()){ System.out.println(Bytes.toString(CellUtil.cloneRow(セル))+ "===>" + Bytes.toString(CellUtil.cloneFamily(セル))+ ":" + Bytes.toString(CellUtil.cloneQualifier(セル))+ "{" + Bytes.toString(CellUtil.cloneValue(セル))+ "}")。 } } }最後に{ rs.close()。//常にResultScannerを閉じます! } } } }
輸入org.apache.hadoop.conf.Configuration。 輸入org.apache.hadoop.fs.Path。 輸入org.apache.hadoop.hbase.HBaseConfiguration。 輸入org.apache.hadoop.hbase.TableName。 輸入org.apache.hadoop.hbase.client.Connection。 輸入org.apache.hadoop.hbase.client.ConnectionFactory; 輸入org.apache.hadoop.hbase.client.Put; 輸入org.apache.hadoop.hbase.client.Table; 輸入org.apache.hadoop.hbase.util.Bytes。 輸入java.io.BufferedReader; インポートにjava.io.IOException; 輸入java.io.InputStreamを。 輸入java.io.InputStreamReader。 輸入はjava.util.ArrayList; 輸入はjava.util.List; / ** * '音'を作成、 * / パブリッククラスDataPrepare { 公共の静的な無効メイン(文字列[] argsが)にIOException {スロー 。入力ストリームイン= DataPrepare.class.getClassLoader()getResourceAsStream( "sound.txtを"); BufferedReaderのBR =新しいBufferedReaderの(新しいInputStreamReaderの(INS))。 一覧<SoundInfo> soundInfos =新しいArrayListを<>(); 文字列の行= NULL; (!(ライン= br.readLine())= NULL){一方 SoundInfo soundInfo =新しいSoundInfo()。 String []型ARR = line.split( "\\ |"); 文字列のrowKey =フォーマット(ARR [4]、6)+ ARR [1] +フォーマット(ARR [0]、6)。 soundInfo.setRowkey(のrowKey)。 soundInfo.setName(ARR [2])。 soundInfo。 soundInfos.add(soundInfo)。 } 構成設定= HBaseConfiguration.create()。 //必要な設定ファイル(HBaseの-site.xmlに、コア-site.xmlの)追加 config.addResource(新しいパス( "SRC /メイン/リソース/ HBaseの-site.xmlのは")); config.addResource(新しいパス( "SRC /メイン/リソース/コア-site.xmlの")); 試みる(接続の接続= ConnectionFactory.createConnection(設定)){ テーブルのテーブルは= connection.getTable(TableName.valueOf() "音")。 一覧<入れ>は置く=新しいArrayListを<>(); (SoundInfo soundInfo:soundInfos)のために、{ =新しいのPut(Bytes.toBytes(soundInfo.getRowkeyを()))入れて置きます。 put.addColumn(Bytes.toBytes( "F")、Bytes.toBytes( "N")、Bytes.toBytes(soundInfo.getName()))。 put.addColumn(Bytes.toBytes( "F")、Bytes.toBytes( "C")、Bytes.toBytes(soundInfo.getCategory()))。 puts.add(置きます)。 } table.put(プット)。 } } パブリック静的文字列の形式(文字列str、int型NUM){ String.Formatのリターン( "%0" + NUM + "d"を、Integer.parseInt(STR))。 } }
スキャンオブジェクトを作成した後、我々は、(00000120120901)setStopRow(00000120120914)をsetStartRow。
したがって、唯一のスキャンデータは、ユーザを満たし、時間帯に応じて結果をフィルタリングするためのユーザID = 1、およびこの時間の特定の期間で定義された時間範囲を走査したとき。中央記憶装置及び記録、高性能以来。
次いでSingleColumnValueFilter(org.apache.hadoop.hbase.filter.SingleColumnValueFilter)、上位4、の合計と名前のそれぞれに結合した上下及び下限のカテゴリ。ファイル名やカテゴリ名で同時に前方一致ミート・ザ・プレス。
(注意:使用SingleColumnValueFilterは、クエリのパフォーマンスに影響を与え、リアルタイムで大量のデータを処理することは、リソースを大量に消費し、長い時間がかかります)
あなたはPageFilterページを追加する必要がある場合も、返されるレコードの数を制限することができます。