HBase模式设计是需要注意的问题:
1.设计准则
1)行键设计
读访问模式:通过行键索引提升查询效率。
HBase中唯一可用的索引只有行键索引,需要对行键精心设计来尽可能地优化数据查询。
某项数据放在行键中会得到更好的查询性能,但是行键的长度变长,行键索引会占用更多的内存资源,由于行键在每个列族中保存,也会需要更多的磁盘空间。
写访问模式:避免同一时间段里写入的数据形成热点。
随机前缀:在原先彼此相邻的行键前面加上一个随机生成的前缀。
哈希前缀:针对随机前缀生成的行键具有不确定性的缺陷,哈希前缀做了改进,通过对原行键调用选定的哈希函数生成前缀。
反转键:将原先彼此相邻的行键按字节序反转生成新的行键。
以上几种策略都会失去数据按特定行键顺序存放的特性,在进行范围查询时需要访问全部索引数据且需要有更多的磁盘IO操作,对性能影响很大。最理想的行键设计方法是既能让有关联的数据集中在一起存放,又能达到写负载均衡的目的。
写访问模式:避免同一时间段里写入的数据形成热点。
随机前缀:在原先彼此相邻的行键前面加上一个随机生成的前缀。
哈希前缀:针对随机前缀生成的行键具有不确定性的缺陷,哈希前缀做了改进,通过对原行键调用选定的哈希函数生成前缀。
反转键:将原先彼此相邻的行键按字节序反转生成新的行键。
以上几种策略都会失去数据按特定行键顺序存放的特性,在进行范围查询时需要访问全部索引数据且需要有更多的磁盘IO操作,对性能影响很大。最理想的行键设计方法是既能让有关联的数据集中在一起存放,又能达到写负载均衡的目的。
2)列族划分
每张表的列族数能少则少,尽量不超过三个。
将有相同访问模式的所有数据存储在同一列族,不同访问模式的数据存储在不同列族,并在列族属性中定义好访问模式。
如果某些列数据经常被一起访问而不需要访问其他列的数据,可考虑将这些列划分为一个列族。
列族和列的名字应尽量短,建议列族名用一个字母表示,列修饰符用少数几个字母表示。
为了提高读性能,可进行反规范化设计,即在多张表中储存冗余数据。冗余设计会对写性能有影响,也会加大应用程序的复杂度。
HBase不支持跨行事务,所以在列族设计时要避免一个事务涉及多行数据。
3)数据量估算和控制
每个单元的大小最好不超过100K,如果超过100K应考虑使用MOB(Medium-sized Objects)文件存储,如果超过50M则应考虑将数据保存在HDFS文件中,在HBase中仅保存文件的访问路径。
每个HRegion的大小最好在10G到50G之间。
每张表的HRegion数量不超过100个为宜。
在创建表的时候预估数据量,据此预分配足够数量的HRegion,从而避免或减少日后对HRegion的拆分。
对于不需要长期保存的数据,设置合理的数据过期时间。
版本数量尽可能设置得小一些或使用默认值1。
如果表中储存的是基于时间的设备数据或日志信息,可将行键设计为设备ID/服务ID加上时间。
4)内存需求估算和配置
内存需求。集群中所有MemStore合计所需的最大内存通过下列公式估算:
MemStore大小 * HRegion数量 * 每个HRegion中平均列族数
内存供给。集群参数hbase.regionserver.global.memstore.size配置了每个HRegionServer允许的所有MemStore合计大小上限,该配置值乘以HRegionServer数量即为整个集群的内存供给。
如果因为HRegion数量过大造成MemStore内存需求远大于实际内存供给,则会导致系统频繁地进行MemStore存盘操作而影响性能。
2.列族属性
BLOOMFILTER:定义布隆过滤器类型,默认为ROW。
NONE:表示不使用布隆过滤。
ROW:表示使用基于行的布隆过滤。
ROWCOL:表示使用基于行和列的布隆过滤。
COMPRESSION:是否以压缩方式在磁盘上存储列族数据及压缩编码格式,默认值为NONE。
NONE:表示不压缩。
GZ:表示采用GZ压缩算法。
LZ4:表示采用LZ4压缩算法,该算法在Hadoop库中提供。
LZO:表示采用LZO压缩算法,该算法库需由用户自行安装。
SNAPPY:表示采用SNAPPY压缩算法,该算法库需由用户自行安装。
DATA_BLOCK_ENCODING:定义数据块编码格式,默认值为NONE。
NONE:表示不使用压缩编码格式。
PREFIX:表示使用前缀编码格式。
DIFF:表示使用差异编码格式。
FAST_DIFF:表示使用快速差异编码格式。
PREFIX_TREE:表示采用前缀树编码格式。
VERSIONS:定义列族单元保存的数据版本数量,默认值为1。
MIN_VERSIONS:定义列族存储的最少版本数,默认值为0。
TTL:定义数据的生存时间,以秒为单位,默认值为FOREVER,表示永远不过期。
KEEP_DELETED_CELLS:定义在主压缩时是否清除带有删除标志的数据以及在查询时是否返回带有删除标志的数据,默认值为false。
BLOCKSIZE:定义HFile数据块的大小,默认值为64K。
BLOCKCACHE:定义是否在内存中缓存数据块,默认值为true。
IN_MEMORY:定义列族是否优先放入块缓存中,默认值为false。
REPLICATION_SCOPE:定义列族是否在其他HBase集群中复制以及复制份数,默认值为0,表示不在其他集群中复制。
3.表属性
SPLITS、SPLITS_FILE、NUMREGIONS、SPLITALGO:对表进行预拆分,有如下预拆分方法:
提供拆分点数组,对应的表属性为SPLITS 。
将拆分点保存在文本文件中,对应的表属性为SPLITS_FILE 。
通过给出HRegion数量和拆分算法来自动计算出拆分点,对应的表属性分别是NUMREGIONS和SPLITALGO。
READONLY:定义只读表。
DURABILITY :定义WAL日志的持久化策略,默认值为USE_DEFAULT。
SYNC_WAL:表示采用同步方式写WAL日志。
ASYNC_WAL:表示采用异步方式写WAL日志。
FSYNC_WAL:表示采用同步方式写WAL日志,并且强制将WAL刷新到磁盘上。
SKIP_WAL:表示不写入WAL日志。
USE_DEFAULT:表示使用HBase的全局默认值SYNC_WAL。
MAX_FILESIZE:定义该表的每个HRegion中所有HFile合计大小上限,默认值为集群配置项hbase.hregion.max.filesize的配置值。
MEMSTORE_FLUSHSIZE:定义表的MemStore大小上限,默认值为集群配置项hbase.hregion.memstore.flush.size的配置值。
4.设计实例
电商平台应用需要解决的问题有以下几类:
统计每类商品或每款商品的销售情况。
查询每类商品或每款商品的购买客户列表,以便对购买人群进行特征分析。
查询某个客户购买的商品列表,以便分析其个人喜好。
根据应用需求设计出以下四张表:
customer:客户表,只有一个列族c,GZ方式压缩存储,PREFIX编码格式。
goods:商品表,只有一个列族g, GZ方式压缩存储,PREFIX编码格式,IN_MEMROY属性为true,VERSIONS属性为10。预拆分成10个HRegion。
order:订单表,有两个列族o和c,其中列族o保存订单信息,列族c保存对购买人群进行特征分析所需的客户信息。订单表采取了和商品表同样的拆分方法预拆分为10个HRegion。
customer_order:客户购买记录表,以客户ID+商品ID+订单时间戳为行键,专门供分析个体客户的个人喜好使用,只有一个列族g保存分析客户喜好所需的那部分信息。