本文介绍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
- 写入性能较单WAL提升20%
- hbase.wal.regiongrouping.strategy = bounded(分组策略)
- hbase.wal.regiongrouping.numgroups = 2(组数量,可以根据盘数设置,默认是2)
这里有两个概念,一个是walgroup,一个是regiongroup,这两个是对应的关系
RegionGrouping策略 RegionGroupingStrategy
hbase提供了RegionGroup的策略接口RegionGroupingStrategy
,他有三个实现,默认实现是BoundedGroupingStrategy
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服务时,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
快乐崇拜234 博客专家 发布了212 篇原创文章 · 获赞 209 · 访问量 89万+ 关注