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  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 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 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 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 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 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 }