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.util;
019
020import java.io.IOException;
021import org.apache.hadoop.hbase.HBaseTestingUtil;
022import org.apache.hadoop.hbase.HConstants;
023import org.apache.hadoop.hbase.TableName;
024import org.apache.hadoop.hbase.client.Connection;
025import org.apache.hadoop.hbase.client.ConnectionFactory;
026import org.apache.hadoop.hbase.client.Result;
027import org.apache.hadoop.hbase.client.ResultScanner;
028import org.apache.hadoop.hbase.client.Scan;
029import org.apache.hadoop.hbase.client.Table;
030import org.apache.hadoop.hbase.io.compress.Compression;
031import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
032import org.apache.hadoop.hbase.util.test.LoadTestDataGenerator;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035
036import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
037
038/**
039 * A command-line tool that spins up a local process-based cluster, loads some data, restarts the
040 * regionserver holding hbase:meta, and verifies that the cluster recovers.
041 */
042public class RestartMetaTest extends AbstractHBaseTool {
043
044  private static final Logger LOG = LoggerFactory.getLogger(RestartMetaTest.class);
045
046  /** The number of region servers used if not specified */
047  private static final int DEFAULT_NUM_RS = 2;
048
049  /** Table name for the test */
050  private static TableName TABLE_NAME = TableName.valueOf("load_test");
051
052  /** The number of seconds to sleep after loading the data */
053  private static final int SLEEP_SEC_AFTER_DATA_LOAD = 5;
054
055  /** The actual number of region servers */
056  private int numRegionServers;
057
058  private static final String OPT_NUM_RS = "num_rs";
059
060  private static final int NUM_DATANODES = 3;
061
062  /** Loads data into the table using the multi-threaded writer. */
063  private void loadData() throws IOException {
064    long startKey = 0;
065    long endKey = 100000;
066    int minColsPerKey = 5;
067    int maxColsPerKey = 15;
068    int minColDataSize = 256;
069    int maxColDataSize = 256 * 3;
070    int numThreads = 10;
071
072    // print out the arguments
073    System.out.printf("Key range %d .. %d\n", startKey, endKey);
074    System.out.printf("Number of Columns/Key: %d..%d\n", minColsPerKey, maxColsPerKey);
075    System.out.printf("Data Size/Column: %d..%d bytes\n", minColDataSize, maxColDataSize);
076    System.out.printf("Client Threads: %d\n", numThreads);
077
078    // start the writers
079    LoadTestDataGenerator dataGen = new MultiThreadedAction.DefaultDataGenerator(minColDataSize,
080      maxColDataSize, minColsPerKey, maxColsPerKey, HFileTestUtil.DEFAULT_COLUMN_FAMILY);
081    MultiThreadedWriter writer = new MultiThreadedWriter(dataGen, conf, TABLE_NAME);
082    writer.setMultiPut(true);
083    writer.start(startKey, endKey, numThreads);
084    System.out.printf("Started loading data...");
085    writer.waitForFinish();
086    System.out.printf("Finished loading data...");
087  }
088
089  @Override
090  protected int doWork() throws Exception {
091    ProcessBasedLocalHBaseCluster hbaseCluster =
092      new ProcessBasedLocalHBaseCluster(conf, NUM_DATANODES, numRegionServers);
093    hbaseCluster.startMiniDFS();
094
095    // start the process based HBase cluster
096    hbaseCluster.startHBase();
097
098    // create tables if needed
099    HBaseTestingUtil.createPreSplitLoadTestTable(conf, TABLE_NAME,
100      HFileTestUtil.DEFAULT_COLUMN_FAMILY, Compression.Algorithm.NONE, DataBlockEncoding.NONE);
101
102    LOG.debug("Loading data....\n\n");
103    loadData();
104
105    LOG.debug("Sleeping for " + SLEEP_SEC_AFTER_DATA_LOAD + " seconds....\n\n");
106    Threads.sleep(5 * SLEEP_SEC_AFTER_DATA_LOAD);
107
108    Connection connection = ConnectionFactory.createConnection(conf);
109
110    int metaRSPort = HBaseTestingUtil.getMetaRSPort(connection);
111
112    LOG.debug("Killing hbase:meta region server running on port " + metaRSPort);
113    hbaseCluster.killRegionServer(metaRSPort);
114    Threads.sleep(2000);
115
116    LOG.debug("Restarting region server running on port metaRSPort");
117    hbaseCluster.startRegionServer(metaRSPort);
118    Threads.sleep(2000);
119
120    LOG.debug("Trying to scan meta");
121
122    Table metaTable = connection.getTable(TableName.META_TABLE_NAME);
123    ResultScanner scanner = metaTable.getScanner(new Scan());
124    Result result;
125    while ((result = scanner.next()) != null) {
126      LOG.info("Region assignment from META: " + Bytes.toStringBinary(result.getRow()) + " => "
127        + Bytes.toStringBinary(
128          result.getFamilyMap(HConstants.CATALOG_FAMILY).get(HConstants.SERVER_QUALIFIER)));
129    }
130    metaTable.close();
131    connection.close();
132    return 0;
133  }
134
135  @Override
136  protected void addOptions() {
137    addOptWithArg(OPT_NUM_RS, "Number of Region Servers");
138    addOptWithArg(HFileTestUtil.OPT_DATA_BLOCK_ENCODING,
139      HFileTestUtil.OPT_DATA_BLOCK_ENCODING_USAGE);
140  }
141
142  @Override
143  protected void processOptions(CommandLine cmd) {
144    numRegionServers =
145      Integer.parseInt(cmd.getOptionValue(OPT_NUM_RS, String.valueOf(DEFAULT_NUM_RS)));
146  }
147
148  public static void main(String[] args) {
149    new RestartMetaTest().doStaticMain(args);
150  }
151
152}