View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.chaos.actions;
20  
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import org.apache.commons.lang.math.RandomUtils;
26  import org.apache.hadoop.hbase.HRegionInfo;
27  import org.apache.hadoop.hbase.ServerName;
28  import org.apache.hadoop.hbase.TableName;
29  import org.apache.hadoop.hbase.chaos.factories.MonkeyConstants;
30  import org.apache.hadoop.hbase.client.Admin;
31  import org.apache.hadoop.hbase.util.Bytes;
32  
33  /**
34  * Action that tries to move every region of a table.
35  */
36  public class MoveRegionsOfTableAction extends Action {
37    private final long sleepTime;
38    private final TableName tableName;
39    private final long maxTime;
40  
41    public MoveRegionsOfTableAction(TableName tableName) {
42      this(-1, MonkeyConstants.DEFAULT_MOVE_REGIONS_MAX_TIME, tableName);
43    }
44  
45    public MoveRegionsOfTableAction(long sleepTime, long maxSleepTime, TableName tableName) {
46      this.sleepTime = sleepTime;
47      this.tableName = tableName;
48      this.maxTime = maxSleepTime;
49    }
50  
51    @Override
52    public void perform() throws Exception {
53      if (sleepTime > 0) {
54        Thread.sleep(sleepTime);
55      }
56  
57      Admin admin = this.context.getHBaseIntegrationTestingUtility().getHBaseAdmin();
58      Collection<ServerName> serversList = admin.getClusterStatus().getServers();
59      ServerName[] servers = serversList.toArray(new ServerName[serversList.size()]);
60  
61      LOG.info("Performing action: Move regions of table " + tableName);
62      List<HRegionInfo> regions = admin.getTableRegions(tableName);
63      if (regions == null || regions.isEmpty()) {
64        LOG.info("Table " + tableName + " doesn't have regions to move");
65        return;
66      }
67  
68      Collections.shuffle(regions);
69  
70      long start = System.currentTimeMillis();
71      for (HRegionInfo regionInfo:regions) {
72  
73        // Don't try the move if we're stopping
74        if (context.isStopping()) {
75          return;
76        }
77  
78        try {
79          String destServerName =
80            servers[RandomUtils.nextInt(servers.length)].getServerName();
81          LOG.debug("Moving " + regionInfo.getRegionNameAsString() + " to " + destServerName);
82          admin.move(regionInfo.getEncodedNameAsBytes(), Bytes.toBytes(destServerName));
83        } catch (Exception ex) {
84          LOG.warn("Move failed, might be caused by other chaos: " + ex.getMessage());
85        }
86        if (sleepTime > 0) {
87          Thread.sleep(sleepTime);
88        }
89  
90        // put a limit on max num regions. Otherwise, this won't finish
91        // with a sleep time of 10sec, 100 regions will finish in 16min
92        if (System.currentTimeMillis() - start > maxTime) {
93          break;
94        }
95      }
96    }
97  }