View Javadoc

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