View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.client.example;
21  
22  import java.io.Closeable;
23  import java.io.IOException;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.conf.Configuration;
27  import org.apache.hadoop.conf.Configured;
28  import org.apache.hadoop.hbase.HBaseConfiguration;
29  import org.apache.hadoop.hbase.HConstants;
30  import org.apache.hadoop.hbase.TableName;
31  import org.apache.hadoop.hbase.client.Connection;
32  import org.apache.hadoop.hbase.client.ConnectionFactory;
33  import org.apache.hadoop.hbase.client.Table;
34  import org.apache.hadoop.hbase.client.coprocessor.Batch;
35  import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
36  import org.apache.hadoop.hbase.ipc.ServerRpcController;
37  import org.apache.hadoop.hbase.protobuf.generated.RefreshHFilesProtos;
38  import org.apache.hadoop.util.Tool;
39  import org.apache.hadoop.util.ToolRunner;
40  
41  /**
42   * This client class is for invoking the refresh HFile function deployed on the
43   * Region Server side via the RefreshHFilesService.
44   */
45  public class RefreshHFilesClient extends Configured implements Tool, Closeable {
46    private static final Log LOG = LogFactory.getLog(RefreshHFilesClient.class);
47    private final Connection connection;
48  
49    /**
50     * Constructor with Conf object
51     *
52     * @param cfg
53     */
54    public RefreshHFilesClient(Configuration cfg) {
55      try {
56        this.connection = ConnectionFactory.createConnection(cfg);
57      } catch (IOException e) {
58        throw new RuntimeException(e);
59      }
60    }
61  
62    @Override
63    public void close() throws IOException {
64      if (this.connection != null && !this.connection.isClosed()) {
65        this.connection.close();
66      }
67    }
68  
69    public void refreshHFiles(final TableName tableName) throws Throwable {
70      try (Table table = connection.getTable(tableName)) {
71        refreshHFiles(table);
72      }
73    }
74  
75    public void refreshHFiles(final Table table) throws Throwable {
76      final RefreshHFilesProtos.RefreshHFilesRequest request = RefreshHFilesProtos.RefreshHFilesRequest
77                                                                 .getDefaultInstance();
78      table.coprocessorService(RefreshHFilesProtos.RefreshHFilesService.class, HConstants.EMPTY_START_ROW,
79                               HConstants.EMPTY_END_ROW,
80                               new Batch.Call<RefreshHFilesProtos.RefreshHFilesService,
81                                               RefreshHFilesProtos.RefreshHFilesResponse>() {
82                                 @Override
83                                 public RefreshHFilesProtos.RefreshHFilesResponse call(
84                                   RefreshHFilesProtos.RefreshHFilesService refreshHFilesService)
85                                   throws IOException {
86                                   ServerRpcController controller = new ServerRpcController();
87                                   BlockingRpcCallback<RefreshHFilesProtos.RefreshHFilesResponse> rpcCallback =
88                                     new BlockingRpcCallback<>();
89                                   refreshHFilesService.refreshHFiles(controller, request, rpcCallback);
90                                   if (controller.failedOnException()) {
91                                     throw controller.getFailedOn();
92                                   }
93                                   return rpcCallback.get();
94                                 }
95                               });
96      LOG.debug("Done refreshing HFiles");
97    }
98  
99    @Override
100   public int run(String[] args) throws Exception {
101     if (args.length != 1) {
102       String message = "When there are multiple HBase clusters sharing a common root directory, "
103           + "especially for read replica cluster (see detail in HBASE-18477), please consider to "
104           + "use this tool manually sync the flushed HFiles from the source cluster.";
105       message += "\nUsage: " + this.getClass().getName() + " tableName";
106       System.out.println(message);
107       return -1;
108     }
109     final TableName tableName = TableName.valueOf(args[0]);
110     try {
111       refreshHFiles(tableName);
112     } catch (Throwable t) {
113       LOG.error("Refresh HFiles from table " + tableName.getNameAsString() + "  failed: ", t);
114       return -1;
115     }
116     return 0;
117   }
118 
119   public static void main(String[] args) throws Exception {
120     ToolRunner.run(new RefreshHFilesClient(HBaseConfiguration.create()), args);
121   }
122 }