1. Hbaseホットスポット(データスキュー)の問題、読み取りおよび書き込み要求が特定のRegionServerに集中する
ホットな問題の理由:
1. hbaseのデータは辞書式順序でソートされます。個々のリージョンに多数の連続する行キーが書き込まれると、リージョン間のデータ分散がバランスされません。
2.テーブルを作成する場合、事前にパーティションを作成する必要はありません。作成されたテーブルには、デフォルトでリージョンが1つしかなく、現在のリージョンに大量のデータが書き込まれます。
3.作成されたテーブルは事前にパーティション化されていますが、設計された行キーには従うべきルールがありません
解決策:行の3つの設計原則
2. Hbaseでフラッシュ、コンパクト、および流出する目的は何ですか
フラッシュ(しきい値128M)
MemStoreがしきい値に達すると、MemstoreデータはStoreFileにフラッシュされます。
コンパクト(データブロックが3ブロックに達すると、HMasterはマージ操作をトリガーします)
cはompactメカニズムであるためにフラッシュ小さなファイルが大きいにマージアウトStorefileのファイル。
ファイルを結合し、削除された、期限切れの、冗長なバージョンのデータをクリアし、データの読み取りと書き込みの効率を向上させます
遊んだ
リージョンがしきい値( 256M )に達すると、大きすぎるリージョンは2つに分割されます(均等に分割されません)。(MiddleKey )
3.Hbaseのregionserverがダウンしているときにデータを復元する方法
4.hbaseの最適化
メモリの最適化:ガベージコレクションの最適化:CMS、G1(Region); JVMの起動:-Xms(1/64)-Xmx(1/4)
リージョンの最適化:事前パーティション化、メジャーマージが無効、手動マージ
クライアントの最適化:バッチ処理
5. Hbase、hive、redisの違い
MRプログラムに基づいて、HiveはHQLをMR実行に変換します。効率が低く、リアルタイムのデータアクセスには適していません
HbaseはHadoopデータストレージに基づいており、大量のデータを保存し、独自のクエリ操作を備えています
メモリに基づくキャッシュを強調し、データの永続性をサポートし、トランザクション操作をサポートするRedis分散キャッシュ
RedisとHbaseはどちらもKey-Valueストレージに基づいています
アプリケーションシナリオ:
Hiveは、待ち時間が長く、オフラインのデータ分析とクリーニングに適しています。
Hbaseは待ち時間が短く、オンラインビジネスでの使用にアクセスでき、効率的なデータアクセス速度を提供します。
6. Hbaseのスキャンを説明し、関数と実装の類似点と相違点を取得します
スキャンスキャンデータ
/**
* 通过scan查询数据
*/
public static void getDataByScanFilter(String tableName) throws IOException {
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
//创建用于扫描region的对象
Scan scan = new Scan();
//设置Filter(较慢)
//字节数组比较器
BinaryComparator bc = new BinaryComparator(Bytes.toBytes("1001"));
//正则表达式比较器
RegexStringComparator rc = new RegexStringComparator("^\\d{3}$");
Filter f1 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,bc);
Filter f2 = new RowFilter(CompareFilter.CompareOp.GREATER_OR_EQUAL,rc);
//设置单个filter
//scan.setFilter(f1);
//设置多个fiter
/**
* 多个filter之间的逻辑关系,相当于java中的与和或
* (AND)
* MUST_PASS_ALL,
* (OR)
* MUST_PASS_ONE
*/
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filterList.addFilter(f1);
filterList.addFilter(f2);
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
//得到rowkey
System.out.println("行键:" + Bytes.toString(CellUtil.cloneRow(cell)));
//得到列族
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
}
}
}
データを取得する
/**
* 获取一行数据
*/
public static void getRow(String tableName, String rowKey) throws IOException{
Connection conn = connHolder.get();
Table table = conn.getTable(TableName.valueOf(tableName));
Get get = new Get(Bytes.toBytes(rowKey));
//get.setMaxVersions();显示所有版本
//get.setTimeStamp();显示指定时间戳的版本
Result result = table.get(get);
for(Cell cell : result.rawCells()){
System.out.println("行键:" + Bytes.toString(result.getRow()));
System.out.println("列族" + Bytes.toString(CellUtil.cloneFamily(cell)));
System.out.println("列:" + Bytes.toString(CellUtil.cloneQualifier(cell)));
System.out.println("值:" + Bytes.toString(CellUtil.cloneValue(cell)));
System.out.println("时间戳:" + cell.getTimestamp());
}
}