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