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 java.io.Closeable;
021import java.io.IOException;
022import java.util.Collections;
023import java.util.List;
024import java.util.Map;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.hadoop.hbase.TableName;
027import org.apache.yetus.audience.InterfaceAudience;
028
029/**
030 * <p>
031 * Used to communicate with a single HBase table similar to {@link Table} but meant for batched,
032 * asynchronous puts. Obtain an instance from a {@link Connection} and call {@link #close()}
033 * afterwards. Customizations can be applied to the {@code BufferedMutator} via the
034 * {@link BufferedMutatorParams}.
035 * </p>
036 * <p>
037 * Exception handling with asynchronously via the {@link BufferedMutator.ExceptionListener}. The
038 * default implementation is to throw the exception upon receipt. This behavior can be overridden
039 * with a custom implementation, provided as a parameter with
040 * {@link BufferedMutatorParams#listener(BufferedMutator.ExceptionListener)}.
041 * </p>
042 * <p>
043 * Map/Reduce jobs are good use cases for using {@code BufferedMutator}. Map/reduce jobs benefit
044 * from batching, but have no natural flush point. {@code BufferedMutator} receives the puts from
045 * the M/R job and will batch puts based on some heuristic, such as the accumulated size of the
046 * puts, and submit batches of puts asynchronously so that the M/R logic can continue without
047 * interruption.
048 * </p>
049 * <p>
050 * {@code BufferedMutator} can also be used on more exotic circumstances. Map/Reduce batch jobs will
051 * have a single {@code BufferedMutator} per thread. A single {@code BufferedMutator} can also be
052 * effectively used in high volume online systems to batch puts, with the caveat that extreme
053 * circumstances, such as JVM or machine failure, may cause some data loss.
054 * </p>
055 * <p>
056 * NOTE: This class replaces the functionality that used to be available via
057 * HTable#setAutoFlush(boolean) set to {@code false}.
058 * </p>
059 * <p>
060 * See also the {@code BufferedMutatorExample} in the hbase-examples module.
061 * </p>
062 * @see ConnectionFactory
063 * @see Connection
064 * @since 1.0.0
065 */
066@InterfaceAudience.Public
067public interface BufferedMutator extends Closeable {
068  /**
069   * Key to use setting non-default BufferedMutator implementation in Configuration.
070   * <p/>
071   * @deprecated Since 3.0.0, will be removed in 4.0.0. For internal test use only, do not use it
072   *             any more.
073   */
074  @Deprecated
075  String CLASSNAME_KEY = "hbase.client.bufferedmutator.classname";
076
077  /**
078   * Having the timer tick run more often that once every 100ms is needless and will probably cause
079   * too many timer events firing having a negative impact on performance.
080   */
081  long MIN_WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS = 100;
082
083  /**
084   * Gets the fully qualified table name instance of the table that this BufferedMutator writes to.
085   */
086  TableName getName();
087
088  /**
089   * Returns the {@link org.apache.hadoop.conf.Configuration} object used by this instance.
090   * <p>
091   * The reference returned is not a copy, so any change made to it will affect this instance.
092   */
093  Configuration getConfiguration();
094
095  /**
096   * Sends a {@link Mutation} to the table. The mutations will be buffered and sent over the wire as
097   * part of a batch. Currently only supports {@link Put} and {@link Delete} mutations.
098   * @param mutation The data to send.
099   * @throws IOException if a remote or network exception occurs.
100   */
101  void mutate(Mutation mutation) throws IOException;
102
103  /**
104   * Send some {@link Mutation}s to the table. The mutations will be buffered and sent over the wire
105   * as part of a batch. There is no guarantee of sending entire content of {@code mutations} in a
106   * single batch; it will be broken up according to the write buffer capacity.
107   * @param mutations The data to send.
108   * @throws IOException if a remote or network exception occurs.
109   */
110  void mutate(List<? extends Mutation> mutations) throws IOException;
111
112  /**
113   * Performs a {@link #flush()} and releases any resources held.
114   * @throws IOException if a remote or network exception occurs.
115   */
116  @Override
117  void close() throws IOException;
118
119  /**
120   * Executes all the buffered, asynchronous {@link Mutation} operations and waits until they are
121   * done.
122   * @throws IOException if a remote or network exception occurs.
123   */
124  void flush() throws IOException;
125
126  /**
127   * Sets the maximum time before the buffer is automatically flushed checking once per second.
128   * @param timeoutMs The maximum number of milliseconds how long records may be buffered before
129   *                  they are flushed. Set to 0 to disable.
130   */
131  default void setWriteBufferPeriodicFlush(long timeoutMs) {
132    setWriteBufferPeriodicFlush(timeoutMs, 1000L);
133  }
134
135  /**
136   * Sets the maximum time before the buffer is automatically flushed.
137   * @param timeoutMs   The maximum number of milliseconds how long records may be buffered before
138   *                    they are flushed. Set to 0 to disable.
139   * @param timerTickMs The number of milliseconds between each check if the timeout has been
140   *                    exceeded. Must be 100ms (as defined in
141   *                    {@link #MIN_WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS}) or larger to avoid
142   *                    performance problems.
143   */
144  default void setWriteBufferPeriodicFlush(long timeoutMs, long timerTickMs) {
145    throw new UnsupportedOperationException(
146      "The BufferedMutator::setWriteBufferPeriodicFlush has not been implemented");
147  }
148
149  /**
150   * Disable periodic flushing of the write buffer.
151   */
152  default void disableWriteBufferPeriodicFlush() {
153    setWriteBufferPeriodicFlush(0, MIN_WRITE_BUFFER_PERIODIC_FLUSH_TIMERTICK_MS);
154  }
155
156  /**
157   * Returns the current periodic flush timeout value in milliseconds.
158   * @return The maximum number of milliseconds how long records may be buffered before they are
159   *         flushed. The value 0 means this is disabled.
160   */
161  default long getWriteBufferPeriodicFlushTimeoutMs() {
162    throw new UnsupportedOperationException(
163      "The BufferedMutator::getWriteBufferPeriodicFlushTimeoutMs has not been implemented");
164  }
165
166  /**
167   * Returns the current periodic flush timertick interval in milliseconds.
168   * @return The number of milliseconds between each check if the timeout has been exceeded. This
169   *         value only has a real meaning if the timeout has been set to > 0
170   */
171  default long getWriteBufferPeriodicFlushTimerTickMs() {
172    throw new UnsupportedOperationException(
173      "The BufferedMutator::getWriteBufferPeriodicFlushTimerTickMs has not been implemented");
174  }
175
176  /**
177   * Returns the maximum size in bytes of the write buffer for this HTable.
178   * <p>
179   * The default value comes from the configuration parameter {@code hbase.client.write.buffer}.
180   * @return The size of the write buffer in bytes.
181   */
182  default long getWriteBufferSize() {
183    throw new UnsupportedOperationException(
184      "The BufferedMutator::getWriteBufferSize has not been implemented");
185  }
186
187  /**
188   * Set rpc timeout for this mutator instance
189   * @deprecated Since 3.0.0, will be removed in 4.0.0. Please set this through the
190   *             {@link BufferedMutatorParams}.
191   */
192  @Deprecated
193  default void setRpcTimeout(int timeout) {
194    throw new UnsupportedOperationException(
195      "The BufferedMutator::setRpcTimeout has not been implemented");
196  }
197
198  /**
199   * Set operation timeout for this mutator instance
200   * @deprecated Since 3.0.0, will be removed in 4.0.0. Please set this through the
201   *             {@link BufferedMutatorParams}.
202   */
203  @Deprecated
204  default void setOperationTimeout(int timeout) {
205    throw new UnsupportedOperationException(
206      "The BufferedMutator::setOperationTimeout has not been implemented");
207  }
208
209  /**
210   * Returns the rpc request attributes.
211   */
212  default Map<String, byte[]> getRequestAttributes() {
213    return Collections.emptyMap();
214  }
215
216  /**
217   * Listens for asynchronous exceptions on a {@link BufferedMutator}.
218   */
219  @InterfaceAudience.Public
220  interface ExceptionListener {
221    public void onException(RetriesExhaustedWithDetailsException exception, BufferedMutator mutator)
222      throws RetriesExhaustedWithDetailsException;
223  }
224}