001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.client;
019
020import static org.apache.hadoop.hbase.HConstants.DEFAULT_HBASE_CLIENT_PAUSE;
021import static org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_PAUSE;
022
023import org.apache.hadoop.conf.Configuration;
024import org.apache.hadoop.hbase.HConstants;
025import org.apache.yetus.audience.InterfaceAudience;
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029/**
030 * Configuration parameters for the connection. Configuration is a heavy weight registry that does a
031 * lot of string operations and regex matching. Method calls into Configuration account for high CPU
032 * usage and have huge performance impact. This class caches connection-related configuration values
033 * in the ConnectionConfiguration object so that expensive conf.getXXX() calls are avoided every
034 * time HTable, etc is instantiated. see HBASE-12128
035 */
036@InterfaceAudience.Private
037public class ConnectionConfiguration {
038  private static final Logger LOG = LoggerFactory.getLogger(ConnectionConfiguration.class);
039
040  public static final String WRITE_BUFFER_SIZE_KEY = "hbase.client.write.buffer";
041  public static final long WRITE_BUFFER_SIZE_DEFAULT = 2097152;
042  public static final String WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS =
043    "hbase.client.write.buffer.periodicflush.timeout.ms";
044  public static final String WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS =
045    "hbase.client.write.buffer.periodicflush.timertick.ms";
046  public static final long WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT = 0; // 0 == Disabled
047  public static final long WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT = 1000L; // 1 second
048  public static final String MAX_KEYVALUE_SIZE_KEY = "hbase.client.keyvalue.maxsize";
049  public static final int MAX_KEYVALUE_SIZE_DEFAULT = 10485760;
050  public static final String PRIMARY_CALL_TIMEOUT_MICROSECOND =
051    "hbase.client.primaryCallTimeout.get";
052  public static final int PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT = 10000; // 10ms
053  public static final String PRIMARY_SCAN_TIMEOUT_MICROSECOND =
054    "hbase.client.replicaCallTimeout.scan";
055  public static final int PRIMARY_SCAN_TIMEOUT_MICROSECOND_DEFAULT = 1000000; // 1s
056
057  /**
058   * Parameter name for client pause when server is overloaded, denoted by an exception where
059   * {@link org.apache.hadoop.hbase.HBaseServerException#isServerOverloaded(Throwable)} is true.
060   */
061  public static final String HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED =
062    "hbase.client.pause.server.overloaded";
063
064  static {
065    // This is added where the configs are referenced. It may be too late to happen before
066    // any user _sets_ the old cqtbe config onto a Configuration option. So we still need
067    // to handle checking both properties in parsing below. The benefit of calling this is
068    // that it should still cause Configuration to log a warning if we do end up falling
069    // through to the old deprecated config.
070    Configuration.addDeprecation(HConstants.HBASE_CLIENT_PAUSE_FOR_CQTBE,
071      HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED);
072  }
073
074  public static final String HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY =
075    "hbase.client.meta.read.rpc.timeout";
076  public static final String HBASE_CLIENT_META_SCANNER_TIMEOUT =
077    "hbase.client.meta.scanner.timeout.period";
078
079  public static final String HBASE_CLIENT_USE_SCANNER_TIMEOUT_PERIOD_FOR_NEXT_CALLS =
080    "hbase.client.use.scanner.timeout.period.for.next.calls";
081
082  public static final boolean HBASE_CLIENT_USE_SCANNER_TIMEOUT_PERIOD_FOR_NEXT_CALLS_DEFAULT =
083    false;
084
085  private final long writeBufferSize;
086  private final long writeBufferPeriodicFlushTimeoutMs;
087  private final long writeBufferPeriodicFlushTimerTickMs;
088  private final int metaOperationTimeout;
089  private final int operationTimeout;
090  private final int scannerCaching;
091  private final long scannerMaxResultSize;
092  private final int primaryCallTimeoutMicroSecond;
093  private final int replicaCallTimeoutMicroSecondScan;
094  private final int metaReplicaCallTimeoutMicroSecondScan;
095  private final int retries;
096  private final int maxKeyValueSize;
097  private final int rpcTimeout;
098  private final int readRpcTimeout;
099  private final int metaReadRpcTimeout;
100  private final int writeRpcTimeout;
101  private final int scanTimeout;
102  private final int metaScanTimeout;
103
104  // toggle for async/sync prefetch
105  private final boolean clientScannerAsyncPrefetch;
106  private final long pauseMs;
107  private final long pauseMsForServerOverloaded;
108  private final boolean useScannerTimeoutForNextCalls;
109
110  /**
111   * Constructor
112   * @param conf Configuration object
113   */
114  ConnectionConfiguration(Configuration conf) {
115    this.writeBufferSize = conf.getLong(WRITE_BUFFER_SIZE_KEY, WRITE_BUFFER_SIZE_DEFAULT);
116
117    this.writeBufferPeriodicFlushTimeoutMs = conf.getLong(WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS,
118      WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT);
119
120    this.writeBufferPeriodicFlushTimerTickMs = conf.getLong(
121      WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS, WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT);
122
123    this.metaOperationTimeout = conf.getInt(HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT,
124      HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
125
126    this.operationTimeout = conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
127      HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
128
129    this.scannerCaching = conf.getInt(HConstants.HBASE_CLIENT_SCANNER_CACHING,
130      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING);
131
132    this.scannerMaxResultSize = conf.getLong(HConstants.HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE_KEY,
133      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
134
135    this.primaryCallTimeoutMicroSecond =
136      conf.getInt(PRIMARY_CALL_TIMEOUT_MICROSECOND, PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT);
137
138    this.replicaCallTimeoutMicroSecondScan =
139      conf.getInt(PRIMARY_SCAN_TIMEOUT_MICROSECOND, PRIMARY_SCAN_TIMEOUT_MICROSECOND_DEFAULT);
140
141    this.metaReplicaCallTimeoutMicroSecondScan =
142      conf.getInt(HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT,
143        HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT);
144
145    this.retries = conf.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
146      HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
147
148    this.clientScannerAsyncPrefetch = conf.getBoolean(Scan.HBASE_CLIENT_SCANNER_ASYNC_PREFETCH,
149      Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH);
150
151    this.maxKeyValueSize = conf.getInt(MAX_KEYVALUE_SIZE_KEY, MAX_KEYVALUE_SIZE_DEFAULT);
152
153    this.rpcTimeout =
154      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
155
156    this.readRpcTimeout = conf.getInt(HConstants.HBASE_RPC_READ_TIMEOUT_KEY,
157      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT));
158
159    this.metaReadRpcTimeout = conf.getInt(HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY, readRpcTimeout);
160
161    this.writeRpcTimeout = conf.getInt(HConstants.HBASE_RPC_WRITE_TIMEOUT_KEY,
162      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT));
163
164    this.scanTimeout = conf.getInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD,
165      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD);
166
167    this.metaScanTimeout = conf.getInt(HBASE_CLIENT_META_SCANNER_TIMEOUT, scanTimeout);
168    this.useScannerTimeoutForNextCalls =
169      conf.getBoolean(HBASE_CLIENT_USE_SCANNER_TIMEOUT_PERIOD_FOR_NEXT_CALLS,
170        HBASE_CLIENT_USE_SCANNER_TIMEOUT_PERIOD_FOR_NEXT_CALLS_DEFAULT);
171
172    long pauseMs = conf.getLong(HBASE_CLIENT_PAUSE, DEFAULT_HBASE_CLIENT_PAUSE);
173    long pauseMsForServerOverloaded = conf.getLong(HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED,
174      conf.getLong(HConstants.HBASE_CLIENT_PAUSE_FOR_CQTBE, pauseMs));
175    if (pauseMsForServerOverloaded < pauseMs) {
176      LOG.warn(
177        "The {} setting: {} ms is less than the {} setting: {} ms, use the greater one instead",
178        HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED, pauseMsForServerOverloaded, HBASE_CLIENT_PAUSE,
179        pauseMs);
180      pauseMsForServerOverloaded = pauseMs;
181    }
182
183    this.pauseMs = pauseMs;
184    this.pauseMsForServerOverloaded = pauseMsForServerOverloaded;
185  }
186
187  /**
188   * Constructor This is for internal testing purpose (using the default value). In real usage, we
189   * should read the configuration from the Configuration object.
190   */
191  protected ConnectionConfiguration() {
192    this.writeBufferSize = WRITE_BUFFER_SIZE_DEFAULT;
193    this.writeBufferPeriodicFlushTimeoutMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT;
194    this.writeBufferPeriodicFlushTimerTickMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT;
195    this.metaOperationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
196    this.operationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
197    this.scannerCaching = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING;
198    this.scannerMaxResultSize = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE;
199    this.primaryCallTimeoutMicroSecond = 10000;
200    this.replicaCallTimeoutMicroSecondScan = 1000000;
201    this.metaReplicaCallTimeoutMicroSecondScan =
202      HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT;
203    this.retries = HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER;
204    this.clientScannerAsyncPrefetch = Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH;
205    this.maxKeyValueSize = MAX_KEYVALUE_SIZE_DEFAULT;
206    this.readRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
207    this.metaReadRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
208    this.writeRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
209    this.rpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
210    this.scanTimeout = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD;
211    this.metaScanTimeout = scanTimeout;
212    this.pauseMs = DEFAULT_HBASE_CLIENT_PAUSE;
213    this.pauseMsForServerOverloaded = DEFAULT_HBASE_CLIENT_PAUSE;
214    this.useScannerTimeoutForNextCalls =
215      HBASE_CLIENT_USE_SCANNER_TIMEOUT_PERIOD_FOR_NEXT_CALLS_DEFAULT;
216  }
217
218  public int getReadRpcTimeout() {
219    return readRpcTimeout;
220  }
221
222  public int getMetaReadRpcTimeout() {
223    return metaReadRpcTimeout;
224  }
225
226  public int getWriteRpcTimeout() {
227    return writeRpcTimeout;
228  }
229
230  public long getWriteBufferSize() {
231    return writeBufferSize;
232  }
233
234  public long getWriteBufferPeriodicFlushTimeoutMs() {
235    return writeBufferPeriodicFlushTimeoutMs;
236  }
237
238  public long getWriteBufferPeriodicFlushTimerTickMs() {
239    return writeBufferPeriodicFlushTimerTickMs;
240  }
241
242  public int getMetaOperationTimeout() {
243    return metaOperationTimeout;
244  }
245
246  public int getOperationTimeout() {
247    return operationTimeout;
248  }
249
250  public int getScannerCaching() {
251    return scannerCaching;
252  }
253
254  public int getPrimaryCallTimeoutMicroSecond() {
255    return primaryCallTimeoutMicroSecond;
256  }
257
258  public int getReplicaCallTimeoutMicroSecondScan() {
259    return replicaCallTimeoutMicroSecondScan;
260  }
261
262  public int getMetaReplicaCallTimeoutMicroSecondScan() {
263    return metaReplicaCallTimeoutMicroSecondScan;
264  }
265
266  public int getRetriesNumber() {
267    return retries;
268  }
269
270  public int getMaxKeyValueSize() {
271    return maxKeyValueSize;
272  }
273
274  public long getScannerMaxResultSize() {
275    return scannerMaxResultSize;
276  }
277
278  public boolean isClientScannerAsyncPrefetch() {
279    return clientScannerAsyncPrefetch;
280  }
281
282  public int getRpcTimeout() {
283    return rpcTimeout;
284  }
285
286  public int getScanTimeout() {
287    return scanTimeout;
288  }
289
290  public boolean isUseScannerTimeoutForNextCalls() {
291    return useScannerTimeoutForNextCalls;
292  }
293
294  public int getMetaScanTimeout() {
295    return metaScanTimeout;
296  }
297
298  public long getPauseMillis() {
299    return pauseMs;
300  }
301
302  public long getPauseMillisForServerOverloaded() {
303    return pauseMsForServerOverloaded;
304  }
305}