HBASE–数据的删除和切分

数据的删除

数据的真正删除发生在两个部分:flush和compaction

flush

当对一个RowKey的数据进行两次写入的时候,这两条记录都在内存中还未flush进磁盘。当flush过后,时间戳在前的数据就会被删掉。

put 'stu','1001','info:name','eatfish'
put 'stu','1001','info:name','fish'
这时候使用:
scan 'stu',{ROW=>TRUE,VERSION=>10}
会显示两条记录
这时候:
flush
再使用:
scan 'stu',{ROW=>TRUE,VERSION=>10}
就只有一条数据了,第一次输入的数据已经被删除了
这时候再改一次:
put 'stu','1001','info:name','eat'
flush
scan 'stu',{ROW=>TRUE,VERSION=>10}
这时候可以看到两条数据,fish的那条是不会被删除的

所以一次内存的flush对应一个文件,当内存中被flush时,会删掉相同RowKey过时的数据,也就是flush只删除相同文件中的过时数据。
已经flush的数据(不同文件)的删除和整理,在下面的合并中才会进行。

StoreFile Compaction

由于内存每次刷写都会产生一个HFile,太多了就不好处理,就要进行StoreFile Compaction。
Compaction分为两种,一种是Minor Compaction:将临近的若干个小的HFile合并成一个较大的HFile,不清理过期和删除的数据;另一种是Major Compaction会将一个Store下的所有HFile合并成一个大的HFile,会清理掉过期和删除的数据。

  • 大合并在系统默认触发的时间是7天,建议关闭(value设为0,在hbase-default.xml文件),在系统空余时间手动开启。
  • 小合并合并的HFile的值默认是(more than 3)源码中的的意思就是大于等于3的情况的就会触发合并。

tips:

  • 关于delete,当delete一个数据之后,会对这个RowKey增加一个删除标记。当flush的时候会直接把内存中现有的这个RowKey的数据直接删掉,再进行flush。但是删除标记要跟着flush进磁盘,然后在大合并的过程中才进行删除。
    因为磁盘中可能还存在这个RowKey的数据,如果不把删除标记flush进磁盘,下一次scan的时候,就会把之前应该被覆盖掉的数据显示出来,这样删除数据等同于失败。

切分

默认的切分会造成数据倾斜问题,所以在建表的时候要进行预分区。
默认的切法是:

Min(R^2*"hbase.hregion.memstore.flush.size","hbase.hregion.max.filesize"

当某个store下所有的StoreFlie总大小超过上面的值就进行拆分,其中hbase.hregion.memstore.flush.size=128M,R是现有的分区数,hbase.hregion.max.filesize=10G。
所以一些分区的总大小可能会一直增大,有些分区的总大小可能会不变。