预分区
create 'user', 'info', SPLITS => ['1001', '2001', '3001', '4001']
在创建表的时候提前创建多个空region,提前预估每个region开始和结束的rowkey,尽量使设计的rowkey能均匀命中各个region(region split分裂的时候始终会占用系统IO资源)。
Rowkey
Rowkey底层存储是一个二进制流,可以是任意字符串,最大长度 64kb ,实际应用中一般是10-100字节,以 byte[] 形式保存,一般设计为定长,Rowkey越短越好,一般建议不要超过16字节(Rowkey越小缓存可以存放的数据越多,操作系统一般为64位,内存8字节对齐);
Rowkey需要尽量散列,避免数据热点问题(与预分区一起规划考虑);
Rowkey是Hbase里面唯一的索引,对于某些查询频繁的限定条件可以把它的内容存放在Rowkey里面,提高查询效率。列族
在设计列族的时候,建议把经常读取的字段存储到一个列族中,不经常读取的字段放到另一个列族中。
这样在读取部分数据的时候,就只需要读取一个列族文件即可,可以提高读取效率。 2.列族设置
生存时间(TTL-单位为秒)
create 'user', {NAME => 'info', TTL => '18000'}
当系统在某些场景下需要删除历史数据时,可以通过配置TTL来设置数据的存放时间,过期的数据会在大合并的时候被真正删除;
版本数
create 'user', {NAME => 'info', VERSIONS => 3}
在0.96版本之前默认每个列族有3个version,0.96之后默认每个列族有一个版本,在大合并时会删除掉过期的版本数据;
压缩
create 'user',{NAME => 'info', COMPRESSION => 'SNAPPY'}
HFile可以被压缩存放在HDFS上,这样有助于节省硬盘IO,但是读写数据时的压缩和解压会额外占用CPU的利用率;
压缩是表定义的一部分,可以在建表或者修改表结构时设定;
在正式的生产环境中建议打开表的压缩;
Hbase可以使用的压缩编码包括LZO、SNAPPY和GZIP;
综合来看,Snappy的压缩率最低,但是编解码速率最高,对CPU的消耗也最小,目前一般建议使用Snappy。
数据块(BLOCKSIZE)大小的配置(单位为字节)
create 'user',{NAME => 'info', BLOCKSIZE => '65537'}
随机查询:数据块越小,索引越大,查询性能越好;
顺序查询:更好的顺序扫描,需要更大的数据块;
在实际使用的时候还是要根据实际业务来定。
数据块缓存
create 'user',{NAME => 'info', BLOCKCACHE => 'false'}
如果一张表或表里的某个列族只被顺序访问或很少被访问,这个时候就算get或scan花费的时间长点也是没关系的,这种情况下,可以关闭那些表或者列族的缓存,否则当程序执行很多顺序访问的时候不但会多次操作缓存,而且还会把应该存放在缓存的数据给挤出缓存。
布隆过滤器(Bloom filters)
create 'user',{NAME => 'info', BLOOMFILTER => 'ROWCOL'}
Hbase中存储额外的索引会占用额外的空间。布隆过滤器随着它们的索引对象的数据增长而增长,所以行级布隆过滤器比列标识符级布隆过滤器占用空间要少。
BLOOMFILTER参数的默认值是ROW,表示是行级布隆过滤器。
使用行级布隆过滤器需要设置为ROW,使用列标识符级布隆过滤器需要设置为ROWCOL。
行级布隆过滤器在数据块里检查特定行键是否不存在,列标识符级布隆过滤器检查行和列标识符联合体是否不存在。
ROWCOL布隆过滤器的开销要高于ROW布隆过滤器。
hbase.hregion.majorcompaction
大合并的间隔时间,默认为604800000毫秒(7天),如果设置为0则表示禁止自动的大合并,大合并的执行可能会持续数小时,为了减少对业务的影响,最好在业务低峰期进行手动或者通过API手动触发进行大合并。hbase.hregion.max.filesize
默认为10737418240 Byte(10G),当Region达到这个阈值时,会自动分裂。Region分裂会有短暂的Region下线时间(通常在5s以内),为减少对业务端的影响,建议调大该值,并在业务低峰期定时手动进行分裂。hbase.regionserver.handler.count
该配置参数用于定义regionserver上用于等待响应用户表级请求的线程数,默认30,对于大负载的Put(达到了M范围)或是大范围的Scan操作,handler数目不易过大,易造成OOM(内存溢出)。 对于小负载的put、get,delete等操作,handler数要适当调大。hbase.hregion.memstore.flush.size
默认值134217728 Byte (128M),单位字节,这个参数是Memstore中数据持久化到Storefile的时机,超过该阈值,则会把Memstore中的数据持久化到Storefile中,如果Regionserver的JVM内存比较充足(例如:16G以上),可以适当调大该值,例如:调整为256M。这样可以减少Memstore中数据溢写文件的次数。hbase.hregion.memstore.block.multiplier
默认值4,当一个 Region 中所有 MemStore 总大小达到或超过hbase.hregion.memstore.flush.size * hbase.hregion.memstore.block.multiplier,则会阻塞该Region所有的写操作(当一个 MemStore 大小达到阈值 hbase.hregion.memstore.flush.size(默认128M)时,会触发 MemStore 的刷写。但是这个时候不会阻塞写请求),为避免阻塞,可以适当调大,例如6~8,但如果太大,则会有OOM的风险。 如果在Regionserver日志中出现"Blocking updates for ‘’ on region : memstore size <多少M> is >= than blocking <多少M> size"的信息时,说明这个值该调整了。hbase.hstore.compaction.min
默认值为3,如果任何一个Store里的Storefile总数超过该值,会触发默认的合并操作,可以设置5~8,在手动的定期大合并中进行Storefile文件的合并,减少合并的次数,不过这会延长合并的时间。