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.classification.InterfaceAudience;
25  import org.apache.hadoop.classification.InterfaceStability;
26  import org.apache.hadoop.conf.Configuration;
27  import org.apache.hadoop.hbase.ZooKeeperConnectionException;
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   * {@code
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    * {@code
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    *
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    * {@code
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    * }
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    * {@code
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    * }
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    * {@code
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    * }
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 }