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  private final long writeBufferSize;
080  private final long writeBufferPeriodicFlushTimeoutMs;
081  private final long writeBufferPeriodicFlushTimerTickMs;
082  private final int metaOperationTimeout;
083  private final int operationTimeout;
084  private final int scannerCaching;
085  private final long scannerMaxResultSize;
086  private final int primaryCallTimeoutMicroSecond;
087  private final int replicaCallTimeoutMicroSecondScan;
088  private final int metaReplicaCallTimeoutMicroSecondScan;
089  private final int retries;
090  private final int maxKeyValueSize;
091  private final int rpcTimeout;
092  private final int readRpcTimeout;
093  private final int metaReadRpcTimeout;
094  private final int writeRpcTimeout;
095  private final int scanTimeout;
096  private final int metaScanTimeout;
097
098  // toggle for async/sync prefetch
099  private final boolean clientScannerAsyncPrefetch;
100  private final long pauseMs;
101  private final long pauseMsForServerOverloaded;
102
103  /**
104   * Constructor
105   * @param conf Configuration object
106   */
107  ConnectionConfiguration(Configuration conf) {
108    this.writeBufferSize = conf.getLong(WRITE_BUFFER_SIZE_KEY, WRITE_BUFFER_SIZE_DEFAULT);
109
110    this.writeBufferPeriodicFlushTimeoutMs = conf.getLong(WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS,
111      WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT);
112
113    this.writeBufferPeriodicFlushTimerTickMs = conf.getLong(
114      WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS, WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT);
115
116    this.metaOperationTimeout = conf.getInt(HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT,
117      HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
118
119    this.operationTimeout = conf.getInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
120      HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
121
122    this.scannerCaching = conf.getInt(HConstants.HBASE_CLIENT_SCANNER_CACHING,
123      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING);
124
125    this.scannerMaxResultSize = conf.getLong(HConstants.HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE_KEY,
126      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
127
128    this.primaryCallTimeoutMicroSecond =
129      conf.getInt(PRIMARY_CALL_TIMEOUT_MICROSECOND, PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT);
130
131    this.replicaCallTimeoutMicroSecondScan =
132      conf.getInt(PRIMARY_SCAN_TIMEOUT_MICROSECOND, PRIMARY_SCAN_TIMEOUT_MICROSECOND_DEFAULT);
133
134    this.metaReplicaCallTimeoutMicroSecondScan =
135      conf.getInt(HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT,
136        HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT);
137
138    this.retries = conf.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
139      HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
140
141    this.clientScannerAsyncPrefetch = conf.getBoolean(Scan.HBASE_CLIENT_SCANNER_ASYNC_PREFETCH,
142      Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH);
143
144    this.maxKeyValueSize = conf.getInt(MAX_KEYVALUE_SIZE_KEY, MAX_KEYVALUE_SIZE_DEFAULT);
145
146    this.rpcTimeout =
147      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
148
149    this.readRpcTimeout = conf.getInt(HConstants.HBASE_RPC_READ_TIMEOUT_KEY,
150      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT));
151
152    this.metaReadRpcTimeout = conf.getInt(HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY, readRpcTimeout);
153
154    this.writeRpcTimeout = conf.getInt(HConstants.HBASE_RPC_WRITE_TIMEOUT_KEY,
155      conf.getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT));
156
157    this.scanTimeout = conf.getInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD,
158      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD);
159
160    this.metaScanTimeout = conf.getInt(HBASE_CLIENT_META_SCANNER_TIMEOUT, scanTimeout);
161
162    long pauseMs = conf.getLong(HBASE_CLIENT_PAUSE, DEFAULT_HBASE_CLIENT_PAUSE);
163    long pauseMsForServerOverloaded = conf.getLong(HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED,
164      conf.getLong(HConstants.HBASE_CLIENT_PAUSE_FOR_CQTBE, pauseMs));
165    if (pauseMsForServerOverloaded < pauseMs) {
166      LOG.warn(
167        "The {} setting: {} ms is less than the {} setting: {} ms, use the greater one instead",
168        HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED, pauseMsForServerOverloaded, HBASE_CLIENT_PAUSE,
169        pauseMs);
170      pauseMsForServerOverloaded = pauseMs;
171    }
172
173    this.pauseMs = pauseMs;
174    this.pauseMsForServerOverloaded = pauseMsForServerOverloaded;
175  }
176
177  /**
178   * Constructor This is for internal testing purpose (using the default value). In real usage, we
179   * should read the configuration from the Configuration object.
180   */
181  protected ConnectionConfiguration() {
182    this.writeBufferSize = WRITE_BUFFER_SIZE_DEFAULT;
183    this.writeBufferPeriodicFlushTimeoutMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT;
184    this.writeBufferPeriodicFlushTimerTickMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT;
185    this.metaOperationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
186    this.operationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
187    this.scannerCaching = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING;
188    this.scannerMaxResultSize = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE;
189    this.primaryCallTimeoutMicroSecond = 10000;
190    this.replicaCallTimeoutMicroSecondScan = 1000000;
191    this.metaReplicaCallTimeoutMicroSecondScan =
192      HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT;
193    this.retries = HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER;
194    this.clientScannerAsyncPrefetch = Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH;
195    this.maxKeyValueSize = MAX_KEYVALUE_SIZE_DEFAULT;
196    this.readRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
197    this.metaReadRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
198    this.writeRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
199    this.rpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
200    this.scanTimeout = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD;
201    this.metaScanTimeout = scanTimeout;
202    this.pauseMs = DEFAULT_HBASE_CLIENT_PAUSE;
203    this.pauseMsForServerOverloaded = DEFAULT_HBASE_CLIENT_PAUSE;
204  }
205
206  public int getReadRpcTimeout() {
207    return readRpcTimeout;
208  }
209
210  public int getMetaReadRpcTimeout() {
211    return metaReadRpcTimeout;
212  }
213
214  public int getWriteRpcTimeout() {
215    return writeRpcTimeout;
216  }
217
218  public long getWriteBufferSize() {
219    return writeBufferSize;
220  }
221
222  public long getWriteBufferPeriodicFlushTimeoutMs() {
223    return writeBufferPeriodicFlushTimeoutMs;
224  }
225
226  public long getWriteBufferPeriodicFlushTimerTickMs() {
227    return writeBufferPeriodicFlushTimerTickMs;
228  }
229
230  public int getMetaOperationTimeout() {
231    return metaOperationTimeout;
232  }
233
234  public int getOperationTimeout() {
235    return operationTimeout;
236  }
237
238  public int getScannerCaching() {
239    return scannerCaching;
240  }
241
242  public int getPrimaryCallTimeoutMicroSecond() {
243    return primaryCallTimeoutMicroSecond;
244  }
245
246  public int getReplicaCallTimeoutMicroSecondScan() {
247    return replicaCallTimeoutMicroSecondScan;
248  }
249
250  public int getMetaReplicaCallTimeoutMicroSecondScan() {
251    return metaReplicaCallTimeoutMicroSecondScan;
252  }
253
254  public int getRetriesNumber() {
255    return retries;
256  }
257
258  public int getMaxKeyValueSize() {
259    return maxKeyValueSize;
260  }
261
262  public long getScannerMaxResultSize() {
263    return scannerMaxResultSize;
264  }
265
266  public boolean isClientScannerAsyncPrefetch() {
267    return clientScannerAsyncPrefetch;
268  }
269
270  public int getRpcTimeout() {
271    return rpcTimeout;
272  }
273
274  public int getScanTimeout() {
275    return scanTimeout;
276  }
277
278  public int getMetaScanTimeout() {
279    return metaScanTimeout;
280  }
281
282  public long getPauseMillis() {
283    return pauseMs;
284  }
285
286  public long getPauseMillisForServerOverloaded() {
287    return pauseMsForServerOverloaded;
288  }
289}