Skip to content

Commit

Permalink
HBASE-24982 Disassemble the method replicateWALEntry from AdminServic…
Browse files Browse the repository at this point in the history
…e to a new interface ReplicationServerService (#2360)

Signed-off-by: Wellington Chevreuil <[email protected]>
  • Loading branch information
ddupg authored and infraio committed Sep 14, 2020
1 parent 2e95e75 commit c302a9e
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 230 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ClientService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MasterService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationServerProtos.ReplicationServerService;

/**
* The implementation of AsyncConnection.
Expand Down Expand Up @@ -107,6 +108,8 @@ class AsyncConnectionImpl implements AsyncConnection {

private final ConcurrentMap<String, ClientService.Interface> rsStubs = new ConcurrentHashMap<>();
private final ConcurrentMap<String, AdminService.Interface> adminSubs = new ConcurrentHashMap<>();
private final ConcurrentMap<String, ReplicationServerService.Interface> replStubs =
new ConcurrentHashMap<>();

private final AtomicReference<MasterService.Interface> masterStub = new AtomicReference<>();

Expand Down Expand Up @@ -266,12 +269,25 @@ private AdminService.Interface createAdminServerStub(ServerName serverName) thro
return AdminService.newStub(rpcClient.createRpcChannel(serverName, user, rpcTimeout));
}

private ReplicationServerService.Interface createReplicationServerStub(ServerName serverName)
throws IOException {
return ReplicationServerService.newStub(
rpcClient.createRpcChannel(serverName, user, rpcTimeout));
}

AdminService.Interface getAdminStub(ServerName serverName) throws IOException {
return ConcurrentMapUtils.computeIfAbsentEx(adminSubs,
getStubKey(AdminService.Interface.class.getSimpleName(), serverName, hostnameCanChange),
() -> createAdminServerStub(serverName));
}

ReplicationServerService.Interface getReplicationServerStub(ServerName serverName)
throws IOException {
return ConcurrentMapUtils.computeIfAbsentEx(replStubs,
getStubKey(ReplicationServerService.Interface.class.getSimpleName(), serverName,
hostnameCanChange), () -> createReplicationServerStub(serverName));
}

CompletableFuture<MasterService.Interface> getMasterStub() {
return ConnectionUtils.getOrFetch(masterStub, masterStubMakeFuture, false, () -> {
CompletableFuture<MasterService.Interface> future = new CompletableFuture<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto2";
package hbase.pb;

option java_package = "org.apache.hadoop.hbase.shaded.protobuf.generated";
option java_outer_classname = "ReplicationServerProtos";
option java_generic_services = true;
option java_generate_equals_and_hash = true;
option optimize_for = SPEED;

import "server/region/Admin.proto";

service ReplicationServerService {
rpc ReplicateWALEntry(ReplicateWALEntryRequest)
returns(ReplicateWALEntryResponse);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.AsyncAdmin;
import org.apache.hadoop.hbase.client.AsyncConnection;
import org.apache.hadoop.hbase.util.FutureUtils;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -212,4 +215,20 @@ public static int getAdaptiveTimeout(final int initialValue, final int retries)
}
return initialValue * HConstants.RETRY_BACKOFF[ntries];
}

/**
* Check whether peer cluster supports replication offload.
* @param peerConn connection for peer cluster
* @return true if peer cluster version >= 3
* @throws IOException exception
*/
public static boolean isPeerClusterSupportReplicationOffload(AsyncConnection peerConn)
throws IOException {
AsyncAdmin admin = peerConn.getAdmin();
String version = FutureUtils.get(admin.getClusterMetrics()).getHBaseVersion();
if (Integer.parseInt(version.split("\\.")[0]) >= 3) {
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public interface AsyncClusterConnection extends AsyncConnection {
*/
AsyncRegionServerAdmin getRegionServerAdmin(ServerName serverName);

/**
* Get the admin service for the give replication server.
*/
AsyncReplicationServerAdmin getReplicationServerAdmin(ServerName serverName);

/**
* Get the nonce generator for this connection.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public AsyncRegionServerAdmin getRegionServerAdmin(ServerName serverName) {
return new AsyncRegionServerAdmin(serverName, this);
}

@Override
public AsyncReplicationServerAdmin getReplicationServerAdmin(ServerName serverName) {
return new AsyncReplicationServerAdmin(serverName, this);
}

@Override
public CompletableFuture<FlushRegionResponse> flush(byte[] regionName,
boolean writeFlushWALMarker) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.client;

import java.io.IOException;
import java.util.concurrent.CompletableFuture;

import org.apache.hadoop.hbase.CellScanner;
import org.apache.hadoop.hbase.ServerName;
import org.apache.hadoop.hbase.ipc.HBaseRpcController;
import org.apache.yetus.audience.InterfaceAudience;

import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;

import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationServerProtos.ReplicationServerService;

/**
* A simple wrapper of the {@link ReplicationServerService} for a replication server.
* <p/>
* Notice that there is no retry, and this is intentional.
*/
@InterfaceAudience.Private
public class AsyncReplicationServerAdmin {

private final ServerName server;

private final AsyncConnectionImpl conn;

AsyncReplicationServerAdmin(ServerName server, AsyncConnectionImpl conn) {
this.server = server;
this.conn = conn;
}

@FunctionalInterface
private interface RpcCall<RESP> {
void call(ReplicationServerService.Interface stub, HBaseRpcController controller,
RpcCallback<RESP> done);
}

private <RESP> CompletableFuture<RESP> call(RpcCall<RESP> rpcCall, CellScanner cellScanner) {
CompletableFuture<RESP> future = new CompletableFuture<>();
HBaseRpcController controller = conn.rpcControllerFactory.newController(cellScanner);
try {
rpcCall.call(conn.getReplicationServerStub(server), controller, resp -> {
if (controller.failed()) {
future.completeExceptionally(controller.getFailed());
} else {
future.complete(resp);
}
});
} catch (IOException e) {
future.completeExceptionally(e);
}
return future;
}

public CompletableFuture<AdminProtos.ReplicateWALEntryResponse> replicateWALEntry(
AdminProtos.ReplicateWALEntryRequest request, CellScanner cellScanner, int timeout) {
return call((stub, controller, done) -> {
controller.setCallTimeout(timeout);
stub.replicateWALEntry(controller, request, done);
}, cellScanner);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.hadoop.hbase.CellScanner;
import org.apache.hadoop.hbase.PrivateCellUtil;
import org.apache.hadoop.hbase.client.AsyncRegionServerAdmin;
import org.apache.hadoop.hbase.client.AsyncReplicationServerAdmin;
import org.apache.hadoop.hbase.io.SizedCellScanner;
import org.apache.hadoop.hbase.regionserver.wal.WALCellCodec;
import org.apache.hadoop.hbase.util.FutureUtils;
Expand Down Expand Up @@ -61,6 +62,23 @@ public static void replicateWALEntry(AsyncRegionServerAdmin admin, Entry[] entri
FutureUtils.get(admin.replicateWALEntry(p.getFirst(), p.getSecond(), timeout));
}

/**
* A helper to replicate a list of WAL entries using replication server admin
* @param admin the replication server admin
* @param entries Array of WAL entries to be replicated
* @param replicationClusterId Id which will uniquely identify source cluster FS client
* configurations in the replication configuration directory
* @param sourceBaseNamespaceDir Path to source cluster base namespace directory
* @param sourceHFileArchiveDir Path to the source cluster hfile archive directory
*/
public static void replicateWALEntry(AsyncReplicationServerAdmin admin, Entry[] entries,
String replicationClusterId, Path sourceBaseNamespaceDir, Path sourceHFileArchiveDir,
int timeout) throws IOException {
Pair<ReplicateWALEntryRequest, CellScanner> p = buildReplicateWALEntryRequest(entries, null,
replicationClusterId, sourceBaseNamespaceDir, sourceHFileArchiveDir);
FutureUtils.get(admin.replicateWALEntry(p.getFirst(), p.getSecond(), timeout));
}

/**
* Create a new ReplicateWALEntryRequest from a list of WAL entries
* @param entries the WAL entries to be replicated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetSpaceQuotaSnapshotsResponse;
import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.GetSpaceQuotaSnapshotsResponse.TableQuotaSnapshot;
import org.apache.hadoop.hbase.shaded.protobuf.generated.RPCProtos.RequestHeader;
import org.apache.hadoop.hbase.shaded.protobuf.generated.ReplicationServerProtos.ReplicationServerService;
import org.apache.hadoop.hbase.shaded.protobuf.generated.TooSlowLog.SlowLogPayload;
import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.BulkLoadDescriptor;
import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.CompactionDescriptor;
Expand All @@ -267,7 +268,7 @@
@SuppressWarnings("deprecation")
public class RSRpcServices implements HBaseRPCErrorHandler,
AdminService.BlockingInterface, ClientService.BlockingInterface, PriorityFunction,
ConfigurationObserver {
ConfigurationObserver, ReplicationServerService.BlockingInterface {
protected static final Logger LOG = LoggerFactory.getLogger(RSRpcServices.class);

/** RPC scheduler to use for the region server. */
Expand Down Expand Up @@ -1487,8 +1488,11 @@ protected List<BlockingServiceAndInterface> getServices() {
}
if (admin) {
bssi.add(new BlockingServiceAndInterface(
AdminService.newReflectiveBlockingService(this),
AdminService.BlockingInterface.class));
AdminService.newReflectiveBlockingService(this),
AdminService.BlockingInterface.class));
bssi.add(new BlockingServiceAndInterface(
ReplicationServerService.newReflectiveBlockingService(this),
ReplicationServerService.BlockingInterface.class));
}
return new org.apache.hbase.thirdparty.com.google.common.collect.
ImmutableList.Builder<BlockingServiceAndInterface>().addAll(bssi).build();
Expand Down
Loading

0 comments on commit c302a9e

Please sign in to comment.