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.rsgroup; 019 020import java.io.IOException; 021import java.util.ArrayList; 022import java.util.List; 023import java.util.Set; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.hadoop.hbase.TableNotFoundException; 026import org.apache.hadoop.hbase.client.Admin; 027import org.apache.hadoop.hbase.client.BalanceRequest; 028import org.apache.hadoop.hbase.client.BalanceResponse; 029import org.apache.hadoop.hbase.client.Connection; 030import org.apache.hadoop.hbase.net.Address; 031import org.apache.yetus.audience.InterfaceAudience; 032 033import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 034import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException; 035 036import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil; 037import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos; 038import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.AddRSGroupRequest; 039import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.BalanceRSGroupRequest; 040import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerRequest; 041import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfServerResponse; 042import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableRequest; 043import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoOfTableResponse; 044import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoRequest; 045import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.GetRSGroupInfoResponse; 046import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.ListRSGroupInfosRequest; 047import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.MoveServersAndTablesRequest; 048import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.MoveServersRequest; 049import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.MoveTablesRequest; 050import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.RSGroupAdminService; 051import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.RemoveRSGroupRequest; 052import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupAdminProtos.RemoveServersRequest; 053import org.apache.hadoop.hbase.shaded.protobuf.generated.RSGroupProtos; 054 055/** 056 * Client used for managing region server group information. 057 * @deprecated Keep it here only for tests, using {@link Admin} instead. 058 */ 059@Deprecated 060@InterfaceAudience.Private 061public class RSGroupAdminClient { 062 private RSGroupAdminService.BlockingInterface stub; 063 private Admin admin; 064 065 public RSGroupAdminClient(Connection conn) throws IOException { 066 admin = conn.getAdmin(); 067 stub = RSGroupAdminService.newBlockingStub(admin.coprocessorService()); 068 } 069 070 /** 071 * Gets {@code RSGroupInfo} for given group name. 072 */ 073 public RSGroupInfo getRSGroupInfo(String groupName) throws IOException { 074 try { 075 GetRSGroupInfoResponse resp = stub.getRSGroupInfo(null, 076 GetRSGroupInfoRequest.newBuilder().setRSGroupName(groupName).build()); 077 if (resp.hasRSGroupInfo()) { 078 return ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 079 } 080 return null; 081 } catch (ServiceException e) { 082 throw ProtobufUtil.handleRemoteException(e); 083 } 084 } 085 086 /** 087 * Gets {@code RSGroupInfo} for the given table's group. 088 */ 089 public RSGroupInfo getRSGroupInfoOfTable(TableName tableName) throws IOException { 090 GetRSGroupInfoOfTableRequest request = GetRSGroupInfoOfTableRequest.newBuilder() 091 .setTableName(ProtobufUtil.toProtoTableName(tableName)).build(); 092 try { 093 GetRSGroupInfoOfTableResponse resp = stub.getRSGroupInfoOfTable(null, request); 094 if (resp.hasRSGroupInfo()) { 095 return ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 096 } 097 return null; 098 } catch (ServiceException e) { 099 throw ProtobufUtil.handleRemoteException(e); 100 } 101 } 102 103 /** 104 * Move given set of servers to the specified target RegionServer group. 105 */ 106 public void moveServers(Set<Address> servers, String targetGroup) throws IOException { 107 Set<HBaseProtos.ServerName> hostPorts = Sets.newHashSet(); 108 for (Address el : servers) { 109 hostPorts.add(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 110 .setPort(el.getPort()).build()); 111 } 112 MoveServersRequest request = 113 MoveServersRequest.newBuilder().setTargetGroup(targetGroup).addAllServers(hostPorts).build(); 114 try { 115 stub.moveServers(null, request); 116 } catch (ServiceException e) { 117 throw ProtobufUtil.handleRemoteException(e); 118 } 119 } 120 121 /** 122 * Move given set of tables to the specified target RegionServer group. This will unassign all of 123 * a table's region so it can be reassigned to the correct group. 124 */ 125 public void moveTables(Set<TableName> tables, String targetGroup) throws IOException { 126 MoveTablesRequest.Builder builder = MoveTablesRequest.newBuilder().setTargetGroup(targetGroup); 127 for (TableName tableName : tables) { 128 builder.addTableName(ProtobufUtil.toProtoTableName(tableName)); 129 if (!admin.tableExists(tableName)) { 130 throw new TableNotFoundException(tableName); 131 } 132 } 133 try { 134 stub.moveTables(null, builder.build()); 135 } catch (ServiceException e) { 136 throw ProtobufUtil.handleRemoteException(e); 137 } 138 } 139 140 /** 141 * Creates a new RegionServer group with the given name. 142 */ 143 public void addRSGroup(String groupName) throws IOException { 144 AddRSGroupRequest request = AddRSGroupRequest.newBuilder().setRSGroupName(groupName).build(); 145 try { 146 stub.addRSGroup(null, request); 147 } catch (ServiceException e) { 148 throw ProtobufUtil.handleRemoteException(e); 149 } 150 } 151 152 /** 153 * Removes RegionServer group associated with the given name. 154 */ 155 public void removeRSGroup(String name) throws IOException { 156 RemoveRSGroupRequest request = RemoveRSGroupRequest.newBuilder().setRSGroupName(name).build(); 157 try { 158 stub.removeRSGroup(null, request); 159 } catch (ServiceException e) { 160 throw ProtobufUtil.handleRemoteException(e); 161 } 162 } 163 164 /** 165 * Balance regions in the given RegionServer group. 166 * @return BalanceResponse details about the balancer run 167 */ 168 public BalanceResponse balanceRSGroup(String groupName, BalanceRequest request) 169 throws IOException { 170 try { 171 BalanceRSGroupRequest req = ProtobufUtil.createBalanceRSGroupRequest(groupName, request); 172 return ProtobufUtil.toBalanceResponse(stub.balanceRSGroup(null, req)); 173 } catch (ServiceException e) { 174 throw ProtobufUtil.handleRemoteException(e); 175 } 176 } 177 178 /** 179 * Lists current set of RegionServer groups. 180 */ 181 public List<RSGroupInfo> listRSGroups() throws IOException { 182 try { 183 List<RSGroupProtos.RSGroupInfo> resp = stub 184 .listRSGroupInfos(null, ListRSGroupInfosRequest.getDefaultInstance()).getRSGroupInfoList(); 185 List<RSGroupInfo> result = new ArrayList<>(resp.size()); 186 for (RSGroupProtos.RSGroupInfo entry : resp) { 187 result.add(ProtobufUtil.toGroupInfo(entry)); 188 } 189 return result; 190 } catch (ServiceException e) { 191 throw ProtobufUtil.handleRemoteException(e); 192 } 193 } 194 195 /** 196 * Retrieve the RSGroupInfo a server is affiliated to 197 * @param hostPort HostPort to get RSGroupInfo for 198 */ 199 public RSGroupInfo getRSGroupOfServer(Address hostPort) throws IOException { 200 GetRSGroupInfoOfServerRequest request = 201 GetRSGroupInfoOfServerRequest.newBuilder().setServer(HBaseProtos.ServerName.newBuilder() 202 .setHostName(hostPort.getHostname()).setPort(hostPort.getPort()).build()).build(); 203 try { 204 GetRSGroupInfoOfServerResponse resp = stub.getRSGroupInfoOfServer(null, request); 205 if (resp.hasRSGroupInfo()) { 206 return ProtobufUtil.toGroupInfo(resp.getRSGroupInfo()); 207 } 208 return null; 209 } catch (ServiceException e) { 210 throw ProtobufUtil.handleRemoteException(e); 211 } 212 } 213 214 /** 215 * Move given set of servers and tables to the specified target RegionServer group. 216 * @param servers set of servers to move 217 * @param tables set of tables to move 218 * @param targetGroup the target group name 219 * @throws IOException if moving the server and tables fail 220 */ 221 public void moveServersAndTables(Set<Address> servers, Set<TableName> tables, String targetGroup) 222 throws IOException { 223 MoveServersAndTablesRequest.Builder builder = 224 MoveServersAndTablesRequest.newBuilder().setTargetGroup(targetGroup); 225 for (Address el : servers) { 226 builder.addServers(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 227 .setPort(el.getPort()).build()); 228 } 229 for (TableName tableName : tables) { 230 builder.addTableName(ProtobufUtil.toProtoTableName(tableName)); 231 if (!admin.tableExists(tableName)) { 232 throw new TableNotFoundException(tableName); 233 } 234 } 235 try { 236 stub.moveServersAndTables(null, builder.build()); 237 } catch (ServiceException e) { 238 throw ProtobufUtil.handleRemoteException(e); 239 } 240 } 241 242 /** 243 * Remove decommissioned servers from rsgroup. 1. Sometimes we may find the server aborted due to 244 * some hardware failure and we must offline the server for repairing. Or we need to move some 245 * servers to join other clusters. So we need to remove these servers from the rsgroup. 2. 246 * Dead/recovering/live servers will be disallowed. 247 * @param servers set of servers to remove 248 */ 249 public void removeServers(Set<Address> servers) throws IOException { 250 Set<HBaseProtos.ServerName> hostPorts = Sets.newHashSet(); 251 for (Address el : servers) { 252 hostPorts.add(HBaseProtos.ServerName.newBuilder().setHostName(el.getHostname()) 253 .setPort(el.getPort()).build()); 254 } 255 RemoveServersRequest request = 256 RemoveServersRequest.newBuilder().addAllServers(hostPorts).build(); 257 try { 258 stub.removeServers(null, request); 259 } catch (ServiceException e) { 260 throw ProtobufUtil.handleRemoteException(e); 261 } 262 } 263}