org.apache.hadoop.hbase.util.HbckRegionInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hbase-server Show documentation
Show all versions of hbase-server Show documentation
Server functionality for HBase
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.util;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hbase.thirdparty.com.google.common.base.Joiner;
import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
/**
* Maintain information about a particular region. It gathers information from three places -- HDFS,
* META, and region servers.
*/
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class HbckRegionInfo implements KeyRange {
private static final Logger LOG = LoggerFactory.getLogger(HbckRegionInfo.class.getName());
private MetaEntry metaEntry = null; // info in META
private HdfsEntry hdfsEntry = null; // info in HDFS
private List deployedEntries = Lists.newArrayList(); // on Region Server
private List deployedOn = Lists.newArrayList(); // info on RS's
private boolean skipChecks = false; // whether to skip further checks to this region info.
private boolean isMerged = false;// whether this region has already been merged into another one
private int deployedReplicaId = RegionInfo.DEFAULT_REPLICA_ID;
private RegionInfo primaryHRIForDeployedReplica = null;
public HbckRegionInfo(MetaEntry metaEntry) {
this.metaEntry = metaEntry;
}
public synchronized int getReplicaId() {
return metaEntry != null ? metaEntry.getReplicaId() : deployedReplicaId;
}
public synchronized void addServer(RegionInfo regionInfo, ServerName serverName) {
OnlineEntry rse = new OnlineEntry(regionInfo, serverName);
this.deployedEntries.add(rse);
this.deployedOn.add(serverName);
// save the replicaId that we see deployed in the cluster
this.deployedReplicaId = regionInfo.getReplicaId();
this.primaryHRIForDeployedReplica =
RegionReplicaUtil.getRegionInfoForDefaultReplica(regionInfo);
}
@Override
public synchronized String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{ meta => ");
sb.append((metaEntry != null) ? metaEntry.getRegionNameAsString() : "null");
sb.append(", hdfs => " + getHdfsRegionDir());
sb.append(", deployed => " + Joiner.on(", ").join(deployedEntries));
sb.append(", replicaId => " + getReplicaId());
sb.append(" }");
return sb.toString();
}
@Override
public byte[] getStartKey() {
if (this.metaEntry != null) {
return this.metaEntry.getStartKey();
} else if (this.hdfsEntry != null) {
return this.hdfsEntry.hri.getStartKey();
} else {
LOG.error("Entry " + this + " has no meta or hdfs region start key.");
return null;
}
}
@Override
public byte[] getEndKey() {
if (this.metaEntry != null) {
return this.metaEntry.getEndKey();
} else if (this.hdfsEntry != null) {
return this.hdfsEntry.hri.getEndKey();
} else {
LOG.error("Entry " + this + " has no meta or hdfs region start key.");
return null;
}
}
public MetaEntry getMetaEntry() {
return this.metaEntry;
}
public void setMetaEntry(MetaEntry metaEntry) {
this.metaEntry = metaEntry;
}
public HdfsEntry getHdfsEntry() {
return this.hdfsEntry;
}
public void setHdfsEntry(HdfsEntry hdfsEntry) {
this.hdfsEntry = hdfsEntry;
}
public List getOnlineEntries() {
return this.deployedEntries;
}
public List getDeployedOn() {
return this.deployedOn;
}
/**
* Read the .regioninfo file from the file system. If there is no .regioninfo, add it to the
* orphan hdfs region list.
*/
public void loadHdfsRegioninfo(Configuration conf) throws IOException {
Path regionDir = getHdfsRegionDir();
if (regionDir == null) {
if (getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID) {
// Log warning only for default/ primary replica with no region dir
LOG.warn("No HDFS region dir found: " + this + " meta=" + metaEntry);
}
return;
}
if (hdfsEntry.hri != null) {
// already loaded data
return;
}
FileSystem fs = FileSystem.get(conf);
RegionInfo hri = HRegionFileSystem.loadRegionInfoFileContent(fs, regionDir);
LOG.debug("RegionInfo read: " + hri.toString());
hdfsEntry.hri = hri;
}
public TableName getTableName() {
if (this.metaEntry != null) {
return this.metaEntry.getTable();
} else if (this.hdfsEntry != null) {
// we are only guaranteed to have a path and not an HRI for hdfsEntry,
// so we get the name from the Path
Path tableDir = this.hdfsEntry.regionDir.getParent();
return CommonFSUtils.getTableName(tableDir);
} else {
// return the info from the first online/deployed hri
for (OnlineEntry e : deployedEntries) {
return e.getRegionInfo().getTable();
}
return null;
}
}
public String getRegionNameAsString() {
if (metaEntry != null) {
return metaEntry.getRegionNameAsString();
} else if (hdfsEntry != null) {
if (hdfsEntry.hri != null) {
return hdfsEntry.hri.getRegionNameAsString();
}
} else {
// return the info from the first online/deployed hri
for (OnlineEntry e : deployedEntries) {
return e.getRegionInfo().getRegionNameAsString();
}
}
return null;
}
public byte[] getRegionName() {
if (metaEntry != null) {
return metaEntry.getRegionName();
} else if (hdfsEntry != null) {
return hdfsEntry.hri.getRegionName();
} else {
// return the info from the first online/deployed hri
for (OnlineEntry e : deployedEntries) {
return e.getRegionInfo().getRegionName();
}
return null;
}
}
public RegionInfo getPrimaryHRIForDeployedReplica() {
return primaryHRIForDeployedReplica;
}
public Path getHdfsRegionDir() {
if (hdfsEntry == null) {
return null;
}
return hdfsEntry.regionDir;
}
public boolean containsOnlyHdfsEdits() {
if (hdfsEntry == null) {
return false;
}
return hdfsEntry.hdfsOnlyEdits;
}
public boolean isHdfsRegioninfoPresent() {
if (hdfsEntry == null) {
return false;
}
return hdfsEntry.hdfsRegioninfoFilePresent;
}
public long getModTime() {
if (hdfsEntry == null) {
return 0;
}
return hdfsEntry.regionDirModTime;
}
public RegionInfo getHdfsHRI() {
if (hdfsEntry == null) {
return null;
}
return hdfsEntry.hri;
}
public void setSkipChecks(boolean skipChecks) {
this.skipChecks = skipChecks;
}
public boolean isSkipChecks() {
return skipChecks;
}
public void setMerged(boolean isMerged) {
this.isMerged = isMerged;
}
public boolean isMerged() {
return this.isMerged;
}
/**
* Stores the regioninfo entries scanned from META
*/
public static class MetaEntry extends HRegionInfo {
ServerName regionServer; // server hosting this region
long modTime; // timestamp of most recent modification metadata
RegionInfo splitA, splitB; // split daughters
public MetaEntry(RegionInfo rinfo, ServerName regionServer, long modTime) {
this(rinfo, regionServer, modTime, null, null);
}
public MetaEntry(RegionInfo rinfo, ServerName regionServer, long modTime, RegionInfo splitA,
RegionInfo splitB) {
super(rinfo);
this.regionServer = regionServer;
this.modTime = modTime;
this.splitA = splitA;
this.splitB = splitB;
}
public ServerName getRegionServer() {
return this.regionServer;
}
@Override
public boolean equals(Object o) {
boolean superEq = super.equals(o);
if (!superEq) {
return superEq;
}
MetaEntry me = (MetaEntry) o;
if (!regionServer.equals(me.regionServer)) {
return false;
}
return (modTime == me.modTime);
}
@Override
public int hashCode() {
int hash = Arrays.hashCode(getRegionName());
hash = (int) (hash ^ getRegionId());
hash ^= Arrays.hashCode(getStartKey());
hash ^= Arrays.hashCode(getEndKey());
hash ^= Boolean.valueOf(isOffline()).hashCode();
hash ^= getTable().hashCode();
if (regionServer != null) {
hash ^= regionServer.hashCode();
}
hash = (int) (hash ^ modTime);
return hash;
}
}
/**
* Stores the regioninfo entries from HDFS
*/
public static class HdfsEntry {
RegionInfo hri;
Path regionDir = null;
long regionDirModTime = 0;
boolean hdfsRegioninfoFilePresent = false;
boolean hdfsOnlyEdits = false;
HdfsEntry() {
}
public HdfsEntry(Path regionDir) {
this.regionDir = regionDir;
}
}
/**
* Stores the regioninfo retrieved from Online region servers.
*/
static class OnlineEntry {
private RegionInfo regionInfo;
private ServerName serverName;
OnlineEntry(RegionInfo regionInfo, ServerName serverName) {
this.regionInfo = regionInfo;
this.serverName = serverName;
}
public RegionInfo getRegionInfo() {
return regionInfo;
}
public ServerName getServerName() {
return serverName;
}
@Override
public String toString() {
return serverName.toString() + ";" + regionInfo.getRegionNameAsString();
}
}
final static Comparator COMPARATOR = new Comparator() {
@Override
public int compare(HbckRegionInfo l, HbckRegionInfo r) {
if (l == r) {
// same instance
return 0;
}
int tableCompare = l.getTableName().compareTo(r.getTableName());
if (tableCompare != 0) {
return tableCompare;
}
int startComparison =
RegionSplitCalculator.BYTES_COMPARATOR.compare(l.getStartKey(), r.getStartKey());
if (startComparison != 0) {
return startComparison;
}
// Special case for absolute endkey
byte[] endKey = r.getEndKey();
endKey = (endKey.length == 0) ? null : endKey;
byte[] endKey2 = l.getEndKey();
endKey2 = (endKey2.length == 0) ? null : endKey2;
int endComparison = RegionSplitCalculator.BYTES_COMPARATOR.compare(endKey2, endKey);
if (endComparison != 0) {
return endComparison;
}
// use regionId as tiebreaker.
// Null is considered after all possible values so make it bigger.
if (l.getHdfsEntry() == null && r.getHdfsEntry() == null) {
return 0;
}
if (l.getHdfsEntry() == null && r.getHdfsEntry() != null) {
return 1;
}
// l.hdfsEntry must not be null
if (r.getHdfsEntry() == null) {
return -1;
}
// both l.hdfsEntry and r.hdfsEntry must not be null.
return Long.compare(l.getHdfsEntry().hri.getRegionId(), r.getHdfsEntry().hri.getRegionId());
}
};
}