Skip to content

Commit

Permalink
HBASE-11574. hbase:meta's regions can be replicated
Browse files Browse the repository at this point in the history
  • Loading branch information
Devaraj Das committed Jan 28, 2015
1 parent 0f6faaf commit 6b20a0f
Show file tree
Hide file tree
Showing 29 changed files with 1,133 additions and 156 deletions.
Expand Up @@ -30,6 +30,7 @@
import org.apache.hadoop.hbase.KeyValue.KVComparator;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.classification.InterfaceStability;
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
import org.apache.hadoop.hbase.master.RegionState;
Expand Down Expand Up @@ -219,12 +220,16 @@ private void setHashCode() {
* first meta regions
*/
private HRegionInfo(long regionId, TableName tableName) {
this(regionId, tableName, DEFAULT_REPLICA_ID);
}

public HRegionInfo(long regionId, TableName tableName, int replicaId) {
super();
this.regionId = regionId;
this.tableName = tableName;
// Note: First Meta regions names are still in old format
this.regionName = createRegionName(tableName, null,
regionId, false);
this.replicaId = replicaId;
// Note: First Meta region replicas names are in old format
this.regionName = createRegionName(tableName, null, regionId, replicaId, false);
setHashCode();
}

Expand Down Expand Up @@ -914,7 +919,8 @@ public static HRegionInfo convert(final RegionInfo proto) {
TableName tableName =
ProtobufUtil.toTableName(proto.getTableName());
if (tableName.equals(TableName.META_TABLE_NAME)) {
return FIRST_META_REGIONINFO;
return RegionReplicaUtil.getRegionInfoForReplica(FIRST_META_REGIONINFO,
proto.getReplicaId());
}
long regionId = proto.getRegionId();
int replicaId = proto.hasReplicaId() ? proto.getReplicaId() : DEFAULT_REPLICA_ID;
Expand Down
Expand Up @@ -1095,7 +1095,7 @@ public static void addRegionToMeta(Table meta, HRegionInfo regionInfo) throws IO
* Adds a (single) hbase:meta row for the specified new region and its daughters. Note that this
* does not add its daughter's as different rows, but adds information about the daughters
* in the same row as the parent. Use
* {@link #splitRegion(Connection, HRegionInfo, HRegionInfo, HRegionInfo, ServerName, int)
* {@link #splitRegion(Connection, HRegionInfo, HRegionInfo, HRegionInfo, ServerName, int)}
* if you want to do that.
* @param meta the Table for META
* @param regionInfo region information
Expand All @@ -1117,7 +1117,7 @@ public static void addRegionToMeta(Table meta, HRegionInfo regionInfo,
* Adds a (single) hbase:meta row for the specified new region and its daughters. Note that this
* does not add its daughter's as different rows, but adds information about the daughters
* in the same row as the parent. Use
* {@link #splitRegion(Connection, HRegionInfo, HRegionInfo, HRegionInfo, ServerName, int)
* {@link #splitRegion(Connection, HRegionInfo, HRegionInfo, HRegionInfo, ServerName, int)}
* if you want to do that.
* @param connection connection we're using
* @param regionInfo region information
Expand Down
Expand Up @@ -551,6 +551,7 @@ public static <T> T execute(HConnectable<T> connectable) throws IOException {
static class HConnectionImplementation implements ClusterConnection, Closeable {
static final Log LOG = LogFactory.getLog(HConnectionImplementation.class);
private final long pause;
private final boolean useMetaReplicas;
private final int numTries;
final int rpcTimeout;
private NonceGenerator nonceGenerator = null;
Expand Down Expand Up @@ -674,6 +675,8 @@ protected HConnectionImplementation(Configuration conf) {
this.closed = false;
this.pause = conf.getLong(HConstants.HBASE_CLIENT_PAUSE,
HConstants.DEFAULT_HBASE_CLIENT_PAUSE);
this.useMetaReplicas = conf.getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS);
this.numTries = tableConfig.getRetriesNumber();
this.rpcTimeout = conf.getInt(
HConstants.HBASE_RPC_TIMEOUT_KEY,
Expand Down Expand Up @@ -1132,7 +1135,7 @@ private RegionLocations locateMeta(final TableName tableName,
RegionLocations locations = null;
if (useCache) {
locations = getCachedLocation(tableName, metaCacheKey);
if (locations != null) {
if (locations != null && locations.getRegionLocation(replicaId) != null) {
return locations;
}
}
Expand All @@ -1143,7 +1146,7 @@ private RegionLocations locateMeta(final TableName tableName,
// same query while we were waiting on the lock.
if (useCache) {
locations = getCachedLocation(tableName, metaCacheKey);
if (locations != null) {
if (locations != null && locations.getRegionLocation(replicaId) != null) {
return locations;
}
}
Expand Down Expand Up @@ -1183,6 +1186,9 @@ private RegionLocations locateRegionInMeta(TableName tableName, byte[] row,
s.setStartRow(metaKey);
s.setSmall(true);
s.setCaching(1);
if (this.useMetaReplicas) {
s.setConsistency(Consistency.TIMELINE);
}

int localNumRetries = (retry ? numTries : 1);

Expand Down
Expand Up @@ -421,9 +421,6 @@ public TableName[] listTableNames(final String regex, final boolean includeSysTa
public HTableDescriptor getTableDescriptor(final TableName tableName)
throws TableNotFoundException, IOException {
if (tableName == null) return null;
if (tableName.equals(TableName.META_TABLE_NAME)) {
return HTableDescriptor.META_TABLEDESC;
}
HTableDescriptor htd = executeCallable(new MasterCallable<HTableDescriptor>(getConnection()) {
@Override
public HTableDescriptor call(int callTimeout) throws ServiceException {
Expand Down
Expand Up @@ -49,6 +49,7 @@ class HConnectionKey {
HConstants.HBASE_META_SCANNER_CACHING,
HConstants.HBASE_CLIENT_INSTANCE_ID,
HConstants.RPC_CODEC_CONF_KEY,
HConstants.USE_META_REPLICAS,
RpcControllerFactory.CUSTOM_CONTROLLER_CONF_KEY};

private Map<String, String> properties;
Expand Down
Expand Up @@ -153,7 +153,9 @@ static void metaScan(Connection connection,
try (Table metaTable = new HTable(TableName.META_TABLE_NAME, connection, null)) {
if (row != null) {
// Scan starting at a particular row in a particular table
Result startRowResult = getClosestRowOrBefore(metaTable, tableName, row);
Result startRowResult = getClosestRowOrBefore(metaTable, tableName, row,
connection.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS));
if (startRowResult == null) {
throw new TableNotFoundException("Cannot find row in " + metaTable.getName() +
" for table: " + tableName + ", row=" + Bytes.toStringBinary(row));
Expand All @@ -177,6 +179,10 @@ static void metaScan(Connection connection,
int scannerCaching = connection.getConfiguration()
.getInt(HConstants.HBASE_META_SCANNER_CACHING,
HConstants.DEFAULT_HBASE_META_SCANNER_CACHING);
if (connection.getConfiguration().getBoolean(HConstants.USE_META_REPLICAS,
HConstants.DEFAULT_USE_META_REPLICAS)) {
scan.setConsistency(Consistency.TIMELINE);
}
if (rowUpperLimit <= scannerCaching) {
scan.setSmall(true);
}
Expand Down Expand Up @@ -215,10 +221,13 @@ static void metaScan(Connection connection,
* @throws IOException
*/
private static Result getClosestRowOrBefore(final Table metaTable, final TableName userTableName,
final byte [] row)
final byte [] row, boolean useMetaReplicas)
throws IOException {
byte[] searchRow = HRegionInfo.createRegionName(userTableName, row, HConstants.NINES, false);
Scan scan = Scan.createGetClosestRowOrBeforeReverseScan(searchRow);
if (useMetaReplicas) {
scan.setConsistency(Consistency.TIMELINE);
}
try (ResultScanner resultScanner = metaTable.getScanner(scan)) {
return resultScanner.next();
}
Expand Down
Expand Up @@ -47,9 +47,13 @@ public static HRegionInfo getRegionInfoForReplica(HRegionInfo regionInfo, int re
if (regionInfo.getReplicaId() == replicaId) {
return regionInfo;
}
HRegionInfo replicaInfo = new HRegionInfo(regionInfo.getTable(), regionInfo.getStartKey(),
regionInfo.getEndKey(), regionInfo.isSplit(), regionInfo.getRegionId(), replicaId);

HRegionInfo replicaInfo;
if (regionInfo.isMetaRegion()) {
replicaInfo = new HRegionInfo(regionInfo.getRegionId(), regionInfo.getTable(), replicaId);
} else {
replicaInfo = new HRegionInfo(regionInfo.getTable(), regionInfo.getStartKey(),
regionInfo.getEndKey(), regionInfo.isSplit(), regionInfo.getRegionId(), replicaId);
}
replicaInfo.setOffline(regionInfo.isOffline());
return replicaInfo;
}
Expand Down
Expand Up @@ -272,7 +272,7 @@ private int addCallsForOtherReplicas(
return 0; // not scheduling on other replicas for strong consistency
}
for (int id = min; id <= max; id++) {
if (currentScannerCallable.getHRegionInfo().getReplicaId() == id) {
if (currentScannerCallable.id == id) {
continue; //this was already scheduled earlier
}
ScannerCallable s = currentScannerCallable.getScannerCallableForReplica(id);
Expand Down
Expand Up @@ -18,6 +18,7 @@
package org.apache.hadoop.hbase.client;

import java.io.IOException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand Down Expand Up @@ -54,14 +55,32 @@ public RegionLocations getMetaRegionLocation() throws IOException {
if (LOG.isTraceEnabled()) {
LOG.trace("Looking up meta region location in ZK," + " connection=" + this);
}
ServerName servername = new MetaTableLocator().blockUntilAvailable(zkw, hci.rpcTimeout);
List<ServerName> servers = new MetaTableLocator().blockUntilAvailable(zkw, hci.rpcTimeout,
hci.getConfiguration());
if (LOG.isTraceEnabled()) {
LOG.trace("Looked up meta region location, connection=" + this +
"; serverName=" + ((servername == null) ? "null" : servername));
if (servers == null) {
LOG.trace("Looked up meta region location, connection=" + this +
"; servers = null");
} else {
StringBuilder str = new StringBuilder();
for (ServerName s : servers) {
str.append(s.toString());
str.append(" ");
}
LOG.trace("Looked up meta region location, connection=" + this +
"; servers = " + str.toString());
}
}
if (servername == null) return null;
HRegionLocation loc = new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, servername, 0);
return new RegionLocations(new HRegionLocation[] {loc});
if (servers == null) return null;
HRegionLocation[] locs = new HRegionLocation[servers.size()];
int i = 0;
for (ServerName server : servers) {
HRegionInfo h = RegionReplicaUtil.getRegionInfoForReplica(
HRegionInfo.FIRST_META_REGIONINFO, i);
if (server == null) locs[i++] = null;
else locs[i++] = new HRegionLocation(h, server, 0);
}
return new RegionLocations(locs);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
Expand Down

0 comments on commit 6b20a0f

Please sign in to comment.