Hbase Compression的配置与生效

0. 问题

最近碰到一个问题:

hbase使用bulkload方式, 两次把全量数据load到hbase表,并且手动进行大合并,发现hbfile的大小差不多变成2倍了(表的version设置为1了),因为version为1,所以同样的数据load两次+大合并应该是只有1份数据,而且文件大小应该是第一次的大小

排查方案:

新发现 假设 排查方法 结果
有多份数据存在? 根据key来查数据,看是不是能查出来多个版本的数据 只有1个版本的数据
发现做hfile的时候,生成KeyValue的时候使用的时间戳都是同一个值HConstants.LATEST_TIMESTAMP 是不是因为timestampe值相同,造成大合并的时候相同的数据无法删除 生成KeyValue的时候使用当前的时间戳,再导2次数据+大合并 文件还是2倍,但是导第三次的时候+大合并,文件保持了2倍
合并完的hfile多了BloomFilter部分多数据 BloomFilter的部分造成数据double hbase hfile -m -f path 直接看出BloomFilter部分的大小 直接排除
注意到我们的hfile的compress的值为none,但我们建表带时候指定了压缩格式为SNAPPY,而且hbase UI上看到的属性为: {NAME=>c}, 而不是 {NAME=>'c', COMPRESSION=>'SNAPPY'} 数据没有启用压缩 使用alter命令修改压缩格式+大合并 文件大小减小到一半

当然在中间过程中查看了一些源码,但没啥效果

1. 原因

1. 代码美学反推

建表的时候压缩格式的设置没有起作用,当时的设置属性的语句:

val tableDescriptor = new HTableDescriptor(table)
tableDescriptor.addFamily(new HColumnDescriptor(familyName))
tableDescriptor.setConfiguration("COMPRESSION", "SNAPPY")
tableDescriptor.setConfiguration("VERSIONS", "1")
tableDescriptor.setConfiguration("BLOCKCACHE", "FALSE")
tableDescriptor.setConfiguration("BLOOMFILTER", "ROW")
tableDescriptor.setConfiguration("DATA_BLOCK_ENCODING", "FAST_DIFF")

当时在查这段代码的时候,有点奇怪,因为HTableDescriptor居然没有直接设置这些属性的方法,后来才明白,原来用的有问题,正确的版本应该是:

val columnDescriptor = new HColumnDescriptor(familyName)
columnDescriptor.setCompressionType(Compression.Algorithm.SNAPPY)
// 还有另一个API是设置大合并的压缩格式的,没有设置的时候,使用的是列簇的压缩格式
tableDescriptor.addFamily(columnDescriptor)

当看到这个版本的代码之后,瞬间觉得这个是对的,而且这个API特别方便,不像第一个需要指定字符串,这种hard-code的东西果然容易出问题,因为再不济应该有类似这样的常量或者枚举出现才好:

val CompressionType = "COMPRESSION"

为啥不把默认格式压缩格式设置为SNAPPY呢?

2. hbase设计原理

只能说代码里面将HColumnDescriptorHTableDescriptor做了区分,而且压缩格式是以列簇来指定的,这样更灵活,当然也更麻烦一点

2. 修复问题

alter 'table', {NAME='c', COMPRESSION='snappy'}
major_compact 'table'

那么问题来了, 修改表压缩格式的时候,是否需要disable表,当前表为只有读操作

你可能感兴趣的:(Hbase Compression的配置与生效)