hbase中通过编写coprocessor来控制表的compaction

在hbase中,compaction是一个很费性能的操作,对于实时性要求较高的场景,需要精确的控制某个表的major compaction和minor compaction,尽可能地在流量低谷进行,在流量高峰期减少甚至完全禁用major compaction。

1. 通过调整配置文件中参数来设置

将hbase-site.xml中hbase.hregion.majorcompaction 参数设置的较大,如7天,也可以设置为0直接禁用major compaction。默认是1天进行一次major compaction。配置如下:

<property>
    <name>hbase.hregion.majorcompaction</name>
    <value>604800000</value>
    <description>The time (in miliseconds) between 'major' compactions of all
    HStoreFiles in a region.  Default: 1 day.
    Set to 0 to disable automated major compactions.
    </description>
  </property>

然后可以每天在集群负载较低的时候触发某个表的major compaction:

echo "major_compact 'auction_table'" | /home/baoniu/hadoop_hbase/hbase/bin/hbase shell  >>/home/baoniu/logs/major_compact.log 2>&amp;1

此外还有不少和compaction相关的参数,如  hbase.regionserver.thread.compaction.small, hbase.regionserver.thread.compaction.large, hbase.regionserver.thread.compaction.throttle  等可以更精确的控制major和minor compaction的过程。

2. 通过coprocessor

hbase中coprocessor的功能类似于数据库中的触发器(trigger),详见官方wiki。示例代码如下:

public class DisableCompaction extends BaseRegionObserver {
    private static final Log logger = LogFactory.getLog(DisableCompaction.class);
    ......
    public void preCompactSelection(ObserverContext<RegionCoprocessorEnvironment> c, Store store, List<StoreFile> candidates)
            throws IOException {
        HRegion region = c.getEnvironment().getRegion();
        Configuration conf = c.getEnvironment().getConfiguration();

        logger.info("arg1=" + conf.get("arg1"));
        logger.info("arg2=" + conf.get("arg2"));
        logger.info("tableName=" + region.getTableDesc().getNameAsString());

        // if (region.getTableDesc().getNameAsString().equals("auction_table")) {
        for (Iterator<StoreFile> iterator = candidates.iterator(); iterator.hasNext();) {
            StoreFile storeFile = (StoreFile) iterator.next();
            long now = System.currentTimeMillis();
            logger.info("nowTime=" + now + " gmt=" + storeFile.getModificationTimeStamp());
            if (now - storeFile.getModificationTimeStamp() > 3600 * 1000) {
                iterator.remove();
                logger.info("remove storefile " + storeFile.getPath());
            }
        }
        // }
    }
    ......
}

这个coprocessor的作用是对表中一个小时之前的数据不进行compaction,需要根据具体业务场景来决定。其中对于表名时间 3600*1000 的判断可以在配置表的coprocessor时从外界通过参数arg1传入。

如下是对某个表配置coprocessor:

disable 'auction_table'
alter 'uic',METHOD=>'table_att',
'coprocessor'=>'hdfs://hadoop1:9000/test/myCoprocessor.jar
|com.instant.tool.DisableCompaction|101|arg1=3600'
enable 'auction_table'

也可以在hbase-site.xml中配置对整个集群生效:

<property>
    <name>hbase.coprocessor.region.classes</name>
    <value>com.instant.tool.DisableCompaction</value>
</property>

这种情况下需要将myCoprocessor.jar分发到每台region server的hbase classpath中。
参考:https://blogs.apache.org/hbase/entry/coprocessor_introduction
http://www.yankay.com/wp-cont/hbase/book.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注