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 org.apache.hadoop.conf.Configuration;
021import org.apache.hadoop.hbase.HConstants;
022import org.apache.yetus.audience.InterfaceAudience;
023
024/**
025 * Configuration parameters for the connection. Configuration is a heavy weight registry that does a
026 * lot of string operations and regex matching. Method calls into Configuration account for high CPU
027 * usage and have huge performance impact. This class caches connection-related configuration values
028 * in the ConnectionConfiguration object so that expensive conf.getXXX() calls are avoided every
029 * time HTable, etc is instantiated. see HBASE-12128
030 */
031@InterfaceAudience.Private
032public class ConnectionConfiguration {
033
034  public static final String WRITE_BUFFER_SIZE_KEY = "hbase.client.write.buffer";
035  public static final long WRITE_BUFFER_SIZE_DEFAULT = 2097152;
036  public static final String WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS =
037    "hbase.client.write.buffer.periodicflush.timeout.ms";
038  public static final String WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS =
039    "hbase.client.write.buffer.periodicflush.timertick.ms";
040  public static final long WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT = 0; // 0 == Disabled
041  public static final long WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT = 1000L; // 1 second
042  public static final String MAX_KEYVALUE_SIZE_KEY = "hbase.client.keyvalue.maxsize";
043  public static final int MAX_KEYVALUE_SIZE_DEFAULT = 10485760;
044  public static final String BUFFERED_MUTATOR_MAX_MUTATIONS_KEY =
045    "hbase.client.write.buffer.maxmutations";
046  public static final int BUFFERED_MUTATOR_MAX_MUTATIONS_DEFAULT = -1;
047  public static final String PRIMARY_CALL_TIMEOUT_MICROSECOND =
048    "hbase.client.primaryCallTimeout.get";
049  public static final int PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT = 10000; // 10ms
050  public static final String PRIMARY_SCAN_TIMEOUT_MICROSECOND =
051    "hbase.client.replicaCallTimeout.scan";
052  public static final int PRIMARY_SCAN_TIMEOUT_MICROSECOND_DEFAULT = 1000000; // 1s
053  public static final String LOG_SCANNER_ACTIVITY = "hbase.client.log.scanner.activity";
054
055  public static final String HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY =
056    "hbase.client.meta.read.rpc.timeout";
057  public static final String HBASE_CLIENT_META_SCANNER_TIMEOUT =
058    "hbase.client.meta.scanner.timeout.period";
059
060  public static final String HBASE_CLIENT_META_CACHE_INVALIDATE_INTERVAL =
061    "hbase.client.connection.metacache.invalidate-interval.ms";
062
063  private final long writeBufferSize;
064  private final long writeBufferPeriodicFlushTimeoutMs;
065  private final long writeBufferPeriodicFlushTimerTickMs;
066  private final int metaOperationTimeout;
067  private final int operationTimeout;
068  private final int scannerCaching;
069  private final long scannerMaxResultSize;
070  private final int primaryCallTimeoutMicroSecond;
071  private final int replicaCallTimeoutMicroSecondScan;
072  private final int metaReplicaCallTimeoutMicroSecondScan;
073  private final int retries;
074  private final int maxKeyValueSize;
075  private final int bufferedMutatorMaxMutations;
076  private final int rpcTimeout;
077  private final int readRpcTimeout;
078  private final int metaReadRpcTimeout;
079  private final int writeRpcTimeout;
080  // toggle for async/sync prefetch
081  private final boolean clientScannerAsyncPrefetch;
082
083  private static int getNonNegativeInt(Configuration conf, String key, int defaultValue) {
084    int value = conf.getInt(key, defaultValue);
085    if (value < 0) {
086      throw new IllegalArgumentException(
087        "The " + key + " must be non-negative, current value is " + value);
088    }
089    return value;
090  }
091
092  /**
093   * Constructor
094   * @param conf Configuration object
095   */
096  ConnectionConfiguration(Configuration conf) {
097    this.writeBufferSize = conf.getLong(WRITE_BUFFER_SIZE_KEY, WRITE_BUFFER_SIZE_DEFAULT);
098
099    this.writeBufferPeriodicFlushTimeoutMs = conf.getLong(WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS,
100      WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT);
101
102    this.writeBufferPeriodicFlushTimerTickMs = conf.getLong(
103      WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS, WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT);
104
105    this.operationTimeout = getNonNegativeInt(conf, HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
106      HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT);
107
108    this.metaOperationTimeout =
109      getNonNegativeInt(conf, HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT, operationTimeout);
110
111    this.scannerCaching = conf.getInt(HConstants.HBASE_CLIENT_SCANNER_CACHING,
112      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING);
113
114    this.scannerMaxResultSize = conf.getLong(HConstants.HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE_KEY,
115      HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE);
116
117    this.primaryCallTimeoutMicroSecond = getNonNegativeInt(conf, PRIMARY_CALL_TIMEOUT_MICROSECOND,
118      PRIMARY_CALL_TIMEOUT_MICROSECOND_DEFAULT);
119
120    this.replicaCallTimeoutMicroSecondScan = getNonNegativeInt(conf,
121      PRIMARY_SCAN_TIMEOUT_MICROSECOND, PRIMARY_SCAN_TIMEOUT_MICROSECOND_DEFAULT);
122
123    this.metaReplicaCallTimeoutMicroSecondScan =
124      getNonNegativeInt(conf, HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT,
125        HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT);
126
127    this.retries = conf.getInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER,
128      HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER);
129
130    this.clientScannerAsyncPrefetch = conf.getBoolean(Scan.HBASE_CLIENT_SCANNER_ASYNC_PREFETCH,
131      Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH);
132
133    this.maxKeyValueSize = conf.getInt(MAX_KEYVALUE_SIZE_KEY, MAX_KEYVALUE_SIZE_DEFAULT);
134
135    this.bufferedMutatorMaxMutations =
136      conf.getInt(BUFFERED_MUTATOR_MAX_MUTATIONS_KEY, BUFFERED_MUTATOR_MAX_MUTATIONS_DEFAULT);
137
138    this.rpcTimeout = getNonNegativeInt(conf, HConstants.HBASE_RPC_TIMEOUT_KEY,
139      HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
140
141    this.readRpcTimeout =
142      getNonNegativeInt(conf, HConstants.HBASE_RPC_READ_TIMEOUT_KEY, rpcTimeout);
143
144    this.metaReadRpcTimeout =
145      getNonNegativeInt(conf, HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY, readRpcTimeout);
146
147    this.writeRpcTimeout =
148      getNonNegativeInt(conf, HConstants.HBASE_RPC_WRITE_TIMEOUT_KEY, rpcTimeout);
149  }
150
151  /**
152   * Constructor This is for internal testing purpose (using the default value). In real usage, we
153   * should read the configuration from the Configuration object.
154   */
155  protected ConnectionConfiguration() {
156    this.writeBufferSize = WRITE_BUFFER_SIZE_DEFAULT;
157    this.writeBufferPeriodicFlushTimeoutMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMEOUT_MS_DEFAULT;
158    this.writeBufferPeriodicFlushTimerTickMs = WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS_DEFAULT;
159    this.metaOperationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
160    this.operationTimeout = HConstants.DEFAULT_HBASE_CLIENT_OPERATION_TIMEOUT;
161    this.scannerCaching = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING;
162    this.scannerMaxResultSize = HConstants.DEFAULT_HBASE_CLIENT_SCANNER_MAX_RESULT_SIZE;
163    this.primaryCallTimeoutMicroSecond = 10000;
164    this.replicaCallTimeoutMicroSecondScan = 1000000;
165    this.metaReplicaCallTimeoutMicroSecondScan =
166      HConstants.HBASE_CLIENT_META_REPLICA_SCAN_TIMEOUT_DEFAULT;
167    this.retries = HConstants.DEFAULT_HBASE_CLIENT_RETRIES_NUMBER;
168    this.clientScannerAsyncPrefetch = Scan.DEFAULT_HBASE_CLIENT_SCANNER_ASYNC_PREFETCH;
169    this.maxKeyValueSize = MAX_KEYVALUE_SIZE_DEFAULT;
170    this.bufferedMutatorMaxMutations = BUFFERED_MUTATOR_MAX_MUTATIONS_DEFAULT;
171    this.readRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
172    this.metaReadRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
173    this.writeRpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
174    this.rpcTimeout = HConstants.DEFAULT_HBASE_RPC_TIMEOUT;
175  }
176
177  public int getReadRpcTimeout() {
178    return readRpcTimeout;
179  }
180
181  public int getMetaReadRpcTimeout() {
182    return metaReadRpcTimeout;
183  }
184
185  public int getWriteRpcTimeout() {
186    return writeRpcTimeout;
187  }
188
189  public long getWriteBufferSize() {
190    return writeBufferSize;
191  }
192
193  public long getWriteBufferPeriodicFlushTimeoutMs() {
194    return writeBufferPeriodicFlushTimeoutMs;
195  }
196
197  public long getWriteBufferPeriodicFlushTimerTickMs() {
198    return writeBufferPeriodicFlushTimerTickMs;
199  }
200
201  public int getMetaOperationTimeout() {
202    return metaOperationTimeout;
203  }
204
205  public int getOperationTimeout() {
206    return operationTimeout;
207  }
208
209  public int getScannerCaching() {
210    return scannerCaching;
211  }
212
213  public int getPrimaryCallTimeoutMicroSecond() {
214    return primaryCallTimeoutMicroSecond;
215  }
216
217  public int getReplicaCallTimeoutMicroSecondScan() {
218    return replicaCallTimeoutMicroSecondScan;
219  }
220
221  public int getMetaReplicaCallTimeoutMicroSecondScan() {
222    return metaReplicaCallTimeoutMicroSecondScan;
223  }
224
225  public int getRetriesNumber() {
226    return retries;
227  }
228
229  public int getMaxKeyValueSize() {
230    return maxKeyValueSize;
231  }
232
233  public int getBufferedMutatorMaxMutations() {
234    return bufferedMutatorMaxMutations;
235  }
236
237  public long getScannerMaxResultSize() {
238    return scannerMaxResultSize;
239  }
240
241  public boolean isClientScannerAsyncPrefetch() {
242    return clientScannerAsyncPrefetch;
243  }
244
245  public int getRpcTimeout() {
246    return rpcTimeout;
247  }
248}