【问题标题】:Hbase number of regions keep growingHbase 区域数量不断增长
【发布时间】:2017-02-02 01:00:57
【问题描述】:

我们使用的是 hbase 1.1.4 版。数据库有大约 40 个表,每个表数据都有一个 TimeToLive 指定。部署在5节点集群上,下面是hbase-site.xml

<property>
<name>phoenix.query.threadPoolSize</name>
<value>2048</value>
</property>

<property>
<name>hbase.hregion.max.filesize</name>
<value>21474836480</value>
</property>

<property>
<name>hbase.hregion.memstore.block.multiplier</name>
<value>4</value>
</property>
<!-- default is 64MB 67108864 -->
<property>
<name>hbase.hregion.memstore.flush.size</name>
<value>536870912</value>
</property>
<!-- default is 7, should be at least 2x compactionThreshold -->
<property>
<name>hbase.hstore.blockingStoreFiles</name>
<value>240</value>
</property>
<property>
<name>hbase.client.scanner.caching</name>
<value>10000</value>
</property>

<property>
<name>hbase.bucketcache.ioengine</name>
<value>offheap</value>
</property>
<property>
<name>hbase.bucketcache.size</name>
<value>40960</value>
</property>

问题是每个区域服务器上的区域数量不断增长。目前我们只使用合并区域

merge_region in the hbase shell.

有没有办法让每台服务器上只有固定数量的区域,或者自动合并区域?

【问题讨论】:

    标签: hadoop apache-spark hbase


    【解决方案1】:

    有没有办法让每个区域只有固定数量的区域 服务器,还是自动合并区域的方式?

    我实现这一点的一种方法是创建带有预分割区域的表。例如

    create 'test_table', 'f1', SPLITS=> ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    

    设计好的rowkey从1-9开始

    您可以使用如下所示的番石榴杂音哈希。

    import com.google.common.hash.HashCode;
    import com.google.common.hash.HashFunction;
    import com.google.common.hash.Hashing;
    
    /**
         * getMurmurHash.
         * 
         * @param content
         * @return HashCode
         */
        public static HashCode getMurmurHash(String content) {
            final HashFunction hf = Hashing.murmur3_128();
            final HashCode hc = hf.newHasher().putString(content, Charsets.UTF_8).hash();
            return hc;
        }
    
    final long hash = getMurmur128Hash(Bytes.toString(yourrowkey as string)).asLong();
                final int prefix = Math.abs((int) hash % 9);
    

    现在将此前缀附加到您的行键

    例如

    1rowkey1 // 将进入第一个区域
    2rowkey2 // 将进入第二个区域
    3rowkey3 // 将进入第三个区域
    ...
    9rowkey9 // 将进入第九个区域

    如果您正在进行预拆分,并且想要手动管理区域拆分,您还可以禁用区域拆分,方法是将 hbase.hregion.max.filesize 设置为较高的数字并将拆分策略设置为 ConstantSizeRegionSplitPolicy。但是,您应该使用像 100GB 这样的安全值,这样区域就不会超出区域服务器的能力。您可以考虑禁用自动拆分并依赖于预拆分的初始区域集,例如,如果您对键前缀使用统一哈希,您可以确保每个区域的读/写负载及其大小在表中的区域之间是统一的。

    另外,看at

    【讨论】:

    • 用 murmur 128 hash 和 guava api 更新了我的答案,确保了均匀分布的哈希码
    • 我现在禁用了拆分,需要等待一天才能看到区域的增长是否停止。
    【解决方案2】:

    这主要取决于您的数据:它是如何跨键分布的。假设您的值对于所有键的大小几乎相同,您可以使用分区:

    例如,如果您的表键是 String 并且您想要 100 个区域,请使用此

    public static byte[] hashKey(String key) {
        int partition = Math.abs(key.hashCode() % 100);
        String prefix = partitionPrefix(partition);
        return Bytes.add(Bytes.toBytes(prefix), ZERO_BYTE, key);
    }
    
    public static String partitionPrefix(int partition) {
        return StringUtils.leftPad(String.valueOf(partition), 2, '0');
    }
    

    在这种情况下,您所有的键都将以数字 00-99 开头,因此您有 100 个分区用于 100 个区域。现在您可以禁用区域拆分:

    HTableDescriptor td = new HTableDescriptor(TableName.valueOf("myTable"));
    td.setRegionSplitPolicyClassName("org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy");
    

    或通过外壳

    alter 'myTable', {TABLE_ATTRIBUTES => {METADATA => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy'}}
    

    【讨论】:

    • 我现在已经禁用了拆分。已经有分割区域的表呢?
    • @sparkDabbler 如果您决定使用分区,则必须将数据传输到新表然后替换它们。如果您只禁用拆分,区域数量将保持不变,但您的区域将不平衡
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多