1. Hbase是什么?hbase的特点是什么?
- Hbase一个分布式的基于列式存储的数据库,基于Hadoop的 hdfs 存储,zookeeper 进行管理。
- Hbase适合存储半结构化或非结构化数据,对于数据结构字段不够确定或者杂乱无章很难按一个概念去抽取的数据。
- Hbase 为 null 的记录不会被存储。
- 基于的表包含 rowkey,时间戳,和列族。新写入数据时,时间戳更新, 同时可以查询到以前的版本。
- hbase 是主从架构。hmaster 作为主节点,hregionserver 作为从节点。
2.请描述Hbase的特点,并简要说明如何分裂region。
- HBase 自动把表水平划分成多个区域 (region) ,每个 region 会保存一个表里面某段连续的数据 (每条记录都有一个行键,按照行键字典序排列)
- 每个表一开始只有一个 region ,随着数据不断插入表, region 不断增大,当增大到一个阈值的时候, region 就会等分会两个新的 region (裂变)
- 当 table 中的行不断增多,就会有越来越多的 region 。这样一张完整的表被保存在多个 Regionserver 上。
- 一个 region 由多个 store 组成,一个 store 对应一个 CF (列族)
- HRegion 是 HBase 中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion 可以分布在不同的 HRegion server 上。 HRegion 由一个或者多个 Store组成,每个 store 保存一个 columns family 。每个 Store 又由一个 memStore 和0 至多个 StoreFile 组成。如图: StoreFile 以 HFile 格式保存在 HDFS 上。
3.Hbase中RowKey如何设计?如何优化?
1. rowkey唯一原则:
必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据放到一块。
2.rowkey 长度原则
rowkey 是一个二进制码流,可以是任意字符串,最大长度 64kb,实际应用中一般为 10-100bytes,以 byte[] 形式保存,一般设计成定长。建议越短越好,不要超过 16 个字节, 原因如下:
数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 rowkey 过长会极大影响 HFile 的存储效率 MemStore 将缓存部分数据到内存,如果 rowkey 字段过长,内存的有效利用率就会降低,系统不能缓存更多的数据,这样会降低检索效率
3. rowkey 散列原则
如果 rowkey 按照时间戳的方式递增,不要将时间放在二进制码的前面,建议将 rowkey 的高位作为散列字段,由程序随机生成,低位放时间字段,这样将提高数据均衡分布在每个 RegionServer,以实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息,所有的数据都会集中在一个 RegionServer 上,这样在数据检索的时候负载会集中在个别的 RegionServer 上,造成热点问题,会降低查询效率。
4.Hbase的热点问题如何解决?
- 加盐
这里所说的加盐不是密码学中的加盐,而是在rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀以使得它和之前的rowkey的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,以避免热点。
- 哈希
哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一个行数据
- 反转
第三种防止热点的方法时反转固定长度或者数字格式的rowkey。这样可以使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。
反转rowkey的例子
以手机号为rowkey,可以将手机号反转后的字符串作为rowkey,这样的就避免了以手机号那样比较固定开头导致热点问题
- 时间戳反转
一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为rowkey的一部分对这个问题十分有用,可以用Long.Max_Value - timestamp追加到key的末尾,例如[key][reverse_timestamp],[key]的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中rowkey是有序的,第一条记录是最后录入的数据。
比如需要保存一个用户的操作记录,按照操作时间倒序排序,在设计rowkey的时候,可以这样设计
[userId反转][Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转后的userId,startRow是[userId反转][000000000000],stopRow是[userId反转][Long.Max_Value - timestamp]
如果需要查询某段时间的操作记录,startRow是[user反转][Long.Max_Value - 起始时间],stopRow是[userId反转][Long.Max_Value - 结束时间]
5.使用过的Hbase Api有哪些?
HBaseConfiguration.create()
conn = ConnectionFactory.createConnection(conf);
Admin admin = conn.getAdmin();
HTableDescriptor table = new HTableDescriptor(TableName.valueOf(tablename));
table.addFamily(columnfamily);
admin.createTable(table);
table.delete(delete);
table.getScanner(scan);
6.Hbase检索支持三种方式?
与nosql数据库们一样,row key是用来检索记录的主键。只有3中方式:
1 通过单个row key访问(get访问单行数据)
2 通过row key的range(访问某个区间内的rowkey,访问多行数据)
3 全表扫描 (scan访问全本的数据)