001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import java.io.Closeable; 021import java.io.IOException; 022import java.util.List; 023import java.util.stream.Collectors; 024import org.apache.hadoop.hbase.HConstants; 025import org.apache.hadoop.hbase.HRegionLocation; 026import org.apache.hadoop.hbase.TableName; 027import org.apache.hadoop.hbase.util.Pair; 028import org.apache.yetus.audience.InterfaceAudience; 029 030/** 031 * Used to view region location information for a single HBase table. Obtain an instance from an 032 * {@link Connection}. 033 * @see ConnectionFactory 034 * @see Connection 035 * @see Table 036 * @since 0.99.0 037 */ 038@InterfaceAudience.Public 039public interface RegionLocator extends Closeable { 040 041 /** 042 * Configuration for Region Locator's mode when meta replica is configured. Valid values are: 043 * HedgedRead, LoadBalance, None 044 */ 045 String LOCATOR_META_REPLICAS_MODE = "hbase.locator.meta.replicas.mode"; 046 047 /** 048 * Configuration for meta replica selector when Region Locator's LoadBalance mode is configured. 049 * The default value is org.apache.hadoop.hbase.client.CatalogReplicaLoadBalanceSimpleSelector. 050 */ 051 String LOCATOR_META_REPLICAS_MODE_LOADBALANCE_SELECTOR = 052 "hbase.locator.meta.replicas.mode.loadbalance.selector"; 053 054 /** 055 * Finds the region on which the given row is being served. Does not reload the cache. 056 * @param row Row to find. 057 * @return Location of the row. 058 * @throws IOException if a remote or network exception occurs 059 */ 060 default HRegionLocation getRegionLocation(byte[] row) throws IOException { 061 return getRegionLocation(row, false); 062 } 063 064 /** 065 * Finds the region on which the given row is being served. 066 * @param row Row to find. 067 * @param reload true to reload information or false to use cached information 068 * @return Location of the row. 069 * @throws IOException if a remote or network exception occurs 070 */ 071 default HRegionLocation getRegionLocation(byte[] row, boolean reload) throws IOException { 072 return getRegionLocation(row, RegionInfo.DEFAULT_REPLICA_ID, reload); 073 } 074 075 /** 076 * Finds the region with the given replica id on which the given row is being served. 077 * @param row Row to find. 078 * @param replicaId the replica id 079 * @return Location of the row. 080 * @throws IOException if a remote or network exception occurs 081 */ 082 default HRegionLocation getRegionLocation(byte[] row, int replicaId) throws IOException { 083 return getRegionLocation(row, replicaId, false); 084 } 085 086 /** 087 * Finds the region with the given replica id on which the given row is being served. 088 * @param row Row to find. 089 * @param replicaId the replica id 090 * @param reload true to reload information or false to use cached information 091 * @return Location of the row. 092 * @throws IOException if a remote or network exception occurs 093 */ 094 HRegionLocation getRegionLocation(byte[] row, int replicaId, boolean reload) throws IOException; 095 096 /** 097 * Find all the replicas for the region on which the given row is being served. 098 * @param row Row to find. 099 * @return Locations for all the replicas of the row. 100 * @throws IOException if a remote or network exception occurs 101 */ 102 default List<HRegionLocation> getRegionLocations(byte[] row) throws IOException { 103 return getRegionLocations(row, false); 104 } 105 106 /** 107 * Find all the replicas for the region on which the given row is being served. 108 * @param row Row to find. 109 * @param reload true to reload information or false to use cached information 110 * @return Locations for all the replicas of the row. 111 * @throws IOException if a remote or network exception occurs 112 */ 113 List<HRegionLocation> getRegionLocations(byte[] row, boolean reload) throws IOException; 114 115 /** 116 * Clear all the entries in the region location cache. 117 * <p/> 118 * This may cause performance issue so use it with caution. 119 */ 120 void clearRegionLocationCache(); 121 122 /** 123 * Retrieves all of the regions associated with this table. 124 * <p/> 125 * Usually we will go to meta table directly in this method so there is no {@code reload} 126 * parameter. 127 * <p/> 128 * Notice that the location for region replicas other than the default replica are also returned. 129 * @return a {@link List} of all regions associated with this table. 130 * @throws IOException if a remote or network exception occurs 131 */ 132 List<HRegionLocation> getAllRegionLocations() throws IOException; 133 134 /** 135 * Bulk lookup of region locations from {@code hbase:meta} in a single RPC, starting at 136 * {@code startKey} (region start-key boundary, inclusive) and returning at most {@code limit} 137 * regions in start-key order. 138 * <p/> 139 * The returned list includes all replicas of each region (matching 140 * {@link #getAllRegionLocations()}), and the result is also written to the connection's region 141 * location cache. 142 * <p/> 143 * Ordering: regions are returned in ascending region start-key order (the natural order of 144 * {@code hbase:meta} rows for a single table). Within each region, replicas are returned in 145 * ascending replica-id order (replica 0, then 1, then 2, ...). Split parents are filtered out, 146 * which may cause a page to contain fewer than {@code limit} regions but never disturbs ordering 147 * of the survivors. 148 * <p/> 149 * To page through all regions of a table, call repeatedly passing 150 * {@code last.getRegion().getEndKey()} as the next {@code startKey}, where {@code last} is the 151 * final element of the previous response. All replicas of a region share the same 152 * {@link RegionInfo}, so the last entry's end key is the correct cursor regardless of which 153 * replica it is. Pass {@code null} for the first call. Stop paging when the returned list is 154 * empty or when the last region's end key is {@link HConstants#EMPTY_END_ROW} (zero-length) - 155 * that signals the end of the table; passing it back in would re-scan from the beginning since by 156 * convention an empty start key means "from the first region". 157 * <p/> 158 * Unlike {@link #getAllRegionLocations()}, this method performs at most one RPC against 159 * {@code hbase:meta} per invocation, so its latency is bounded by {@code limit} rather than table 160 * size. The single-RPC behavior is best-effort: if the response would exceed 161 * {@code hbase.client.scanner.max.result.size} (default 2 MB), the server may split the slice 162 * across multiple {@code ScannerNext} RPCs. For typical meta row sizes and default caching this 163 * rarely fires, but callers passing large {@code limit} values against clusters with replicas or 164 * heavy meta rows should treat single-RPC as a soft guarantee, not absolute. 165 * <p/> 166 * This method is optional. Implementations that cannot support paginated lookups should throw 167 * {@link UnsupportedOperationException} (the default behavior); callers should fall back to 168 * {@link #getAllRegionLocations()} in that case. 169 * @param startKey region start-key to begin scanning from (inclusive); {@code null} or empty 170 * starts from the first region 171 * @param limit maximum number of regions to return. If <= 0, falls back to 172 * {@code hbase.meta.scanner.caching} - this is a SOFT cap on a single page, NOT 173 * "all regions"; tables larger than the cap still require the caller to keep 174 * paging via {@code last.getRegion().getEndKey()}. 175 * @return up to {@code limit} {@link HRegionLocation}s in start-key order, possibly empty when no 176 * more regions exist 177 * @throws IOException if a remote or network exception occurs 178 * @throws UnsupportedOperationException if this implementation does not support paginated lookups 179 */ 180 default List<HRegionLocation> getRegionLocationsPage(byte[] startKey, int limit) 181 throws IOException { 182 throw new UnsupportedOperationException( 183 "getRegionLocationsPage(byte[], int) is not supported by this RegionLocator;" 184 + " fall back to getAllRegionLocations()"); 185 } 186 187 /** 188 * Gets the starting row key for every region in the currently open table. 189 * <p> 190 * This is mainly useful for the MapReduce integration. 191 * @return Array of region starting row keys 192 * @throws IOException if a remote or network exception occurs 193 */ 194 default byte[][] getStartKeys() throws IOException { 195 return getStartEndKeys().getFirst(); 196 } 197 198 /** 199 * Gets the ending row key for every region in the currently open table. 200 * <p> 201 * This is mainly useful for the MapReduce integration. 202 * @return Array of region ending row keys 203 * @throws IOException if a remote or network exception occurs 204 */ 205 default byte[][] getEndKeys() throws IOException { 206 return getStartEndKeys().getSecond(); 207 } 208 209 /** 210 * Gets the starting and ending row keys for every region in the currently open table. 211 * <p> 212 * This is mainly useful for the MapReduce integration. 213 * @return Pair of arrays of region starting and ending row keys 214 * @throws IOException if a remote or network exception occurs 215 */ 216 default Pair<byte[][], byte[][]> getStartEndKeys() throws IOException { 217 List<HRegionLocation> regions = getAllRegionLocations().stream() 218 .filter(loc -> RegionReplicaUtil.isDefaultReplica(loc.getRegion())) 219 .collect(Collectors.toList()); 220 byte[][] startKeys = new byte[regions.size()][]; 221 byte[][] endKeys = new byte[regions.size()][]; 222 for (int i = 0, n = regions.size(); i < n; i++) { 223 RegionInfo region = regions.get(i).getRegion(); 224 startKeys[i] = region.getStartKey(); 225 endKeys[i] = region.getEndKey(); 226 } 227 return Pair.newPair(startKeys, endKeys); 228 } 229 230 /** 231 * Gets the fully qualified table name instance of this table. 232 */ 233 TableName getName(); 234}