Skip to content

Commit 9a693e8

Browse files
authored
fix: disabling incompatible mutation metrics for HBase 1.3 or lower (#3599)
Due to lack of custom counter support in HBase. #3596 Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/java-bigtable-hbase/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [ ] Ensure the tests and linter pass - [ ] Code coverage does not decrease (if any source code was changed) - [ ] Appropriate docs were updated (if necessary) Fixes #<issue_number_goes_here> ☕️ If you write sample code, please follow the [samples format]( https://github.com/GoogleCloudPlatform/java-docs-samples/blob/main/SAMPLE_FORMAT.md).
1 parent 0dfb130 commit 9a693e8

File tree

6 files changed

+114
-11
lines changed

6 files changed

+114
-11
lines changed

hbase-migration-tools/bigtable-hbase-replication/README.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ data. Near zero downtime migrations include the following steps:
6161
and service account json file.
6262
4. Add a CBT replication peer in HBase. On HBase shell
6363
execute `add_peer '2', ENDPOINT_CLASSNAME => 'com.google.cloud.bigtable.hbase2_x.replication.HbaseToCloudBigtableReplicationEndpoint'`
64-
. Please use endpoint class `com.google.cloud.bigtable.hbase1_x.replication.HbaseToCloudBigtableReplicationEndpoint` for HBase 1.x clusters. Use add_peer options to enable replication for select tables.
64+
. Please use endpoint
65+
class `com.google.cloud.bigtable.hbase1_x.replication.HbaseToCloudBigtableReplicationEndpoint`
66+
for HBase 1.x clusters. Use add_peer options to enable replication for select
67+
tables.
6568
5. Immediately disable the CBT replication peer, this allows WAL logs to
6669
accumulate on HDFS. On HBase shell execute: `disable_peer '2'`
6770
6. Check the replicated tables by executing `list_replicated_tables` and enable
@@ -111,9 +114,11 @@ classpath.
111114
</property>
112115
```
113116

114-
We recommend specifying a single-cluster routing [application profile](https://cloud.google.com/bigtable/docs/app-profiles#routing) by setting config key
117+
We recommend specifying a single-cluster
118+
routing [application profile](https://cloud.google.com/bigtable/docs/app-profiles#routing)
119+
by setting config key
115120
`google.bigtable.app_profile.id`. A single-cluster routing application profile
116-
preserves order of mutations between HBase and Cloud Bigtable.
121+
preserves order of mutations between HBase and Cloud Bigtable.
117122

118123
Next, you should configure Cloud Bigtable authentication. Create a service
119124
account and download a json file as shown
@@ -236,7 +241,9 @@ in `hbase-site.xml` but we recommend setting it during peer creation.
236241
Enabling/disabling dry run mode during peer creation can avoid restarting the
237242
HBase cluster to pickup changes to `hbase-site.xml` file. Enable dry run mode by
238243
running the following command to add Cloud Bigtable replication peer (please
239-
change the endpoint class to `com.google.cloud.bigtable.hbase1_x.replication.HbaseToCloudBigtableReplicationEndpoint` for HBase 1.x):
244+
change the endpoint class
245+
to `com.google.cloud.bigtable.hbase1_x.replication.HbaseToCloudBigtableReplicationEndpoint`
246+
for HBase 1.x):
240247

241248
```
242249
add_peer 'peer_id',
@@ -283,7 +290,8 @@ are 3 kinds of metrics that the replication library will publish:
283290
2. Cloud Bigtable client side metrics. These will include latencies and failures
284291
of various CBT APIs.
285292
3. Custom metrics from the replication library. For example,
286-
NumberOfIncompatibleMutations.
293+
NumberOfIncompatibleMutations. Please note that cusotm metrics support is
294+
available for HBase 1.4 or newer.
287295

288296
Please refer to javadocs for class HBaseToCloudBigtableReplicationMetrics for
289297
list of available metrics.

hbase-migration-tools/bigtable-hbase-replication/bigtable-hbase-1.x-replication/src/main/java/com/google/cloud/bigtable/hbase1_x/replication/HbaseToCloudBigtableReplicationEndpoint.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ public class HbaseToCloudBigtableReplicationEndpoint extends BaseReplicationEndp
3737

3838
public HbaseToCloudBigtableReplicationEndpoint() {
3939
cloudBigtableReplicator = new CloudBigtableReplicator();
40-
metricsExporter = new HBaseMetricsExporter();
40+
metricsExporter = HBaseMetricsExporter.create();
4141
}
4242

4343
@Override
4444
protected synchronized void doStart() {
45-
metricsExporter.setMetricsSource(ctx.getMetrics());
45+
metricsExporter.init(ctx);
4646
cloudBigtableReplicator.start(ctx.getConfiguration(), metricsExporter);
4747
notifyStarted();
4848
}

hbase-migration-tools/bigtable-hbase-replication/bigtable-hbase-1.x-replication/src/main/java/com/google/cloud/bigtable/hbase1_x/replication/metrics/HBaseMetricsExporter.java

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,57 @@
1717
package com.google.cloud.bigtable.hbase1_x.replication.metrics;
1818

1919
import com.google.bigtable.repackaged.com.google.api.core.InternalApi;
20+
import com.google.bigtable.repackaged.com.google.api.core.InternalExtensionOnly;
2021
import com.google.cloud.bigtable.hbase.replication.metrics.MetricsExporter;
22+
import java.lang.reflect.Method;
23+
import org.apache.hadoop.hbase.replication.ReplicationEndpoint.Context;
2124
import org.apache.hadoop.hbase.replication.regionserver.MetricsSource;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
2227

2328
/** HBaseMetricsExporter implements MetricExporter which bridges with MetricsSource. */
2429
@InternalApi
2530
public class HBaseMetricsExporter implements MetricsExporter {
31+
32+
private static final Logger LOG = LoggerFactory.getLogger(HBaseMetricsExporter.class);
33+
34+
// Force the use of static factory method to create instances.
35+
@InternalExtensionOnly
36+
protected HBaseMetricsExporter() {}
37+
2638
// same pattern as used by HbaseInterClusterRepl
2739
private MetricsSource metricsSource;
2840

29-
public void setMetricsSource(MetricsSource metricsSource) {
30-
this.metricsSource = metricsSource;
41+
public void init(Context ctx) {
42+
this.metricsSource = ctx.getMetrics();
3143
}
3244

3345
@Override
3446
public void incCounters(String counterName, long delta) {
3547
metricsSource.incCounters(counterName, delta);
3648
}
49+
50+
/**
51+
* Creates the right implementation for HBaseMetricsExporter. The incCounter method used to
52+
* integrate with HBase metrics was introduced in HBase 1.4, so when running on HBase version 1.3
53+
* or lower, we need to skip incrementing the counters. More details on:
54+
* https://github.com/googleapis/java-bigtable-hbase/issues/3596
55+
*/
56+
public static HBaseMetricsExporter create() {
57+
// TODO: Define configuration that allows users to inject a custom implementation of
58+
// HBaseMetricsExporter
59+
try {
60+
Method method = MetricsSource.class.getMethod("incCounters", String.class, long.class);
61+
// HBase version > 1.4, supports incCounters, return normal MetricsExporter.
62+
return new HBaseMetricsExporter();
63+
} catch (NoSuchMethodException e) {
64+
// HBase version <1.4 : HBase does not support generic counters. Revert to no-op metrics
65+
// exporter.
66+
LOG.warn(
67+
"Can not find MetricsSource.incCounters method, probably running HBase 1.3 or older."
68+
+ " Disabling metrics for IncompatibleMutations. Please refer to "
69+
+ "https://github.com/googleapis/java-bigtable-hbase/issues/3596 for details.");
70+
return new NoOpHBaseMetricsExporter();
71+
}
72+
}
3773
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.bigtable.hbase1_x.replication.metrics;
18+
19+
import com.google.bigtable.repackaged.com.google.api.core.InternalApi;
20+
21+
/**
22+
* No-op implemnentation of MetricsExporter interface. To be used where incCounters method from
23+
* HBase MetricsSource is not available.
24+
*/
25+
@InternalApi
26+
public class NoOpHBaseMetricsExporter extends HBaseMetricsExporter {
27+
28+
// Use the HBaseMetricsExporter.create method to create instances of this class.
29+
@InternalApi
30+
NoOpHBaseMetricsExporter() {}
31+
32+
@Override
33+
public void incCounters(String counterName, long delta) {}
34+
}

hbase-migration-tools/bigtable-hbase-replication/bigtable-hbase-1.x-replication/src/test/java/com/google/cloud/bigtable/hbase1_x/replication/metrics/HBaseMetricsExporterTest.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
1616

1717
package com.google.cloud.bigtable.hbase1_x.replication.metrics;
1818

19+
import static org.junit.Assert.assertEquals;
20+
import static org.mockito.Mockito.reset;
1921
import static org.mockito.Mockito.times;
2022
import static org.mockito.Mockito.verify;
23+
import static org.mockito.Mockito.when;
2124

25+
import org.apache.hadoop.hbase.replication.ReplicationEndpoint.Context;
2226
import org.apache.hadoop.hbase.replication.regionserver.MetricsSource;
27+
import org.junit.After;
2328
import org.junit.Before;
2429
import org.junit.Rule;
2530
import org.junit.Test;
@@ -33,6 +38,7 @@
3338
public class HBaseMetricsExporterTest {
3439
@Rule public final MockitoRule mockitoRule = MockitoJUnit.rule();
3540

41+
@Mock Context context;
3642
@Mock MetricsSource metricsSource;
3743

3844
HBaseMetricsExporter hbaseMetricsExporter;
@@ -42,8 +48,22 @@ public class HBaseMetricsExporterTest {
4248

4349
@Before
4450
public void setUp() {
45-
hbaseMetricsExporter = new HBaseMetricsExporter();
46-
hbaseMetricsExporter.setMetricsSource(metricsSource);
51+
when(context.getMetrics()).thenReturn(metricsSource);
52+
hbaseMetricsExporter = HBaseMetricsExporter.create();
53+
hbaseMetricsExporter.init(context);
54+
}
55+
56+
@After
57+
public void tearDown() {
58+
reset(context, metricsSource);
59+
}
60+
61+
@Test
62+
public void testCreate() {
63+
// Make sure that create returns an HBaseMetricsExporter object. There is no good way to test
64+
// the other case where incCounter method is not available as it requires adding hbase <1.4 to
65+
// the classpath along with hbase 1.4.
66+
assertEquals(HBaseMetricsExporter.class, hbaseMetricsExporter.getClass());
4767
}
4868

4969
@Test

hbase-migration-tools/bigtable-hbase-replication/bigtable-hbase-replication-core/src/main/java/com/google/cloud/bigtable/hbase/replication/metrics/HBaseToCloudBigtableReplicationMetrics.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616

1717
package com.google.cloud.bigtable.hbase.replication.metrics;
1818

19+
/**
20+
* Metrics exported by the Cloud Bigtable replication endpoint. Please note that custom replication
21+
* metrics are only supported by HBase 1.4 and newer. Please see
22+
* https://github.com/googleapis/java-bigtable-hbase/issues/3596 for more details.
23+
*/
1924
public class HBaseToCloudBigtableReplicationMetrics {
2025

2126
// Static class for listing all the metrics

0 commit comments

Comments
 (0)