hbase--walgroup源码分析

本文介绍hbase的walgroup原理及实现

开启多wal

默认情况下,一个regionserver只有一个wal文件。 在HBase-5699之后,可以配置多个wal,在hbase-site.xml中,添加以下配置,既可开启多wal(同一个RS服务中):

<property>
    <name>hbase.wal.provider</name>
    <value>multiwal</value>
  </property>

具体有几个walgroup,实际是通过org.apache.hadoop.hbase.wal.BoundedGroupingStrategy#NUM_REGION_GROUPS的配置值来决定的,默认是org.apache.hadoop.hbase.wal.BoundedGroupingStrategy#DEFAULT_NUM_REGION_GROUPS=2

walgroup的格式为:providerId.regiongroup-0;providerId.regiongroup-1

hbase--walgroup源码分析

  1. 写入性能较单WAL提升20%
  2. hbase.wal.regiongrouping.strategy = bounded(分组策略)
  3. hbase.wal.regiongrouping.numgroups = 2(组数量,可以根据盘数设置,默认是2)

这里有两个概念,一个是walgroup,一个是regiongroup,这两个是对应的关系

RegionGrouping策略 RegionGroupingStrategy

hbase提供了RegionGroup的策略接口RegionGroupingStrategy,他有三个实现,默认实现是BoundedGroupingStrategy

hbase--walgroup源码分析

public static interface RegionGroupingStrategy {
    String GROUP_NAME_DELIMITER = ".";

    /**
     * Given an identifier and a namespace, pick a group.
     */
    String group(final byte[] identifier, byte[] namespace);
    void init(Configuration config, String providerId);
  }


BoundedGroupingStrategy中的默认实现:
public String group(byte[] identifier, byte[] namespace) {
    String idStr = Bytes.toString(identifier);

    //groupNameCache缓存了region到walgroup(或者说regiongroup)的映射关系。**

    // 这里是简单的轮询。
    //hbase集群重启以后,每个region对应的walgroup是会发生变化的。
    return computeIfAbsent(groupNameCache, idStr,
      () -> groupNames[getAndIncrAtomicInteger(counter, groupNames.length)]);
  }

NamespaceGroupingStrategy也是一个比较实用的策略。

可以通过配置hbase.wal.regiongrouping.strategy=bounded来指定分组策略,目前支持4中:
defaultStrategy(默认策略,与bounded相同),identity,bounded,namespace,对应类Strategies

static enum Strategies {
    defaultStrategy(BoundedGroupingStrategy.class),
    identity(IdentityGroupingStrategy.class),
    bounded(BoundedGroupingStrategy.class),
    namespace(NamespaceGroupingStrategy.class);

    final Class<? extends RegionGroupingStrategy> clazz;
    Strategies(Class<? extends RegionGroupingStrategy> clazz) {
      this.clazz = clazz;
    }
  }

策略修改以后,需要重启RS服务生效,所以,wals文件夹内的文件会迁移到oldwals中,然后RS开启时,根据策略重新在wals文件夹内生成新wal文件。sequence依然region级别递增。

初始化region时设置walGroup信息

hbase--walgroup源码分析

在开启hbase服务时,RS服务会打开region,在此过程中,按照配置,打开一定数量的wal日志文件。如果从单个wal修改为多个,原先的wal会被删除,取而代之的是一个WAL组,如上图。

打开创建wal的代码在org.apache.hadoop.hbase.wal.AsyncFSWALProvider#createWAL

protected AsyncFSWAL createWAL() throws IOException {
    //这里只会调用一次[每个wal创建一次],因为上层有缓存(org.apache.hadoop.hbase.wal.AbstractFSWALProvider.getWAL)
    return new AsyncFSWAL(CommonFSUtils.getWALFileSystem(conf), CommonFSUtils.getWALRootDir(conf),
        getWALDirectoryName(factory.factoryId),
        getWALArchiveDirectoryName(conf, factory.factoryId), conf, listeners, true, logPrefix,
        META_WAL_PROVIDER_ID.equals(providerId) ? META_WAL_PROVIDER_ID : null,
        eventLoopGroup, channelClass);
  }

在写文件时,如何获取wal对象呢?在org.apache.hadoop.hbase.wal.RegionGroupingProvider#getWAL(org.apache.hadoop.hbase.client.RegionInfo)中根据region信息获取wal

public WAL getWAL(RegionInfo region) throws IOException {
    String group;
    if (META_WAL_PROVIDER_ID.equals(this.providerId)) {
      group = META_WAL_GROUP_NAME;
    } else {
      byte[] id;
      byte[] namespace;
      if (region != null) {
        id = region.getEncodedNameAsBytes();
        namespace = region.getTable().getNamespace();
      } else {
        id = HConstants.EMPTY_BYTE_ARRAY;
        namespace = null;
      }

//下面strategy.group的实现就在org.apache.hadoop.hbase.wal.BoundedGroupingStrategy#group中,轮询获取wal
      group = strategy.group(id, namespace);
    }
    WAL wal = getWAL(group);

    return wal;
  }

在HFSLOG

hbase--walgroup源码分析hbase--walgroup源码分析 快乐崇拜234 博客专家 发布了212 篇原创文章 · 获赞 209 · 访问量 89万+ 他的留言板 关注
上一篇:FATE


下一篇:FATE