Skip to content

Commit d0f6883

Browse files
bharathvndimiduk
authored andcommitted
HBASE-23281: Track meta region locations in masters (#830)
* HBASE-23281: Track meta region changes on masters This patch adds a simple cache that tracks the meta region replica locations. It keeps an eye on the region movements so that the cached locations are not stale. This information is used for servicing client RPCs for connections that use master based registry (HBASE-18095). The RPC end points will be added in a separate patch. Signed-off-by: Nick Dimiduk <ndimiduk@apache.org>
1 parent e7ebaea commit d0f6883

23 files changed

+586
-86
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/ProtobufUtil.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -80,6 +80,7 @@
8080
import org.apache.hadoop.hbase.client.Put;
8181
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
8282
import org.apache.hadoop.hbase.client.RegionLoadStats;
83+
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
8384
import org.apache.hadoop.hbase.client.RegionStatesCount;
8485
import org.apache.hadoop.hbase.client.Result;
8586
import org.apache.hadoop.hbase.client.Scan;
@@ -93,6 +94,7 @@
9394
import org.apache.hadoop.hbase.filter.ByteArrayComparable;
9495
import org.apache.hadoop.hbase.filter.Filter;
9596
import org.apache.hadoop.hbase.io.TimeRange;
97+
import org.apache.hadoop.hbase.master.RegionState;
9698
import org.apache.hadoop.hbase.protobuf.ProtobufMagic;
9799
import org.apache.hadoop.hbase.protobuf.ProtobufMessageConverter;
98100
import org.apache.hadoop.hbase.quotas.QuotaScope;
@@ -3059,6 +3061,44 @@ public static ProcedureDescription buildProcedureDescription(String signature, S
30593061
return builder.build();
30603062
}
30613063

3064+
/**
3065+
* Get the Meta region state from the passed data bytes. Can handle both old and new style
3066+
* server names.
3067+
* @param data protobuf serialized data with meta server name.
3068+
* @param replicaId replica ID for this region
3069+
* @return RegionState instance corresponding to the serialized data.
3070+
* @throws DeserializationException if the data is invalid.
3071+
*/
3072+
public static RegionState parseMetaRegionStateFrom(final byte[] data, int replicaId)
3073+
throws DeserializationException {
3074+
RegionState.State state = RegionState.State.OPEN;
3075+
ServerName serverName;
3076+
if (data != null && data.length > 0 && ProtobufUtil.isPBMagicPrefix(data)) {
3077+
try {
3078+
int prefixLen = ProtobufUtil.lengthOfPBMagic();
3079+
ZooKeeperProtos.MetaRegionServer rl =
3080+
ZooKeeperProtos.MetaRegionServer.parser().parseFrom(data, prefixLen,
3081+
data.length - prefixLen);
3082+
if (rl.hasState()) {
3083+
state = RegionState.State.convert(rl.getState());
3084+
}
3085+
HBaseProtos.ServerName sn = rl.getServer();
3086+
serverName = ServerName.valueOf(
3087+
sn.getHostName(), sn.getPort(), sn.getStartCode());
3088+
} catch (InvalidProtocolBufferException e) {
3089+
throw new DeserializationException("Unable to parse meta region location");
3090+
}
3091+
} else {
3092+
// old style of meta region location?
3093+
serverName = parseServerNameFrom(data);
3094+
}
3095+
if (serverName == null) {
3096+
state = RegionState.State.OFFLINE;
3097+
}
3098+
return new RegionState(RegionReplicaUtil.getRegionInfoForReplica(
3099+
RegionInfoBuilder.FIRST_META_REGIONINFO, replicaId), state, serverName);
3100+
}
3101+
30623102
/**
30633103
* Get a ServerName from the passed in data bytes.
30643104
* @param data Data with a serialize server name in it; can handle the old style

hbase-client/src/main/java/org/apache/hadoop/hbase/zookeeper/ZNodePaths.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -40,7 +40,8 @@ public class ZNodePaths {
4040
// TODO: Replace this with ZooKeeper constant when ZOOKEEPER-277 is resolved.
4141
public static final char ZNODE_PATH_SEPARATOR = '/';
4242

43-
public final static String META_ZNODE_PREFIX = "meta-region-server";
43+
public static final String META_ZNODE_PREFIX_CONF_KEY = "zookeeper.znode.metaserver";
44+
public static final String META_ZNODE_PREFIX = "meta-region-server";
4445
private static final String DEFAULT_SNAPSHOT_CLEANUP_ZNODE = "snapshot-cleanup";
4546

4647
// base znode for this cluster
@@ -94,7 +95,7 @@ public class ZNodePaths {
9495
public ZNodePaths(Configuration conf) {
9596
baseZNode = conf.get(ZOOKEEPER_ZNODE_PARENT, DEFAULT_ZOOKEEPER_ZNODE_PARENT);
9697
ImmutableMap.Builder<Integer, String> builder = ImmutableMap.builder();
97-
metaZNodePrefix = conf.get("zookeeper.znode.metaserver", META_ZNODE_PREFIX);
98+
metaZNodePrefix = conf.get(META_ZNODE_PREFIX_CONF_KEY, META_ZNODE_PREFIX);
9899
String defaultMetaReplicaZNode = ZNodePaths.joinZNode(baseZNode, metaZNodePrefix);
99100
builder.put(DEFAULT_REPLICA_ID, defaultMetaReplicaZNode);
100101
int numMetaReplicas = conf.getInt(META_REPLICAS_NUM, DEFAULT_META_REPLICA_NUM);
@@ -178,6 +179,18 @@ public String getZNodeForReplica(int replicaId) {
178179
.orElseGet(() -> metaReplicaZNodes.get(DEFAULT_REPLICA_ID) + "-" + replicaId);
179180
}
180181

182+
/**
183+
* Parses the meta replicaId from the passed path.
184+
* @param path the name of the full path which includes baseZNode.
185+
* @return replicaId
186+
*/
187+
public int getMetaReplicaIdFromPath(String path) {
188+
// Extract the znode from path. The prefix is of the following format.
189+
// baseZNode + PATH_SEPARATOR.
190+
int prefixLen = baseZNode.length() + 1;
191+
return getMetaReplicaIdFromZnode(path.substring(prefixLen));
192+
}
193+
181194
/**
182195
* Parse the meta replicaId from the passed znode
183196
* @param znode the name of the znode, does not include baseZNode

hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/**
1+
/*
22
* Licensed to the Apache Software Foundation (ASF) under one
33
* or more contributor license agreements. See the NOTICE file
44
* distributed with this work for additional information
@@ -355,6 +355,12 @@ public void run() {
355355
// manager of assignment nodes in zookeeper
356356
private AssignmentManager assignmentManager;
357357

358+
/**
359+
* Cache for the meta region replica's locations. Also tracks their changes to avoid stale
360+
* cache entries.
361+
*/
362+
private final MetaRegionLocationCache metaRegionLocationCache;
363+
358364
// manager of replication
359365
private ReplicationPeerManager replicationPeerManager;
360366

@@ -508,8 +514,7 @@ public void doGet(HttpServletRequest request,
508514
* #finishActiveMasterInitialization(MonitoredTask) after
509515
* the master becomes the active one.
510516
*/
511-
public HMaster(final Configuration conf)
512-
throws IOException, KeeperException {
517+
public HMaster(final Configuration conf) throws IOException {
513518
super(conf);
514519
TraceUtil.initTracer(conf);
515520
try {
@@ -522,7 +527,6 @@ public HMaster(final Configuration conf)
522527
} else {
523528
maintenanceMode = false;
524529
}
525-
526530
this.rsFatals = new MemoryBoundedLogMessageBuffer(
527531
conf.getLong("hbase.master.buffer.for.rs.fatals", 1 * 1024 * 1024));
528532
LOG.info("hbase.rootdir={}, hbase.cluster.distributed={}", getDataRootDir(),
@@ -570,8 +574,10 @@ public HMaster(final Configuration conf)
570574

571575
// Some unit tests don't need a cluster, so no zookeeper at all
572576
if (!conf.getBoolean("hbase.testing.nocluster", false)) {
577+
this.metaRegionLocationCache = new MetaRegionLocationCache(this.zooKeeper);
573578
this.activeMasterManager = new ActiveMasterManager(zooKeeper, this.serverName, this);
574579
} else {
580+
this.metaRegionLocationCache = null;
575581
this.activeMasterManager = null;
576582
}
577583
cachedClusterId = new CachedClusterId(conf);
@@ -3880,4 +3886,8 @@ public void runReplicationBarrierCleaner() {
38803886
rbc.chore();
38813887
}
38823888
}
3889+
3890+
public MetaRegionLocationCache getMetaRegionLocationCache() {
3891+
return this.metaRegionLocationCache;
3892+
}
38833893
}

0 commit comments

Comments
 (0)