1、Hbase热点(数据倾斜)问题,读写请求会集中到某一个RegionServer上
产生热点问题的原因:
1、hbase的中的数据是按照字典序排序的,当大量连续的rowkey集中写在个别的region,各个region之间数据分布不均衡;
2、创建表时没有提前预分区,创建的表默认只有一个region,大量的数据写入当前region
3、创建表已经提前预分区,但是设计的rowkey没有规律可循
解决方案:row三大设计原则
2、Hbase中flush、compact、spilt的用途是什么
Flush(阈值128M)
当MemStore达到阈值,将Memstore中的数据Flush进Storefile;
Compact(当数据块达到3块,HMaster触发合并操作)
compact机制则是把flush出来的小文件合并成大的Storefile文件。
合并文件;清除删除、过期、多余版本的数据;提高读写数据的效率
spilt
当Region达到阈值(256M),会把过大的Region一分为二(不是均分)。(middleKey)
3、Hbase的regionserver挂了如何恢复数据
4、hbase优化
内存优化:垃圾回收优化:CMS, G1(Region);JVM启动:-Xms(1/64) –Xmx(1/4)
Region优化:预分区;禁用major合并,手动合并
客户端优化:批处理
5、Hbase,hive和redis的区别
Hive基于MR程序,将HQL转换为MR执行。效率比较低,不适合实时数据访问
Hbase基于Hadoop数据存储,存储海量数据,而且拥有自己的查询操作
Redis分布式缓存,强调缓存,基于内存,支持数据持久化,支持事务操作
Redis和Hbase都是基于Key-Value存储的
应用场景:
Hive适用于离线的数据分析和清洗,延迟较高。
Hbase延迟较低,接入在线业务使用,提供了高效的数据访问速度。
6、描述Hbase的scan和get功能以及实现的异同
scan扫描数据
/**
* 通过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)));
}
}
}
get获取数据
/**
* 获取一行数据
*/
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());
}
}