001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with this
004 * work for additional information regarding copyright ownership. The ASF
005 * licenses this file to you under the Apache License, Version 2.0 (the
006 * "License"); you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014 * License for the specific language governing permissions and limitations
015 * under the License.
016 */
017package org.apache.hadoop.hbase.util;
018
019import java.io.IOException;
020
021import org.apache.hadoop.hbase.HBaseTestingUtility;
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;
035import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
036
037/**
038 * A command-line tool that spins up a local process-based cluster, loads
039 * some data, restarts the regionserver holding hbase:meta, and verifies that the
040 * 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 =
051      TableName.valueOf("load_test");
052
053  /** The number of seconds to sleep after loading the data */
054  private static final int SLEEP_SEC_AFTER_DATA_LOAD = 5;
055
056  /** The actual number of region servers */
057  private int numRegionServers;
058
059  private static final String OPT_NUM_RS = "num_rs";
060
061  private static final int NUM_DATANODES = 3;
062
063  /** Loads data into the table using the multi-threaded writer. */
064  private void loadData() throws IOException {
065    long startKey = 0;
066    long endKey = 100000;
067    int minColsPerKey = 5;
068    int maxColsPerKey = 15;
069    int minColDataSize = 256;
070    int maxColDataSize = 256 * 3;
071    int numThreads = 10;
072
073    // print out the arguments
074    System.out.printf("Key range %d .. %d\n", startKey, endKey);
075    System.out.printf("Number of Columns/Key: %d..%d\n", minColsPerKey,
076        maxColsPerKey);
077    System.out.printf("Data Size/Column: %d..%d bytes\n", minColDataSize,
078        maxColDataSize);
079    System.out.printf("Client Threads: %d\n", numThreads);
080
081    // start the writers
082    LoadTestDataGenerator dataGen = new MultiThreadedAction.DefaultDataGenerator(
083      minColDataSize, maxColDataSize, minColsPerKey, maxColsPerKey,
084      HFileTestUtil.DEFAULT_COLUMN_FAMILY);
085    MultiThreadedWriter writer = new MultiThreadedWriter(dataGen, conf, TABLE_NAME);
086    writer.setMultiPut(true);
087    writer.start(startKey, endKey, numThreads);
088    System.out.printf("Started loading data...");
089    writer.waitForFinish();
090    System.out.printf("Finished loading data...");
091  }
092
093  @Override
094  protected int doWork() throws Exception {
095    ProcessBasedLocalHBaseCluster hbaseCluster =
096        new ProcessBasedLocalHBaseCluster(conf, NUM_DATANODES, numRegionServers);
097    hbaseCluster.startMiniDFS();
098
099    // start the process based HBase cluster
100    hbaseCluster.startHBase();
101
102    // create tables if needed
103    HBaseTestingUtility.createPreSplitLoadTestTable(conf, TABLE_NAME,
104        HFileTestUtil.DEFAULT_COLUMN_FAMILY, Compression.Algorithm.NONE,
105        DataBlockEncoding.NONE);
106
107    LOG.debug("Loading data....\n\n");
108    loadData();
109
110    LOG.debug("Sleeping for " + SLEEP_SEC_AFTER_DATA_LOAD +
111        " seconds....\n\n");
112    Threads.sleep(5 * SLEEP_SEC_AFTER_DATA_LOAD);
113
114    Connection connection = ConnectionFactory.createConnection(conf);
115
116    int metaRSPort = HBaseTestingUtility.getMetaRSPort(connection);
117
118    LOG.debug("Killing hbase:meta region server running on port " + metaRSPort);
119    hbaseCluster.killRegionServer(metaRSPort);
120    Threads.sleep(2000);
121
122    LOG.debug("Restarting region server running on port metaRSPort");
123    hbaseCluster.startRegionServer(metaRSPort);
124    Threads.sleep(2000);
125
126    LOG.debug("Trying to scan meta");
127
128    Table metaTable = connection.getTable(TableName.META_TABLE_NAME);
129    ResultScanner scanner = metaTable.getScanner(new Scan());
130    Result result;
131    while ((result = scanner.next()) != null) {
132      LOG.info("Region assignment from META: "
133          + Bytes.toStringBinary(result.getRow())
134          + " => "
135          + Bytes.toStringBinary(result.getFamilyMap(HConstants.CATALOG_FAMILY)
136              .get(HConstants.SERVER_QUALIFIER)));
137    }
138    metaTable.close();
139    connection.close();
140    return 0;
141  }
142
143  @Override
144  protected void addOptions() {
145    addOptWithArg(OPT_NUM_RS, "Number of Region Servers");
146    addOptWithArg(HFileTestUtil.OPT_DATA_BLOCK_ENCODING,
147        HFileTestUtil.OPT_DATA_BLOCK_ENCODING_USAGE);
148  }
149
150  @Override
151  protected void processOptions(CommandLine cmd) {
152    numRegionServers = Integer.parseInt(cmd.getOptionValue(OPT_NUM_RS,
153        String.valueOf(DEFAULT_NUM_RS)));
154  }
155
156  public static void main(String[] args) {
157    new RestartMetaTest().doStaticMain(args);
158  }
159
160}