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