命名空间
概念
在HBase有很多张表,这些表需要按照业务划分开,为方便管理这些表,不同业务就有不同的名称空间,
类似Hive中的数据库,不同的数据库用来存储不同类型的表。
注:
- HBase默认的名称空间是「default」,默认情况下,创建表时表都将创建在 default 名称空间下
- HBase中还有一个命名空间「hbase」,用于存放系统的内建表(namespace、meta)
语法
创建命名空间:
create_namespace 'MOMO_CHAT'
查看命名空间列表:
list_namespace
查看命名空间:
describe_namespace 'MOMO_CHAT'
命名空间创建表:
在命令MOMO_CHAT命名空间下创建名为:MSG的表,该表包含一个名为C1的列蔟。
注意:带有命名空间的表,使用冒号将命名空间和表名连接到一起。
create 'MOMO_CHAT:MSG','C1'
删除命名空间:
删除命名空间,命名空间中必须没有表,如果命名空间中有表,是无法删除的
drop_namespace 'MOMO_CHAT'
列簇设计
- 设计目的
- 提高读取性能
- 设计原则
个数原则
- HBase列蔟的数量应该越少越好
- 两个及以上的列蔟HBase性能并不是很好
- 一个列蔟所存储的数据达到flush的阈值时,表中所有列蔟将同时进行flush操作,这将带来不必要的I/O开销,列蔟越多,对性能影响越大
长度原则
- 列簇名过长,会导致在内存和硬盘中占用多余的空间,导致性能下降
- Hbase底层数据结构
版本设计
- 按照项目需求确定数据更新后是否保存历史数据
- 需要保存历史数据设置版本>1,否则设置版本=1
- HBase默认创建表的版本为1
查看表的版本信息:
查看命名空间MOMO_CHAT中的MSG表信息:
describe "MOMO_CHAT:MSG"
通过输出可以看到:
- 版本是相对于列蔟而言
- 默认列蔟的版本数为1
数据压缩
压缩算法
在HBase可以使用多种压缩编码,包括LZO、SNAPPY、GZIP。只在硬盘压缩,内存中或者网络传输中没有压缩。
- GZIP的压缩率最高,但是其实CPU密集型的,对CPU的消耗比其他算法要多,压缩和解压速度也慢;
- LZO的压缩率居中,比GZIP要低一些,但是压缩和解压速度明显要比GZIP快很多,其中解压速度快的更多;
- Zippy/Snappy的压缩率最低,而压缩和解压速度要稍微比LZO要快一些
查看表数据压缩方式
查看命名空间MOMO_CHAT中的MSG表信息:
escribe "MOMO_CHAT:MSG"
通过输出可以看出,HBase创建表默认是没有指定压缩算法的
设置数据压缩
创建新的表,并指定数据压缩算法:
create "MOMO_CHAT:MSG", {NAME => "C1", COMPRESSION => "GZ"}
修改已有的表,并指定数据压缩算法:
alter "MOMO_CHAT:MSG", {NAME => "C1", COMPRESSION => "GZ"}
ROWKEY设计原则
HBase设计原则(六大原则)
业务原则:用最常见的查询条件作为rowkey
目的:尽量走索引查询
唯一原则:每条Rowkey是不能重复
目的:唯一标识一条数据
- 设计ROWKEY时,必须保证RowKey的唯一性
- 由于在HBase中数据存储是Key-Value形式,若向HBase中同一张表插入相同RowKey的数据,则原先存在的数据会被新的数据覆盖。
组合原则:将最常用的几个查询条件组合构建Rowkey
目的:尽量大部分查询都走索引
散列原则:Rowkey整体或者前缀不能是连续的,需要构建随机的散列
目的:避免热点问题
- 避免使用递增行键/时序数据
如果ROWKEY设计的都是按照顺序递增(例如:时间戳),这样会有很多的数据写入时,负载都在一台机器上。我们尽量应当将写入大压力均衡到各个RegionServer
长度原则:在满足业务需求情况下,越短越好
目的:提高性能
- Rowkey本身每列都会存储:存储占用的空间越大
- Rowkey会构建索引:内存的占用越大,比较就越慢
- 使用long等类型比String类型更省空间
long类型为8个字节,8个字节可以保存非常大的无符号整数,例如:18446744073709551615。如果是字符串,是按照一个字节一个字符方式保存,需要快3倍的字节数存储。
避免数据热点
- 热点是指大量的客户端(client)直接访问集群的一个或者几个节点(可能是读、也可能是写)
- 大量地访问量可能会使得某个服务器节点超出承受能力,导致整个RegionServer的性能下降,其他的Region也会受影响
预分区:
- 默认情况:一个HBase的表只有一个Region,被托管在一个RegionServer中
- 如果只有一个Region,那么Start Key、End Key都是空的,没有边界。所有的数据都会放在这个Region中,但当数据越来越大时,会将Region分裂,取一个Mid Key来分裂成两个Region
- 预分区个数 = 节点的倍数。默认Region的大小为10G,假设我们预估1年下来的大小为10T,则10000G / 10G = 1000个Region,所以,我们可以预设为1000个Region,这样,1000个Region将均衡地分布在各个节点上
ROWKEY避免热点设计
- 反转策略
- 如果设计出的ROWKEY在数据分布上不均匀,但ROWKEY尾部的数据却呈现出了良好的随机性,可以考虑将ROWKEY的翻转,或者直接将尾部的bytes提前到ROWKEY的开头。
- 反转策略可以使ROWKEY随机分布,但是牺牲了ROWKEY的有序性
- 缺点:利于Get操作,但不利于Scan操作,因为数据在原ROWKEY上的自然顺序已经被打乱
- 加盐策略
- Salting(加盐)的原理是在原ROWKEY的前面添加固定长度的随机数,也就是给ROWKEY分配一个随机前缀使它和之间的ROWKEY的开头不同
- 随机数能保障数据在所有Regions间的负载均衡
- 缺点:因为添加的是随机数,基于原ROWKEY查询时无法知道随机数是什么,那样在查询的时候就需要去各个可能的Regions中查找,加盐对比读取是无力的
- 哈希策略
- 基于 ROWKEY的完整或部分数据进行 Hash,而后将Hashing后的值完整替换或部分替换原ROWKEY的前缀部分
- 这里说的 hash 包含 MD5、sha1、sha256 或 sha512 等算法
- 缺点:Hashing 也不利于 Scan,因为打乱了原RowKey的自然顺序