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 class HConnectionManager extends ConnectionFactory {
90  
91    @Deprecated
92    public static final String RETRIES_BY_SERVER_KEY =
93        ConnectionManager.RETRIES_BY_SERVER_KEY;
94  
95    @Deprecated
96    public static final int MAX_CACHED_CONNECTION_INSTANCES =
97        ConnectionManager.MAX_CACHED_CONNECTION_INSTANCES;
98  
99    /*
100    * Non-instantiable.
101    */
102   private HConnectionManager() {
103     super();
104   }
105 
106   /**
107    * Get the connection that goes with the passed <code>conf</code> configuration instance.
108    * If no current connection exists, method creates a new connection and keys it using
109    * connection-specific properties from the passed {@link Configuration}; see
110    * {@link HConnectionKey}.
111    * @param conf configuration
112    * @return HConnection object for <code>conf</code>
113    * @throws ZooKeeperConnectionException
114    */
115   @Deprecated
116   public static HConnection getConnection(final Configuration conf) throws IOException {
117     return ConnectionManager.getConnectionInternal(conf);
118   }
119 
120   /**
121    * Create a new HConnection instance using the passed <code>conf</code> instance.
122    * <p>Note: This bypasses the usual HConnection life cycle management done by
123    * {@link #getConnection(Configuration)}. The caller is responsible for
124    * calling {@link HConnection#close()} on the returned connection instance.
125    *
126    * This is the recommended way to create HConnections.
127    * <pre>
128    * HConnection connection = HConnectionManager.createConnection(conf);
129    * HTableInterface table = connection.getTable("mytable");
130    * try {
131    *   table.get(...);
132    *   ...
133    * } finally {
134    *   table.close();
135    *   connection.close();
136    * }
137    * </pre>
138    *
139    * @param conf configuration
140    * @return HConnection object for <code>conf</code>
141    * @throws ZooKeeperConnectionException
142    */
143   @Deprecated
144   public static HConnection createConnection(Configuration conf) throws IOException {
145     return ConnectionManager.createConnectionInternal(conf);
146   }
147 
148 
149   /**
150    * Create a new HConnection instance using the passed <code>conf</code> instance.
151    * <p>Note: This bypasses the usual HConnection life cycle management done by
152    * {@link #getConnection(Configuration)}. The caller is responsible for
153    * calling {@link HConnection#close()} on the returned connection instance.
154    * This is the recommended way to create HConnections.
155    * <pre>
156    * ExecutorService pool = ...;
157    * HConnection connection = HConnectionManager.createConnection(conf, pool);
158    * HTableInterface table = connection.getTable("mytable");
159    * table.get(...);
160    * ...
161    * table.close();
162    * connection.close();
163    * </pre>
164    * @param conf configuration
165    * @param pool the thread pool to use for batch operation in HTables used via this HConnection
166    * @return HConnection object for <code>conf</code>
167    * @throws ZooKeeperConnectionException
168    */
169   @Deprecated
170   public static HConnection createConnection(Configuration conf, ExecutorService pool)
171       throws IOException {
172     return ConnectionManager.createConnection(conf, pool);
173   }
174 
175   /**
176    * Create a new HConnection instance using the passed <code>conf</code> instance.
177    * <p>Note: This bypasses the usual HConnection life cycle management done by
178    * {@link #getConnection(Configuration)}. The caller is responsible for
179    * calling {@link HConnection#close()} on the returned connection instance.
180    * This is the recommended way to create HConnections.
181    * <pre>
182    * ExecutorService pool = ...;
183    * HConnection connection = HConnectionManager.createConnection(conf, pool);
184    * HTableInterface table = connection.getTable("mytable");
185    * table.get(...);
186    * ...
187    * table.close();
188    * connection.close();
189    * </pre>
190    * @param conf configuration
191    * @param user the user the connection is for
192    * @return HConnection object for <code>conf</code>
193    * @throws ZooKeeperConnectionException
194    */
195   @Deprecated
196   public static HConnection createConnection(Configuration conf, User user)
197   throws IOException {
198     return ConnectionManager.createConnection(conf, user);
199   }
200 
201   /**
202    * Create a new HConnection instance using the passed <code>conf</code> instance.
203    * <p>Note: This bypasses the usual HConnection life cycle management done by
204    * {@link #getConnection(Configuration)}. The caller is responsible for
205    * calling {@link HConnection#close()} on the returned connection instance.
206    * This is the recommended way to create HConnections.
207    * <pre>
208    * ExecutorService pool = ...;
209    * HConnection connection = HConnectionManager.createConnection(conf, pool);
210    * HTableInterface table = connection.getTable("mytable");
211    * table.get(...);
212    * ...
213    * table.close();
214    * connection.close();
215    * </pre>
216    * @param conf configuration
217    * @param pool the thread pool to use for batch operation in HTables used via this HConnection
218    * @param user the user the connection is for
219    * @return HConnection object for <code>conf</code>
220    * @throws ZooKeeperConnectionException
221    */
222   @Deprecated
223   public static HConnection createConnection(Configuration conf, ExecutorService pool, User user)
224   throws IOException {
225     return ConnectionManager.createConnection(conf, pool, user);
226   }
227 
228   @Deprecated
229   static HConnection createConnection(final Configuration conf, final boolean managed)
230       throws IOException {
231     return ConnectionManager.createConnection(conf, managed);
232   }
233 
234   @Deprecated
235   static ClusterConnection createConnection(final Configuration conf, final boolean managed,
236       final ExecutorService pool, final User user) throws IOException {
237     return ConnectionManager.createConnection(conf, managed, pool, user);
238   }
239 
240   /**
241    * Delete connection information for the instance specified by passed configuration.
242    * If there are no more references to the designated connection connection, this method will
243    * then close connection to the zookeeper ensemble and let go of all associated resources.
244    *
245    * @param conf configuration whose identity is used to find {@link HConnection} instance.
246    * @deprecated
247    */
248   @Deprecated
249   public static void deleteConnection(Configuration conf) {
250     ConnectionManager.deleteConnection(conf);
251   }
252 
253   /**
254    * Cleanup a known stale connection.
255    * This will then close connection to the zookeeper ensemble and let go of all resources.
256    *
257    * @param connection
258    * @deprecated
259    */
260   @Deprecated
261   public static void deleteStaleConnection(HConnection connection) {
262     ConnectionManager.deleteStaleConnection(connection);
263   }
264 
265   /**
266    * Delete information for all connections. Close or not the connection, depending on the
267    *  staleConnection boolean and the ref count. By default, you should use it with
268    *  staleConnection to true.
269    * @deprecated
270    */
271   @Deprecated
272   public static void deleteAllConnections(boolean staleConnection) {
273     ConnectionManager.deleteAllConnections(staleConnection);
274   }
275 
276   /**
277    * Delete information for all connections..
278    * @deprecated kept for backward compatibility, but the behavior is broken. HBASE-8983
279    */
280   @Deprecated
281   public static void deleteAllConnections() {
282     ConnectionManager.deleteAllConnections();
283   }
284 
285   /**
286    * This convenience method invokes the given {@link HConnectable#connect}
287    * implementation using a {@link HConnection} instance that lasts just for the
288    * duration of the invocation.
289    *
290    * @param <T> the return type of the connect method
291    * @param connectable the {@link HConnectable} instance
292    * @return the value returned by the connect method
293    * @throws IOException
294    * @deprecated Internal method, do not use thru HConnectionManager.
295    */
296   @InterfaceAudience.Private
297   @Deprecated
298   public static <T> T execute(HConnectable<T> connectable) throws IOException {
299     return ConnectionManager.execute(connectable);
300   }
301 
302   /**
303    * Set the number of retries to use serverside when trying to communicate
304    * with another server over {@link HConnection}.  Used updating catalog
305    * tables, etc.  Call this method before we create any Connections.
306    * @param c The Configuration instance to set the retries into.
307    * @param log Used to log what we set in here.
308    * @deprecated Internal method, do not use.
309    */
310   @InterfaceAudience.Private
311   @Deprecated
312   public static void setServerSideHConnectionRetries(
313       final Configuration c, final String sn, final Log log) {
314     ConnectionUtils.setServerSideHConnectionRetriesConfig(c, sn, log);
315   }
316 }