1 /** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 package org.apache.hadoop.hbase.client; 20 21 import java.io.IOException; 22 import java.util.concurrent.ExecutorService; 23 import org.apache.commons.logging.Log; 24 import org.apache.hadoop.hbase.classification.InterfaceAudience; 25 import org.apache.hadoop.hbase.classification.InterfaceStability; 26 import org.apache.hadoop.conf.Configuration; 27 import org.apache.hadoop.hbase.security.User; 28 29 /** 30 * A non-instantiable class that manages creation of {@link HConnection}s. 31 * <p>The simplest way to use this class is by using {@link #createConnection(Configuration)}. 32 * This creates a new {@link HConnection} to the cluster that is managed by the caller. 33 * From this {@link HConnection} {@link HTableInterface} implementations are retrieved 34 * with {@link HConnection#getTable(byte[])}. Example: 35 * <pre> 36 * HConnection connection = HConnectionManager.createConnection(config); 37 * HTableInterface table = connection.getTable(TableName.valueOf("table1")); 38 * try { 39 * // Use the table as needed, for a single operation and a single thread 40 * } finally { 41 * table.close(); 42 * connection.close(); 43 * } 44 * </pre> 45 * <p>This class has a static Map of {@link HConnection} instances keyed by 46 * {@link HConnectionKey}; A {@link HConnectionKey} is identified by a set of 47 * {@link Configuration} properties. Invocations of {@link #getConnection(Configuration)} 48 * that pass the same {@link Configuration} instance will return the same 49 * {@link HConnection} instance ONLY WHEN the set of properties are the same 50 * (i.e. if you change properties in your {@link Configuration} instance, such as RPC timeout, 51 * the codec used, HBase will create a new {@link HConnection} instance. For more details on 52 * how this is done see {@link HConnectionKey}). 53 * <p>Sharing {@link HConnection} instances is usually what you want; all clients 54 * of the {@link HConnection} instances share the HConnections' cache of Region 55 * locations rather than each having to discover for itself the location of meta, etc. 56 * But sharing connections makes clean up of {@link HConnection} instances a little awkward. 57 * Currently, clients cleanup by calling {@link #deleteConnection(Configuration)}. This will 58 * shutdown the zookeeper connection the HConnection was using and clean up all 59 * HConnection resources as well as stopping proxies to servers out on the 60 * cluster. Not running the cleanup will not end the world; it'll 61 * just stall the closeup some and spew some zookeeper connection failed 62 * messages into the log. Running the cleanup on a {@link HConnection} that is 63 * subsequently used by another will cause breakage so be careful running 64 * cleanup. 65 * <p>To create a {@link HConnection} that is not shared by others, you can 66 * set property "hbase.client.instance.id" to a unique value for your {@link Configuration} 67 * instance, like the following: 68 * <pre> 69 * {@code 70 * conf.set("hbase.client.instance.id", "12345"); 71 * HConnection connection = HConnectionManager.getConnection(conf); 72 * // Use the connection to your hearts' delight and then when done... 73 * conf.set("hbase.client.instance.id", "12345"); 74 * HConnectionManager.deleteConnection(conf, true); 75 * } 76 * </pre> 77 * <p>Cleanup used to be done inside in a shutdown hook. On startup we'd 78 * register a shutdown hook that called {@link #deleteAllConnections()} 79 * on its way out but the order in which shutdown hooks run is not defined so 80 * were problematic for clients of HConnection that wanted to register their 81 * own shutdown hooks so we removed ours though this shifts the onus for 82 * cleanup to the client. 83 * @deprecated Please use ConnectionFactory instead 84 */ 85 @InterfaceAudience.Public 86 @InterfaceStability.Evolving 87 @Deprecated 88 public class HConnectionManager extends ConnectionFactory { 89 90 @Deprecated 91 public static final String RETRIES_BY_SERVER_KEY = 92 ConnectionManager.RETRIES_BY_SERVER_KEY; 93 94 @Deprecated 95 public static final int MAX_CACHED_CONNECTION_INSTANCES = 96 ConnectionManager.MAX_CACHED_CONNECTION_INSTANCES; 97 98 /* 99 * Non-instantiable. 100 */ 101 private HConnectionManager() { 102 super(); 103 } 104 105 /** 106 * Get the connection that goes with the passed <code>conf</code> configuration instance. 107 * If no current connection exists, method creates a new connection and keys it using 108 * connection-specific properties from the passed {@link Configuration}; see 109 * {@link HConnectionKey}. 110 * @param conf configuration 111 * @return HConnection object for <code>conf</code> 112 * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException 113 */ 114 @Deprecated 115 public static HConnection getConnection(final Configuration conf) throws IOException { 116 return ConnectionManager.getConnectionInternal(conf); 117 } 118 119 /** 120 * Create a new HConnection instance using the passed <code>conf</code> instance. 121 * <p>Note: This bypasses the usual HConnection life cycle management done by 122 * {@link #getConnection(Configuration)}. The caller is responsible for 123 * calling {@link HConnection#close()} on the returned connection instance. 124 * 125 * This is the recommended way to create HConnections. 126 * <pre> 127 * HConnection connection = HConnectionManager.createConnection(conf); 128 * HTableInterface table = connection.getTable("mytable"); 129 * try { 130 * table.get(...); 131 * ... 132 * } finally { 133 * table.close(); 134 * connection.close(); 135 * } 136 * </pre> 137 * 138 * @param conf configuration 139 * @return HConnection object for <code>conf</code> 140 * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException 141 */ 142 @Deprecated 143 public static HConnection createConnection(Configuration conf) throws IOException { 144 return ConnectionManager.createConnectionInternal(conf); 145 } 146 147 148 /** 149 * Create a new HConnection instance using the passed <code>conf</code> instance. 150 * <p>Note: This bypasses the usual HConnection life cycle management done by 151 * {@link #getConnection(Configuration)}. The caller is responsible for 152 * calling {@link HConnection#close()} on the returned connection instance. 153 * This is the recommended way to create HConnections. 154 * <pre> 155 * ExecutorService pool = ...; 156 * HConnection connection = HConnectionManager.createConnection(conf, pool); 157 * HTableInterface table = connection.getTable("mytable"); 158 * table.get(...); 159 * ... 160 * table.close(); 161 * connection.close(); 162 * </pre> 163 * @param conf configuration 164 * @param pool the thread pool to use for batch operation in HTables used via this HConnection 165 * @return HConnection object for <code>conf</code> 166 * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException 167 */ 168 @Deprecated 169 public static HConnection createConnection(Configuration conf, ExecutorService pool) 170 throws IOException { 171 return ConnectionManager.createConnection(conf, pool); 172 } 173 174 /** 175 * Create a new HConnection instance using the passed <code>conf</code> instance. 176 * <p>Note: This bypasses the usual HConnection life cycle management done by 177 * {@link #getConnection(Configuration)}. The caller is responsible for 178 * calling {@link HConnection#close()} on the returned connection instance. 179 * This is the recommended way to create HConnections. 180 * <pre> 181 * ExecutorService pool = ...; 182 * HConnection connection = HConnectionManager.createConnection(conf, pool); 183 * HTableInterface table = connection.getTable("mytable"); 184 * table.get(...); 185 * ... 186 * table.close(); 187 * connection.close(); 188 * </pre> 189 * @param conf configuration 190 * @param user the user the connection is for 191 * @return HConnection object for <code>conf</code> 192 * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException 193 */ 194 @Deprecated 195 public static HConnection createConnection(Configuration conf, User user) 196 throws IOException { 197 return ConnectionManager.createConnection(conf, user); 198 } 199 200 /** 201 * Create a new HConnection instance using the passed <code>conf</code> instance. 202 * <p>Note: This bypasses the usual HConnection life cycle management done by 203 * {@link #getConnection(Configuration)}. The caller is responsible for 204 * calling {@link HConnection#close()} on the returned connection instance. 205 * This is the recommended way to create HConnections. 206 * <pre> 207 * ExecutorService pool = ...; 208 * HConnection connection = HConnectionManager.createConnection(conf, pool); 209 * HTableInterface table = connection.getTable("mytable"); 210 * table.get(...); 211 * ... 212 * table.close(); 213 * connection.close(); 214 * </pre> 215 * @param conf configuration 216 * @param pool the thread pool to use for batch operation in HTables used via this HConnection 217 * @param user the user the connection is for 218 * @return HConnection object for <code>conf</code> 219 * @throws org.apache.hadoop.hbase.ZooKeeperConnectionException 220 */ 221 @Deprecated 222 public static HConnection createConnection(Configuration conf, ExecutorService pool, User user) 223 throws IOException { 224 return ConnectionManager.createConnection(conf, pool, user); 225 } 226 227 @Deprecated 228 static HConnection createConnection(final Configuration conf, final boolean managed) 229 throws IOException { 230 return ConnectionManager.createConnection(conf, managed); 231 } 232 233 @Deprecated 234 static ClusterConnection createConnection(final Configuration conf, final boolean managed, 235 final ExecutorService pool, final User user) throws IOException { 236 return ConnectionManager.createConnection(conf, managed, pool, user); 237 } 238 239 /** 240 * Delete connection information for the instance specified by passed configuration. 241 * If there are no more references to the designated connection connection, this method will 242 * then close connection to the zookeeper ensemble and let go of all associated resources. 243 * 244 * @param conf configuration whose identity is used to find {@link HConnection} instance. 245 * @deprecated 246 */ 247 @Deprecated 248 public static void deleteConnection(Configuration conf) { 249 ConnectionManager.deleteConnection(conf); 250 } 251 252 /** 253 * Cleanup a known stale connection. 254 * This will then close connection to the zookeeper ensemble and let go of all resources. 255 * 256 * @param connection 257 * @deprecated 258 */ 259 @Deprecated 260 public static void deleteStaleConnection(HConnection connection) { 261 ConnectionManager.deleteStaleConnection(connection); 262 } 263 264 /** 265 * Delete information for all connections. Close or not the connection, depending on the 266 * staleConnection boolean and the ref count. By default, you should use it with 267 * staleConnection to true. 268 * @deprecated 269 */ 270 @Deprecated 271 public static void deleteAllConnections(boolean staleConnection) { 272 ConnectionManager.deleteAllConnections(staleConnection); 273 } 274 275 /** 276 * Delete information for all connections.. 277 * @deprecated kept for backward compatibility, but the behavior is broken. HBASE-8983 278 */ 279 @Deprecated 280 public static void deleteAllConnections() { 281 ConnectionManager.deleteAllConnections(); 282 } 283 284 /** 285 * This convenience method invokes the given {@link HConnectable#connect} 286 * implementation using a {@link HConnection} instance that lasts just for the 287 * duration of the invocation. 288 * 289 * @param <T> the return type of the connect method 290 * @param connectable the {@link HConnectable} instance 291 * @return the value returned by the connect method 292 * @throws IOException 293 * @deprecated Internal method, do not use thru HConnectionManager. 294 */ 295 @InterfaceAudience.Private 296 @Deprecated 297 public static <T> T execute(HConnectable<T> connectable) throws IOException { 298 return ConnectionManager.execute(connectable); 299 } 300 301 /** 302 * Set the number of retries to use serverside when trying to communicate 303 * with another server over {@link HConnection}. Used updating catalog 304 * tables, etc. Call this method before we create any Connections. 305 * @param c The Configuration instance to set the retries into. 306 * @param log Used to log what we set in here. 307 * @deprecated Internal method, do not use. 308 */ 309 @InterfaceAudience.Private 310 @Deprecated 311 public static void setServerSideHConnectionRetries( 312 final Configuration c, final String sn, final Log log) { 313 ConnectionUtils.setServerSideHConnectionRetriesConfig(c, sn, log); 314 } 315 }