use of org.apache.hadoop.hbase.HRegionLocation in project hbase by apache.
the class AsyncMetaRegionLocator method getRegionLocation.
CompletableFuture<HRegionLocation> getRegionLocation() {
for (; ; ) {
HRegionLocation metaRegionLocation = this.metaRegionLocation.get();
if (metaRegionLocation != null) {
return CompletableFuture.completedFuture(metaRegionLocation);
}
if (LOG.isTraceEnabled()) {
LOG.trace("Meta region location cache is null, try fetching from registry.");
}
if (metaRelocateFuture.compareAndSet(null, new CompletableFuture<>())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Start fetching meta region location from registry.");
}
CompletableFuture<HRegionLocation> future = metaRelocateFuture.get();
registry.getMetaRegionLocation().whenComplete((locs, error) -> {
if (error != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to fetch meta region location from registry", error);
}
metaRelocateFuture.getAndSet(null).completeExceptionally(error);
return;
}
HRegionLocation loc = locs.getDefaultRegionLocation();
if (LOG.isDebugEnabled()) {
LOG.debug("The fetched meta region location is " + loc);
}
// Here we update cache before reset future, so it is possible that someone can get a
// stale value. Consider this:
// 1. update cache
// 2. someone clear the cache and relocate again
// 3. the metaRelocateFuture is not null so the old future is used.
// 4. we clear metaRelocateFuture and complete the future in it with the value being
// cleared in step 2.
// But we do not think it is a big deal as it rarely happens, and even if it happens, the
// caller will retry again later, no correctness problems.
this.metaRegionLocation.set(loc);
metaRelocateFuture.set(null);
future.complete(loc);
});
} else {
CompletableFuture<HRegionLocation> future = metaRelocateFuture.get();
if (future != null) {
return future;
}
}
}
}
use of org.apache.hadoop.hbase.HRegionLocation in project hbase by apache.
the class AsyncNonMetaRegionLocator method getRegionLocationInternal.
// locateToPrevious is true means we will use the start key of a region to locate the region
// placed before it. Used for reverse scan. See the comment of
// AsyncRegionLocator.getPreviousRegionLocation.
private CompletableFuture<HRegionLocation> getRegionLocationInternal(TableName tableName, byte[] row, RegionLocateType locateType) {
// AFTER should be convert to CURRENT before calling this method
assert !locateType.equals(RegionLocateType.AFTER);
TableCache tableCache = getTableCache(tableName);
HRegionLocation loc = locateInCache(tableCache, tableName, row, locateType);
if (loc != null) {
return CompletableFuture.completedFuture(loc);
}
CompletableFuture<HRegionLocation> future;
LocateRequest req;
boolean sendRequest = false;
synchronized (tableCache) {
// check again
loc = locateInCache(tableCache, tableName, row, locateType);
if (loc != null) {
return CompletableFuture.completedFuture(loc);
}
req = new LocateRequest(row, locateType);
future = tableCache.allRequests.get(req);
if (future == null) {
future = new CompletableFuture<>();
tableCache.allRequests.put(req, future);
if (tableCache.hasQuota(maxConcurrentLocateRequestPerTable) && !tableCache.isPending(req)) {
tableCache.send(req);
sendRequest = true;
}
}
}
if (sendRequest) {
locateInMeta(tableName, req);
}
return future;
}
use of org.apache.hadoop.hbase.HRegionLocation in project hbase by apache.
the class AsyncNonMetaRegionLocator method locateRowBeforeInCache.
private HRegionLocation locateRowBeforeInCache(TableCache tableCache, TableName tableName, byte[] row) {
Map.Entry<byte[], HRegionLocation> entry = isEmptyStopRow(row) ? tableCache.cache.lastEntry() : tableCache.cache.lowerEntry(row);
if (entry == null) {
return null;
}
HRegionLocation loc = entry.getValue();
if (isEmptyStopRow(loc.getRegionInfo().getEndKey()) || Bytes.compareTo(loc.getRegionInfo().getEndKey(), row) >= 0) {
if (LOG.isTraceEnabled()) {
LOG.trace("Found " + loc + " in cache for '" + tableName + "', row='" + Bytes.toStringBinary(row) + "', locateType=" + RegionLocateType.BEFORE);
}
return loc;
} else {
return null;
}
}
use of org.apache.hadoop.hbase.HRegionLocation in project hbase by apache.
the class AsyncRegionLocator method updateCachedLoation.
static void updateCachedLoation(HRegionLocation loc, Throwable exception, Function<HRegionLocation, HRegionLocation> cachedLocationSupplier, Consumer<HRegionLocation> addToCache, Consumer<HRegionLocation> removeFromCache) {
HRegionLocation oldLoc = cachedLocationSupplier.apply(loc);
if (LOG.isDebugEnabled()) {
LOG.debug("Try updating " + loc + ", the old value is " + oldLoc, exception);
}
if (!canUpdate(loc, oldLoc)) {
return;
}
Throwable cause = findException(exception);
if (LOG.isDebugEnabled()) {
LOG.debug("The actual exception when updating " + loc, cause);
}
if (cause == null || !isMetaClearingException(cause)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Will not update " + loc + " because the exception is null or not the one we care about");
}
return;
}
if (cause instanceof RegionMovedException) {
RegionMovedException rme = (RegionMovedException) cause;
HRegionLocation newLoc = new HRegionLocation(loc.getRegionInfo(), rme.getServerName(), rme.getLocationSeqNum());
if (LOG.isDebugEnabled()) {
LOG.debug("Try updating " + loc + " with the new location " + newLoc + " constructed by " + rme);
}
addToCache.accept(newLoc);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Try removing " + loc + " from cache");
}
removeFromCache.accept(loc);
}
}
use of org.apache.hadoop.hbase.HRegionLocation in project hbase by apache.
the class ConnectionImplementation method locateRegions.
@Override
public List<HRegionLocation> locateRegions(final TableName tableName, final boolean useCache, final boolean offlined) throws IOException {
List<HRegionInfo> regions = MetaTableAccessor.getTableRegions(this, tableName, !offlined);
final List<HRegionLocation> locations = new ArrayList<>();
for (HRegionInfo regionInfo : regions) {
RegionLocations list = locateRegion(tableName, regionInfo.getStartKey(), useCache, true);
if (list != null) {
for (HRegionLocation loc : list.getRegionLocations()) {
if (loc != null) {
locations.add(loc);
}
}
}
}
return locations;
}
Aggregations