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}