18
18
package com .alipay .oceanbase .hbase .util ;
19
19
20
20
import com .alipay .oceanbase .hbase .OHTable ;
21
- import com .google .common .annotations .VisibleForTesting ;
21
+ import com .alipay .oceanbase .rpc .exception .ObTableUnexpectedException ;
22
+ import com .alipay .oceanbase .rpc .protocol .payload .impl .execute .ObTableBatchOperation ;
22
23
import org .apache .hadoop .classification .InterfaceAudience ;
23
24
import org .apache .hadoop .conf .Configuration ;
25
+ import org .apache .hadoop .hbase .KeyValue ;
24
26
import org .apache .hadoop .hbase .TableName ;
25
27
import org .apache .hadoop .hbase .client .*;
26
28
import org .slf4j .Logger ;
31
33
import java .util .concurrent .ExecutorService ;
32
34
import java .util .concurrent .TimeUnit ;
33
35
import java .util .concurrent .atomic .AtomicLong ;
34
- import static com .alipay .oceanbase .rpc .util .TableClientLoggerFactory .LCD ;
36
+
37
+ import static com .alipay .oceanbase .hbase .util .TableHBaseLoggerFactory .LCD ;
38
+ import static com .alipay .oceanbase .rpc .ObGlobal .*;
35
39
36
40
@ InterfaceAudience .Private
37
41
public class OHBufferedMutatorImpl implements BufferedMutator {
@@ -40,13 +44,11 @@ public class OHBufferedMutatorImpl implements BufferedMutator {
40
44
41
45
private final ExceptionListener listener ;
42
46
43
- private final OHTable ohTable ;
44
47
private final TableName tableName ;
45
48
private volatile Configuration conf ;
46
49
47
- @ VisibleForTesting
50
+ private OHTable ohTable ;
48
51
final ConcurrentLinkedQueue <Mutation > asyncWriteBuffer = new ConcurrentLinkedQueue <Mutation >();
49
- @ VisibleForTesting
50
52
AtomicLong currentAsyncBufferSize = new AtomicLong (0 );
51
53
52
54
private long writeBufferSize ;
@@ -55,9 +57,11 @@ public class OHBufferedMutatorImpl implements BufferedMutator {
55
57
private final ExecutorService pool ;
56
58
private int rpcTimeout ;
57
59
private int operationTimeout ;
60
+ private static final long OB_VERSION_4_2_5_1 = calcVersion (4 , (short ) 2 ,
61
+ (byte ) 5 , (byte ) 1 );
58
62
59
- public OHBufferedMutatorImpl (OHConnectionImpl ohConnection , BufferedMutatorParams params )
60
- throws IOException {
63
+ public OHBufferedMutatorImpl (OHConnectionImpl ohConnection , BufferedMutatorParams params ,
64
+ OHTable ohTable ) throws IOException {
61
65
if (ohConnection == null || ohConnection .isClosed ()) {
62
66
throw new IllegalArgumentException ("Connection is null or closed." );
63
67
}
@@ -77,7 +81,38 @@ public OHBufferedMutatorImpl(OHConnectionImpl ohConnection, BufferedMutatorParam
77
81
.getMaxKeyValueSize () : connectionConfig .getMaxKeyValueSize ();
78
82
79
83
// create an OHTable object to do batch work
80
- this .ohTable = new OHTable (tableName , ohConnection , connectionConfig , pool );
84
+ if (ohTable != null ) {
85
+ this .ohTable = ohTable ;
86
+ } else {
87
+ this .ohTable = new OHTable (tableName , ohConnection , connectionConfig , pool );
88
+ }
89
+ }
90
+
91
+ /**
92
+ * only used for OHTable get bufferedMutator
93
+ * */
94
+ public OHBufferedMutatorImpl (Configuration conf , BufferedMutatorParams params , OHTable ohTable )
95
+ throws IOException {
96
+ // create an OHTable object to do batch work
97
+ if (ohTable == null ) {
98
+ throw new ObTableUnexpectedException ("The ohTable is null." );
99
+ }
100
+ this .ohTable = ohTable ;
101
+ // init params in OHBufferedMutatorImpl
102
+ this .tableName = params .getTableName ();
103
+ this .conf = conf ;
104
+ this .listener = params .getListener ();
105
+
106
+ OHConnectionConfiguration connectionConfig = new OHConnectionConfiguration (conf );
107
+ this .pool = params .getPool ();
108
+ this .rpcTimeout = connectionConfig .getRpcTimeout ();
109
+ this .operationTimeout = connectionConfig .getOperationTimeout ();
110
+
111
+ this .writeBufferSize = params .getWriteBufferSize () != OHConnectionImpl .BUFFERED_PARAM_UNSET ? params
112
+ .getWriteBufferSize () : connectionConfig .getWriteBufferSize ();
113
+ this .maxKeyValueSize = params .getMaxKeyValueSize () != OHConnectionImpl .BUFFERED_PARAM_UNSET ? params
114
+ .getMaxKeyValueSize () : connectionConfig .getMaxKeyValueSize ();
115
+
81
116
}
82
117
83
118
@ Override
@@ -119,14 +154,12 @@ public void mutate(List<? extends Mutation> mutations) throws IOException {
119
154
validateOperation (m );
120
155
toAddSize += m .heapSize ();
121
156
}
122
-
123
157
currentAsyncBufferSize .addAndGet (toAddSize );
124
158
asyncWriteBuffer .addAll (mutations );
125
159
126
160
if (currentAsyncBufferSize .get () > writeBufferSize ) {
127
- execute (false );
161
+ batchExecute (false );
128
162
}
129
-
130
163
}
131
164
132
165
/**
@@ -142,10 +175,18 @@ private void validateOperation(Mutation mt) throws IllegalArgumentException {
142
175
}
143
176
if (mt instanceof Put ) {
144
177
// family empty check is in validatePut
145
- HTable .validatePut ((Put ) mt , maxKeyValueSize );
146
- OHTable .checkFamilyViolation (mt .getFamilyMap ().keySet (), true );
178
+ OHTable .validatePut ((Put ) mt , maxKeyValueSize );
179
+ if (isMultiFamilySupport ()) {
180
+ OHTable .checkFamilyViolation (mt .getFamilyMap ().keySet (), true );
181
+ } else {
182
+ OHTable .checkFamilyViolationForOneFamily (mt .getFamilyMap ().keySet ());
183
+ }
147
184
} else {
148
- OHTable .checkFamilyViolation (mt .getFamilyMap ().keySet (), false );
185
+ if (isMultiFamilySupport ()) {
186
+ OHTable .checkFamilyViolation (mt .getFamilyMap ().keySet (), false );
187
+ } else {
188
+ OHTable .checkFamilyViolationForOneFamily (mt .getFamilyMap ().keySet ());
189
+ }
149
190
}
150
191
}
151
192
@@ -156,7 +197,7 @@ private void validateOperation(Mutation mt) throws IllegalArgumentException {
156
197
* @param flushAll - if true, sends all the writes and wait for all of them to finish before
157
198
* returning.
158
199
*/
159
- private void execute (boolean flushAll ) throws IOException {
200
+ private void batchExecute (boolean flushAll ) throws IOException {
160
201
LinkedList <Mutation > execBuffer = new LinkedList <>();
161
202
long dequeuedSize = 0L ;
162
203
try {
@@ -172,19 +213,16 @@ private void execute(boolean flushAll) throws IOException {
172
213
if (execBuffer .isEmpty ()) {
173
214
return ;
174
215
}
175
- ohTable .batch (execBuffer );
216
+ Object [] results = new Object [execBuffer .size ()];
217
+ ohTable .batch (execBuffer , results );
176
218
// if commit all successfully, clean execBuffer
177
219
execBuffer .clear ();
178
220
} catch (Exception ex ) {
179
- LOGGER .error (LCD .convert ("01-00026" ), ex );
221
+ // do not recollect error operations, notify outside
222
+ LOGGER .error ("error happens: table name = " , tableName .getNameAsString (), ex );
180
223
if (ex .getCause () instanceof RetriesExhaustedWithDetailsException ) {
181
- LOGGER .error (tableName + ": One or more of the operations have failed after retries." );
224
+ LOGGER .error (tableName . getNameAsString () + ": One or more of the operations have failed after retries." , ex );
182
225
RetriesExhaustedWithDetailsException retryException = (RetriesExhaustedWithDetailsException ) ex .getCause ();
183
- // recollect mutations
184
- execBuffer .clear ();
185
- for (int i = 0 ; i < retryException .getNumExceptions (); ++i ) {
186
- execBuffer .add ((Mutation ) retryException .getRow (i ));
187
- }
188
226
if (listener != null ) {
189
227
listener .onException (retryException , this );
190
228
} else {
@@ -194,12 +232,6 @@ private void execute(boolean flushAll) throws IOException {
194
232
LOGGER .error ("Errors unrelated to operations occur during mutation operation" , ex );
195
233
throw ex ;
196
234
}
197
- } finally {
198
- for (Mutation mutation : execBuffer ) {
199
- long size = mutation .heapSize ();
200
- currentAsyncBufferSize .addAndGet (size );
201
- asyncWriteBuffer .add (mutation );
202
- }
203
235
}
204
236
}
205
237
@@ -209,7 +241,7 @@ public void close() throws IOException {
209
241
return ;
210
242
}
211
243
try {
212
- execute (true );
244
+ batchExecute (true );
213
245
} finally {
214
246
// the pool in ObTableClient will be shut down too
215
247
this .pool .shutdown ();
@@ -234,13 +266,21 @@ public void setWriteBufferSize(long writeBufferSize) throws IOException {
234
266
}
235
267
}
236
268
269
+ /**
270
+ * Only 4_2_5 BP1 - 4_3_0 and after 4_3_4 support multi-cf
271
+ * */
272
+ boolean isMultiFamilySupport () {
273
+ return (OB_VERSION >= OB_VERSION_4_2_5_1 && OB_VERSION < OB_VERSION_4_3_0_0 )
274
+ || (OB_VERSION >= OB_VERSION_4_3_4_0 );
275
+ }
276
+
237
277
/**
238
278
* Force to commit all operations
239
279
* do not care whether the pool is shut down or this BufferedMutator is closed
240
280
*/
241
281
@ Override
242
282
public void flush () throws IOException {
243
- execute (true );
283
+ batchExecute (true );
244
284
}
245
285
246
286
@ Override
@@ -258,6 +298,10 @@ public void setOperationTimeout(int operationTimeout) {
258
298
this .ohTable .setOperationTimeout (operationTimeout );
259
299
}
260
300
301
+ public long getCurrentBufferSize () {
302
+ return currentAsyncBufferSize .get ();
303
+ }
304
+
261
305
@ Deprecated
262
306
public List <Row > getWriteBuffer () {
263
307
return Arrays .asList (asyncWriteBuffer .toArray (new Row [0 ]));
0 commit comments