HBASE-22196 Split TestRestartCluster
This commit is contained in:
parent
ffede2edfa
commit
a74e1ecad9
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class AbstractTestRestartCluster {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractTestRestartCluster.class);
|
||||
|
||||
protected HBaseTestingUtility UTIL = new HBaseTestingUtility();
|
||||
|
||||
protected static final TableName[] TABLES = { TableName.valueOf("restartTableOne"),
|
||||
TableName.valueOf("restartTableTwo"), TableName.valueOf("restartTableThree") };
|
||||
|
||||
protected static final byte[] FAMILY = Bytes.toBytes("family");
|
||||
|
||||
protected abstract boolean splitWALCoordinatedByZk();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
boolean splitWALCoordinatedByZk = splitWALCoordinatedByZk();
|
||||
LOG.info("WAL splitting coordinated by zk {}", splitWALCoordinatedByZk);
|
||||
UTIL.getConfiguration().setBoolean(HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK,
|
||||
splitWALCoordinatedByZk);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
UTIL.shutdownMiniCluster();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.MetaTableAccessor;
|
||||
import org.apache.hadoop.hbase.TableExistsException;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.RegionInfo;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestClusterRestart extends AbstractTestRestartCluster {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestClusterRestart.class);
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestClusterRestart.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
UTIL.startMiniCluster(3);
|
||||
UTIL.waitFor(60000, () -> UTIL.getMiniHBaseCluster().getMaster().isInitialized());
|
||||
LOG.info("\n\nCreating tables");
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
}
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.waitTableEnabled(TABLE);
|
||||
}
|
||||
|
||||
List<RegionInfo> allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false);
|
||||
assertEquals(3, allRegions.size());
|
||||
|
||||
LOG.info("\n\nShutting down cluster");
|
||||
UTIL.shutdownMiniHBaseCluster();
|
||||
|
||||
LOG.info("\n\nSleeping a bit");
|
||||
Thread.sleep(2000);
|
||||
|
||||
LOG.info("\n\nStarting cluster the second time");
|
||||
UTIL.restartHBaseCluster(3);
|
||||
|
||||
// Need to use a new 'Configuration' so we make a new Connection.
|
||||
// Otherwise we're reusing an Connection that has gone stale because
|
||||
// the shutdown of the cluster also called shut of the connection.
|
||||
allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false);
|
||||
assertEquals(3, allRegions.size());
|
||||
LOG.info("\n\nWaiting for tables to be available");
|
||||
for (TableName TABLE : TABLES) {
|
||||
try {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
assertTrue("Able to create table that should already exist", false);
|
||||
} catch (TableExistsException tee) {
|
||||
LOG.info("Table already exists as expected");
|
||||
}
|
||||
UTIL.waitTableAvailable(TABLE);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.master.assignment.ServerState;
|
||||
import org.apache.hadoop.hbase.master.assignment.ServerStateNode;
|
||||
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
|
||||
import org.apache.hadoop.hbase.procedure2.Procedure;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestClusterRestartFailover extends AbstractTestRestartCluster {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestClusterRestartFailover.class);
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestClusterRestartFailover.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private ServerStateNode getServerStateNode(ServerName serverName) {
|
||||
return UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(serverName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
UTIL.startMiniCluster(3);
|
||||
UTIL.waitFor(60000, () -> UTIL.getMiniHBaseCluster().getMaster().isInitialized());
|
||||
// wait for all SCPs finished
|
||||
UTIL.waitFor(60000, () -> UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.noneMatch(p -> p instanceof ServerCrashProcedure));
|
||||
TableName tableName = TABLES[0];
|
||||
ServerName testServer = UTIL.getHBaseCluster().getRegionServer(0).getServerName();
|
||||
UTIL.waitFor(10000, () -> getServerStateNode(testServer) != null);
|
||||
ServerStateNode serverNode = getServerStateNode(testServer);
|
||||
Assert.assertNotNull(serverNode);
|
||||
Assert.assertTrue("serverNode should be ONLINE when cluster runs normally",
|
||||
serverNode.isInState(ServerState.ONLINE));
|
||||
UTIL.createMultiRegionTable(tableName, FAMILY);
|
||||
UTIL.waitTableEnabled(tableName);
|
||||
Table table = UTIL.getConnection().getTable(tableName);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
UTIL.loadTable(table, FAMILY);
|
||||
}
|
||||
List<Integer> ports =
|
||||
UTIL.getHBaseCluster().getMaster().getServerManager().getOnlineServersList().stream()
|
||||
.map(serverName -> serverName.getPort()).collect(Collectors.toList());
|
||||
LOG.info("Shutting down cluster");
|
||||
UTIL.getHBaseCluster().killAll();
|
||||
UTIL.getHBaseCluster().waitUntilShutDown();
|
||||
LOG.info("Starting cluster the second time");
|
||||
UTIL.restartHBaseCluster(3, ports);
|
||||
UTIL.waitFor(10000, () -> UTIL.getHBaseCluster().getMaster().isInitialized());
|
||||
serverNode = UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(testServer);
|
||||
Assert.assertNotNull("serverNode should not be null when restart whole cluster", serverNode);
|
||||
Assert.assertFalse(serverNode.isInState(ServerState.ONLINE));
|
||||
LOG.info("start to find the procedure of SCP for the severName we choose");
|
||||
UTIL.waitFor(60000,
|
||||
() -> UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.anyMatch(procedure -> (procedure instanceof ServerCrashProcedure) &&
|
||||
((ServerCrashProcedure) procedure).getServerName().equals(testServer)));
|
||||
Assert.assertFalse("serverNode should not be ONLINE during SCP processing",
|
||||
serverNode.isInState(ServerState.ONLINE));
|
||||
LOG.info("start to submit the SCP for the same serverName {} which should fail", testServer);
|
||||
Assert
|
||||
.assertFalse(UTIL.getHBaseCluster().getMaster().getServerManager().expireServer(testServer));
|
||||
Procedure<?> procedure = UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.filter(p -> (p instanceof ServerCrashProcedure) &&
|
||||
((ServerCrashProcedure) p).getServerName().equals(testServer))
|
||||
.findAny().get();
|
||||
UTIL.waitFor(60000, () -> procedure.isFinished());
|
||||
LOG.info("even when the SCP is finished, the duplicate SCP should not be scheduled for {}",
|
||||
testServer);
|
||||
Assert
|
||||
.assertFalse(UTIL.getHBaseCluster().getMaster().getServerManager().expireServer(testServer));
|
||||
serverNode = UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(testServer);
|
||||
Assert.assertNull("serverNode should be deleted after SCP finished", serverNode);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestClusterRestartFailoverSplitWithoutZk extends TestClusterRestartFailover {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestClusterRestartFailoverSplitWithoutZk.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestClusterRestartSplitWithoutZk extends TestClusterRestart {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestClusterRestartSplitWithoutZk.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.util.JVMClusterUtil;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestNewStartedRegionServerVersion {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestNewStartedRegionServerVersion.class);
|
||||
|
||||
private static final Logger LOG =
|
||||
LoggerFactory.getLogger(TestNewStartedRegionServerVersion.class);
|
||||
|
||||
private static HBaseTestingUtility UTIL = new HBaseTestingUtility();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
UTIL.startMiniCluster(1);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() throws Exception {
|
||||
UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws InterruptedException {
|
||||
// Start 3 new region server
|
||||
Thread t = new Thread(() -> {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
JVMClusterUtil.RegionServerThread newRS = UTIL.getMiniHBaseCluster().startRegionServer();
|
||||
newRS.waitForServerOnline();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to start a new RS", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
|
||||
HMaster master = UTIL.getMiniHBaseCluster().getMaster();
|
||||
while (t.isAlive()) {
|
||||
List<ServerName> serverNames = master.getServerManager().getOnlineServersList();
|
||||
for (ServerName serverName : serverNames) {
|
||||
assertNotEquals(0, master.getServerManager().getVersionNumber(serverName));
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,327 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.HBaseTestingUtility;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.MetaTableAccessor;
|
||||
import org.apache.hadoop.hbase.MiniHBaseCluster;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.TableExistsException;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.RegionInfo;
|
||||
import org.apache.hadoop.hbase.client.Table;
|
||||
import org.apache.hadoop.hbase.master.assignment.ServerState;
|
||||
import org.apache.hadoop.hbase.master.assignment.ServerStateNode;
|
||||
import org.apache.hadoop.hbase.master.procedure.ServerCrashProcedure;
|
||||
import org.apache.hadoop.hbase.procedure2.Procedure;
|
||||
import org.apache.hadoop.hbase.testclassification.LargeTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.JVMClusterUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
@Category({ MasterTests.class, LargeTests.class })
|
||||
public class TestRestartCluster {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestRestartCluster.class);
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestRestartCluster.class);
|
||||
private HBaseTestingUtility UTIL = new HBaseTestingUtility();
|
||||
|
||||
@Parameterized.Parameter
|
||||
public boolean splitWALCoordinatedByZK;
|
||||
|
||||
private static final TableName[] TABLES = {
|
||||
TableName.valueOf("restartTableOne"),
|
||||
TableName.valueOf("restartTableTwo"),
|
||||
TableName.valueOf("restartTableThree")
|
||||
};
|
||||
private static final byte[] FAMILY = Bytes.toBytes("family");
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
LOG.info("WAL splitting coordinated by zk? {}", splitWALCoordinatedByZK);
|
||||
UTIL.getConfiguration().setBoolean(HConstants.HBASE_SPLIT_WAL_COORDINATED_BY_ZK,
|
||||
splitWALCoordinatedByZK);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
UTIL.shutdownMiniCluster();
|
||||
}
|
||||
|
||||
private ServerStateNode getServerStateNode(ServerName serverName) {
|
||||
return UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(serverName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterRestartFailOver() throws Exception {
|
||||
UTIL.startMiniCluster(3);
|
||||
UTIL.waitFor(60000, () -> UTIL.getMiniHBaseCluster().getMaster().isInitialized());
|
||||
// wait for all SCPs finished
|
||||
UTIL.waitFor(60000, () -> UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.noneMatch(p -> p instanceof ServerCrashProcedure));
|
||||
TableName tableName = TABLES[0];
|
||||
ServerName testServer = UTIL.getHBaseCluster().getRegionServer(0).getServerName();
|
||||
UTIL.waitFor(10000, () -> getServerStateNode(testServer) != null);
|
||||
ServerStateNode serverNode = getServerStateNode(testServer);
|
||||
Assert.assertNotNull(serverNode);
|
||||
Assert.assertTrue("serverNode should be ONLINE when cluster runs normally",
|
||||
serverNode.isInState(ServerState.ONLINE));
|
||||
UTIL.createMultiRegionTable(tableName, FAMILY);
|
||||
UTIL.waitTableEnabled(tableName);
|
||||
Table table = UTIL.getConnection().getTable(tableName);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
UTIL.loadTable(table, FAMILY);
|
||||
}
|
||||
List<Integer> ports =
|
||||
UTIL.getHBaseCluster().getMaster().getServerManager().getOnlineServersList().stream()
|
||||
.map(serverName -> serverName.getPort()).collect(Collectors.toList());
|
||||
LOG.info("Shutting down cluster");
|
||||
UTIL.getHBaseCluster().killAll();
|
||||
UTIL.getHBaseCluster().waitUntilShutDown();
|
||||
LOG.info("Starting cluster the second time");
|
||||
UTIL.restartHBaseCluster(3, ports);
|
||||
UTIL.waitFor(10000, () -> UTIL.getHBaseCluster().getMaster().isInitialized());
|
||||
serverNode = UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(testServer);
|
||||
Assert.assertNotNull("serverNode should not be null when restart whole cluster", serverNode);
|
||||
Assert.assertFalse(serverNode.isInState(ServerState.ONLINE));
|
||||
LOG.info("start to find the procedure of SCP for the severName we choose");
|
||||
UTIL.waitFor(60000,
|
||||
() -> UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.anyMatch(procedure -> (procedure instanceof ServerCrashProcedure)
|
||||
&& ((ServerCrashProcedure) procedure).getServerName().equals(testServer)));
|
||||
Assert.assertFalse("serverNode should not be ONLINE during SCP processing",
|
||||
serverNode.isInState(ServerState.ONLINE));
|
||||
LOG.info("start to submit the SCP for the same serverName {} which should fail", testServer);
|
||||
Assert.assertFalse(
|
||||
UTIL.getHBaseCluster().getMaster().getServerManager().expireServer(testServer));
|
||||
Procedure<?> procedure = UTIL.getHBaseCluster().getMaster().getProcedures().stream()
|
||||
.filter(p -> (p instanceof ServerCrashProcedure)
|
||||
&& ((ServerCrashProcedure) p).getServerName().equals(testServer))
|
||||
.findAny().get();
|
||||
UTIL.waitFor(60000, () -> procedure.isFinished());
|
||||
LOG.info("even when the SCP is finished, the duplicate SCP should not be scheduled for {}",
|
||||
testServer);
|
||||
Assert.assertFalse(
|
||||
UTIL.getHBaseCluster().getMaster().getServerManager().expireServer(testServer));
|
||||
serverNode = UTIL.getHBaseCluster().getMaster().getAssignmentManager().getRegionStates()
|
||||
.getServerNode(testServer);
|
||||
Assert.assertNull("serverNode should be deleted after SCP finished", serverNode);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClusterRestart() throws Exception {
|
||||
UTIL.startMiniCluster(3);
|
||||
UTIL.waitFor(60000, () -> UTIL.getMiniHBaseCluster().getMaster().isInitialized());
|
||||
LOG.info("\n\nCreating tables");
|
||||
for(TableName TABLE : TABLES) {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
}
|
||||
for(TableName TABLE : TABLES) {
|
||||
UTIL.waitTableEnabled(TABLE);
|
||||
}
|
||||
|
||||
List<RegionInfo> allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false);
|
||||
assertEquals(3, allRegions.size());
|
||||
|
||||
LOG.info("\n\nShutting down cluster");
|
||||
UTIL.shutdownMiniHBaseCluster();
|
||||
|
||||
LOG.info("\n\nSleeping a bit");
|
||||
Thread.sleep(2000);
|
||||
|
||||
LOG.info("\n\nStarting cluster the second time");
|
||||
UTIL.restartHBaseCluster(3);
|
||||
|
||||
// Need to use a new 'Configuration' so we make a new Connection.
|
||||
// Otherwise we're reusing an Connection that has gone stale because
|
||||
// the shutdown of the cluster also called shut of the connection.
|
||||
allRegions = MetaTableAccessor.getAllRegions(UTIL.getConnection(), false);
|
||||
assertEquals(3, allRegions.size());
|
||||
LOG.info("\n\nWaiting for tables to be available");
|
||||
for(TableName TABLE: TABLES) {
|
||||
try {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
assertTrue("Able to create table that should already exist", false);
|
||||
} catch(TableExistsException tee) {
|
||||
LOG.info("Table already exists as expected");
|
||||
}
|
||||
UTIL.waitTableAvailable(TABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests retaining assignments on a cluster restart
|
||||
*/
|
||||
@Test
|
||||
public void testRetainAssignmentOnRestart() throws Exception {
|
||||
UTIL.startMiniCluster(2);
|
||||
// Turn off balancer
|
||||
UTIL.getMiniHBaseCluster().getMaster().getMasterRpcServices().synchronousBalanceSwitch(false);
|
||||
LOG.info("\n\nCreating tables");
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
}
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.waitTableEnabled(TABLE);
|
||||
}
|
||||
|
||||
HMaster master = UTIL.getMiniHBaseCluster().getMaster();
|
||||
UTIL.waitUntilNoRegionsInTransition(120000);
|
||||
|
||||
// We don't have to use SnapshotOfRegionAssignmentFromMeta.
|
||||
// We use it here because AM used to use it to load all user region placements
|
||||
SnapshotOfRegionAssignmentFromMeta snapshot = new SnapshotOfRegionAssignmentFromMeta(
|
||||
master.getConnection());
|
||||
snapshot.initialize();
|
||||
Map<RegionInfo, ServerName> regionToRegionServerMap
|
||||
= snapshot.getRegionToRegionServerMap();
|
||||
|
||||
MiniHBaseCluster cluster = UTIL.getHBaseCluster();
|
||||
List<JVMClusterUtil.RegionServerThread> threads = cluster.getLiveRegionServerThreads();
|
||||
assertEquals(2, threads.size());
|
||||
int[] rsPorts = new int[3];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
rsPorts[i] = threads.get(i).getRegionServer().getServerName().getPort();
|
||||
}
|
||||
rsPorts[2] = cluster.getMaster().getServerName().getPort();
|
||||
for (ServerName serverName: regionToRegionServerMap.values()) {
|
||||
boolean found = false; // Test only, no need to optimize
|
||||
for (int k = 0; k < 3 && !found; k++) {
|
||||
found = serverName.getPort() == rsPorts[k];
|
||||
}
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
LOG.info("\n\nShutting down HBase cluster");
|
||||
cluster.stopMaster(0);
|
||||
cluster.shutdown();
|
||||
cluster.waitUntilShutDown();
|
||||
|
||||
LOG.info("\n\nSleeping a bit");
|
||||
Thread.sleep(2000);
|
||||
|
||||
LOG.info("\n\nStarting cluster the second time with the same ports");
|
||||
try {
|
||||
cluster.getConf().setInt(
|
||||
ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 3);
|
||||
master = cluster.startMaster().getMaster();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, rsPorts[i]);
|
||||
cluster.startRegionServer();
|
||||
}
|
||||
} finally {
|
||||
// Reset region server port so as not to conflict with other tests
|
||||
cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, 0);
|
||||
cluster.getConf().setInt(
|
||||
ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 2);
|
||||
}
|
||||
|
||||
// Make sure live regionservers are on the same host/port
|
||||
List<ServerName> localServers = master.getServerManager().getOnlineServersList();
|
||||
assertEquals(3, localServers.size());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
boolean found = false;
|
||||
for (ServerName serverName: localServers) {
|
||||
if (serverName.getPort() == rsPorts[i]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
// Wait till master is initialized and all regions are assigned
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.waitTableAvailable(TABLE);
|
||||
}
|
||||
|
||||
snapshot = new SnapshotOfRegionAssignmentFromMeta(master.getConnection());
|
||||
snapshot.initialize();
|
||||
Map<RegionInfo, ServerName> newRegionToRegionServerMap =
|
||||
snapshot.getRegionToRegionServerMap();
|
||||
assertEquals(regionToRegionServerMap.size(), newRegionToRegionServerMap.size());
|
||||
for (Map.Entry<RegionInfo, ServerName> entry : newRegionToRegionServerMap.entrySet()) {
|
||||
ServerName oldServer = regionToRegionServerMap.get(entry.getKey());
|
||||
ServerName currentServer = entry.getValue();
|
||||
LOG.info(
|
||||
"Key=" + entry.getKey() + " oldServer=" + oldServer + ", currentServer=" + currentServer);
|
||||
assertEquals(entry.getKey().toString(), oldServer.getAddress(), currentServer.getAddress());
|
||||
assertNotEquals(oldServer.getStartcode(), currentServer.getStartcode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNewStartedRegionServerVersion() throws Exception {
|
||||
UTIL.startMiniCluster(1);
|
||||
|
||||
// Start 3 new region server
|
||||
Thread t = new Thread(() -> {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
JVMClusterUtil.RegionServerThread newRS = UTIL.getMiniHBaseCluster().startRegionServer();
|
||||
newRS.waitForServerOnline();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to start a new RS", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
|
||||
HMaster master = UTIL.getMiniHBaseCluster().getMaster();
|
||||
while (t.isAlive()) {
|
||||
List<ServerName> serverNames = master.getServerManager().getOnlineServersList();
|
||||
for (ServerName serverName : serverNames) {
|
||||
assertNotEquals(0, master.getServerManager().getVersionNumber(serverName));
|
||||
}
|
||||
Thread.sleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static Collection<?> coordinatedByZK() {
|
||||
return Arrays.asList(false, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.HConstants;
|
||||
import org.apache.hadoop.hbase.MiniHBaseCluster;
|
||||
import org.apache.hadoop.hbase.ServerName;
|
||||
import org.apache.hadoop.hbase.TableName;
|
||||
import org.apache.hadoop.hbase.client.RegionInfo;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.apache.hadoop.hbase.util.JVMClusterUtil;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import org.junit.experimental.categories.Category;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestRetainAssignmentOnRestart extends AbstractTestRestartCluster {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestRetainAssignmentOnRestart.class);
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TestRetainAssignmentOnRestart.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This tests retaining assignments on a cluster restart
|
||||
*/
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
UTIL.startMiniCluster(2);
|
||||
// Turn off balancer
|
||||
UTIL.getMiniHBaseCluster().getMaster().getMasterRpcServices().synchronousBalanceSwitch(false);
|
||||
LOG.info("\n\nCreating tables");
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.createTable(TABLE, FAMILY);
|
||||
}
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.waitTableEnabled(TABLE);
|
||||
}
|
||||
|
||||
HMaster master = UTIL.getMiniHBaseCluster().getMaster();
|
||||
UTIL.waitUntilNoRegionsInTransition(60000);
|
||||
|
||||
// We don't have to use SnapshotOfRegionAssignmentFromMeta.
|
||||
// We use it here because AM used to use it to load all user region placements
|
||||
SnapshotOfRegionAssignmentFromMeta snapshot =
|
||||
new SnapshotOfRegionAssignmentFromMeta(master.getConnection());
|
||||
snapshot.initialize();
|
||||
Map<RegionInfo, ServerName> regionToRegionServerMap = snapshot.getRegionToRegionServerMap();
|
||||
|
||||
MiniHBaseCluster cluster = UTIL.getHBaseCluster();
|
||||
List<JVMClusterUtil.RegionServerThread> threads = cluster.getLiveRegionServerThreads();
|
||||
assertEquals(2, threads.size());
|
||||
int[] rsPorts = new int[3];
|
||||
for (int i = 0; i < 2; i++) {
|
||||
rsPorts[i] = threads.get(i).getRegionServer().getServerName().getPort();
|
||||
}
|
||||
rsPorts[2] = cluster.getMaster().getServerName().getPort();
|
||||
for (ServerName serverName : regionToRegionServerMap.values()) {
|
||||
boolean found = false; // Test only, no need to optimize
|
||||
for (int k = 0; k < 3 && !found; k++) {
|
||||
found = serverName.getPort() == rsPorts[k];
|
||||
}
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
LOG.info("\n\nShutting down HBase cluster");
|
||||
cluster.stopMaster(0);
|
||||
cluster.shutdown();
|
||||
cluster.waitUntilShutDown();
|
||||
|
||||
LOG.info("\n\nSleeping a bit");
|
||||
Thread.sleep(2000);
|
||||
|
||||
LOG.info("\n\nStarting cluster the second time with the same ports");
|
||||
cluster.getConf().setInt(ServerManager.WAIT_ON_REGIONSERVERS_MINTOSTART, 3);
|
||||
master = cluster.startMaster().getMaster();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
cluster.getConf().setInt(HConstants.REGIONSERVER_PORT, rsPorts[i]);
|
||||
cluster.startRegionServer();
|
||||
}
|
||||
|
||||
// Make sure live regionservers are on the same host/port
|
||||
List<ServerName> localServers = master.getServerManager().getOnlineServersList();
|
||||
assertEquals(3, localServers.size());
|
||||
for (int i = 0; i < 3; i++) {
|
||||
boolean found = false;
|
||||
for (ServerName serverName : localServers) {
|
||||
if (serverName.getPort() == rsPorts[i]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue(found);
|
||||
}
|
||||
|
||||
// Wait till master is initialized and all regions are assigned
|
||||
for (TableName TABLE : TABLES) {
|
||||
UTIL.waitTableAvailable(TABLE);
|
||||
}
|
||||
UTIL.waitUntilNoRegionsInTransition(60000);
|
||||
|
||||
snapshot = new SnapshotOfRegionAssignmentFromMeta(master.getConnection());
|
||||
snapshot.initialize();
|
||||
Map<RegionInfo, ServerName> newRegionToRegionServerMap = snapshot.getRegionToRegionServerMap();
|
||||
assertEquals(regionToRegionServerMap.size(), newRegionToRegionServerMap.size());
|
||||
for (Map.Entry<RegionInfo, ServerName> entry : newRegionToRegionServerMap.entrySet()) {
|
||||
ServerName oldServer = regionToRegionServerMap.get(entry.getKey());
|
||||
ServerName currentServer = entry.getValue();
|
||||
LOG.info(
|
||||
"Key=" + entry.getKey() + " oldServer=" + oldServer + ", currentServer=" + currentServer);
|
||||
assertEquals(entry.getKey().toString(), oldServer.getAddress(), currentServer.getAddress());
|
||||
assertNotEquals(oldServer.getStartcode(), currentServer.getStartcode());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.hbase.master;
|
||||
|
||||
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||
import org.apache.hadoop.hbase.testclassification.MasterTests;
|
||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.experimental.categories.Category;
|
||||
|
||||
@Category({ MasterTests.class, MediumTests.class })
|
||||
public class TestRetainAssignmentOnRestartSplitWithoutZk extends TestRetainAssignmentOnRestart {
|
||||
|
||||
@ClassRule
|
||||
public static final HBaseClassTestRule CLASS_RULE =
|
||||
HBaseClassTestRule.forClass(TestRetainAssignmentOnRestartSplitWithoutZk.class);
|
||||
|
||||
@Override
|
||||
protected boolean splitWALCoordinatedByZk() {
|
||||
return false;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue