You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2010/08/19 08:01:35 UTC
svn commit: r987026 - in /hbase/branches/0.90_master_rewrite/src:
main/java/org/apache/hadoop/hbase/master/
main/java/org/apache/hadoop/hbase/master/handler/
test/java/org/apache/hadoop/hbase/master/
Author: stack
Date: Thu Aug 19 06:01:34 2010
New Revision: 987026
URL: http://svn.apache.org/viewvc?rev=987026&view=rev
Log:
Put together the two unit tests that were named with the prefix
TestZKBased* They were duplicating a bunch of code. They needed
fixup too to pass; they referenced what I'm guessing are old names
for messages. Test passes now.
D src/test/java/org/apache/hadoop/hbase/master/TestZKBasedReopenRegion.java
Moved test to TestZKBaseOpenCloseRegion; this test dupp'd a bunch of
code from there anyways.
M src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
More detail in log message about what type of event we just got.
M src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java
New marker interface; useful testing.
M src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java
M src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java
Implement the new interface.
Added:
hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java
hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedOpenCloseRegion.java
Removed:
hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedCloseRegion.java
hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedReopenRegion.java
Modified:
hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java
hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java
Modified: hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java?rev=987026&r1=987025&r2=987026&view=diff
==============================================================================
--- hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (original)
+++ hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java Thu Aug 19 06:01:34 2010
@@ -239,8 +239,9 @@ public class AssignmentManager extends Z
}
String encodedName = HRegionInfo.encodeRegionName(data.getRegionName());
String prettyPrintedRegionName = HRegionInfo.prettyPrint(encodedName);
- LOG.debug("Handling transition=" + data.getEventType() + ", server=" +
- data.getServerName() + ", region=" + prettyPrintedRegionName);
+ LOG.debug("Handling transition=" + data.getEventType().name() +
+ "/" + data.getEventType().toString() +
+ ", server=" + data.getServerName() + ", region=" + prettyPrintedRegionName);
RegionState regionState = regionsInTransition.get(encodedName);
switch(data.getEventType()) {
Modified: hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java?rev=987026&r1=987025&r2=987026&view=diff
==============================================================================
--- hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java (original)
+++ hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/ClosedRegionHandler.java Thu Aug 19 06:01:34 2010
@@ -37,12 +37,13 @@ import org.apache.zookeeper.KeeperExcept
* <p>
* Otherwise, assigns the region to another server.
*/
-public class ClosedRegionHandler extends EventHandler {
+public class ClosedRegionHandler extends EventHandler implements TotesHRegionInfo {
private static final Log LOG = LogFactory.getLog(ClosedRegionHandler.class);
private final AssignmentManager assignmentManager;
private final RegionTransitionData data;
private final HRegionInfo regionInfo;
+
private final ClosedPriority priority;
private enum ClosedPriority {
@@ -81,6 +82,11 @@ public class ClosedRegionHandler extends
}
@Override
+ public HRegionInfo getHRegionInfo() {
+ return this.regionInfo;
+ }
+
+ @Override
public void process() {
LOG.debug("Handling CLOSED event with data: " + data);
// Check if this table is being disabled or not
Modified: hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java?rev=987026&r1=987025&r2=987026&view=diff
==============================================================================
--- hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java (original)
+++ hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/OpenedRegionHandler.java Thu Aug 19 06:01:34 2010
@@ -33,7 +33,7 @@ import org.apache.zookeeper.KeeperExcept
/**
* Handles OPENED region event on Master.
*/
-public class OpenedRegionHandler extends EventHandler {
+public class OpenedRegionHandler extends EventHandler implements TotesHRegionInfo {
private static final Log LOG = LogFactory.getLog(OpenedRegionHandler.class);
private final AssignmentManager assignmentManager;
@@ -79,6 +79,11 @@ public class OpenedRegionHandler extends
}
@Override
+ public HRegionInfo getHRegionInfo() {
+ return this.regionInfo;
+ }
+
+ @Override
public void process() {
LOG.debug("Handling OPENED event; deleting unassigned node with data: " + data);
// TODO: should we check if this table was disabled and get it closed?
Added: hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java?rev=987026&view=auto
==============================================================================
--- hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java (added)
+++ hbase/branches/0.90_master_rewrite/src/main/java/org/apache/hadoop/hbase/master/handler/TotesHRegionInfo.java Thu Aug 19 06:01:34 2010
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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.handler;
+
+import java.beans.EventHandler;
+
+import org.apache.hadoop.hbase.HRegionInfo;
+
+/**
+ * Implementors tote an HRegionInfo instance.
+ * This is a marker interface that can be put on {@link EventHandler}s that
+ * have an {@link HRegionInfo}.
+ */
+public interface TotesHRegionInfo {
+ /**
+ * @return HRegionInfo instance.
+ */
+ public HRegionInfo getHRegionInfo();
+}
Added: hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedOpenCloseRegion.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedOpenCloseRegion.java?rev=987026&view=auto
==============================================================================
--- hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedOpenCloseRegion.java (added)
+++ hbase/branches/0.90_master_rewrite/src/test/java/org/apache/hadoop/hbase/master/TestZKBasedOpenCloseRegion.java Thu Aug 19 06:01:34 2010
@@ -0,0 +1,346 @@
+/**
+ * Copyright 2010 The Apache Software Foundation
+ *
+ * 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.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.executor.EventHandler;
+import org.apache.hadoop.hbase.executor.EventHandler.EventHandlerListener;
+import org.apache.hadoop.hbase.executor.EventHandler.EventType;
+import org.apache.hadoop.hbase.master.handler.TotesHRegionInfo;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.regionserver.HRegionServer;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Threads;
+import org.apache.hadoop.hbase.util.Writables;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test open and close of regions using zk.
+ */
+public class TestZKBasedOpenCloseRegion {
+ private static final Log LOG = LogFactory.getLog(TestZKBasedOpenCloseRegion.class);
+ private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ private static final String TABLENAME = "TestZKBasedOpenCloseRegion";
+ private static final byte [][] FAMILIES = new byte [][] {Bytes.toBytes("a"),
+ Bytes.toBytes("b"), Bytes.toBytes("c")};
+
+ @BeforeClass public static void beforeAllTests() throws Exception {
+ Configuration c = TEST_UTIL.getConfiguration();
+ c.setBoolean("dfs.support.append", true);
+ c.setInt("hbase.regionserver.info.port", 0);
+ c.setInt("hbase.master.meta.thread.rescanfrequency", 5*1000);
+ TEST_UTIL.startMiniCluster(2);
+ TEST_UTIL.createTable(Bytes.toBytes(TABLENAME), FAMILIES);
+ HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME);
+ int countOfRegions = TEST_UTIL.createMultiRegions(t, getTestFamily());
+ waitUntilAllRegionsAssigned(countOfRegions);
+ addToEachStartKey(countOfRegions);
+ }
+
+ @AfterClass public static void afterAllTests() throws IOException {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ @Before public void setup() throws IOException {
+ if (TEST_UTIL.getHBaseCluster().getLiveRegionServerThreads().size() < 2) {
+ // Need at least two servers.
+ LOG.info("Started new server=" +
+ TEST_UTIL.getHBaseCluster().startRegionServer());
+
+ }
+ }
+
+ /**
+ * Test we reopen a region once closed.
+ * @throws Exception
+ */
+ @Test (timeout=300000) public void testReOpenRegion()
+ throws Exception {
+ MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+ LOG.info("Number of region servers = " +
+ cluster.getLiveRegionServerThreads().size());
+
+ int rsIdx = 0;
+ HRegionServer regionServer =
+ TEST_UTIL.getHBaseCluster().getRegionServer(rsIdx);
+ Collection<HRegion> regions = regionServer.getOnlineRegions();
+ HRegion region;
+ while((region = regions.iterator().next()) != null) {
+ if(!region.getRegionInfo().isMetaRegion() && !region.getRegionInfo().isRootRegion()) {
+ break;
+ }
+ }
+ LOG.debug("Asking RS to close region " + region.getRegionNameAsString());
+
+ AtomicBoolean closeEventProcessed = new AtomicBoolean(false);
+ AtomicBoolean reopenEventProcessed = new AtomicBoolean(false);
+
+ EventHandlerListener closeListener =
+ new ReopenEventListener(region.getRegionNameAsString(),
+ closeEventProcessed, EventType.RS2ZK_REGION_CLOSED);
+ cluster.getMaster().executorService.
+ registerListener(EventType.RS2ZK_REGION_CLOSED, closeListener);
+
+ EventHandlerListener openListener =
+ new ReopenEventListener(region.getRegionNameAsString(),
+ reopenEventProcessed, EventType.RS2ZK_REGION_OPENED);
+ cluster.getMaster().executorService.
+ registerListener(EventType.RS2ZK_REGION_OPENED, openListener);
+
+ LOG.info("Unassign " + region.getRegionNameAsString());
+ cluster.getMaster().assignmentManager.unassign(region.getRegionInfo());
+
+ synchronized(closeEventProcessed) {
+ closeEventProcessed.wait(3*60*1000);
+ }
+
+ if (!closeEventProcessed.get()) {
+ throw new Exception("Timed out, close event not called on master.");
+ }
+
+ synchronized(reopenEventProcessed) {
+ reopenEventProcessed.wait(3*60*1000);
+ }
+
+ if(!reopenEventProcessed.get()) {
+ throw new Exception("Timed out, open event not called on master after region close.");
+ }
+
+ LOG.info("\n\n\nDone with test, RS informed master successfully.\n\n\n");
+ }
+
+ public static class ReopenEventListener implements EventHandlerListener {
+ private static final Log LOG = LogFactory.getLog(ReopenEventListener.class);
+ String regionName;
+ AtomicBoolean eventProcessed;
+ EventType eventType;
+
+ public ReopenEventListener(String regionName,
+ AtomicBoolean eventProcessed, EventType eventType) {
+ this.regionName = regionName;
+ this.eventProcessed = eventProcessed;
+ this.eventType = eventType;
+ }
+
+ @Override
+ public void beforeProcess(EventHandler event) {
+ if(event.getEventType() == eventType) {
+ LOG.info("Received " + eventType + " and beginning to process it");
+ }
+ }
+
+ @Override
+ public void afterProcess(EventHandler event) {
+ LOG.info("afterProcess(" + event + ")");
+ if(event.getEventType() == eventType) {
+ LOG.info("Finished processing " + eventType);
+ String regionName = "";
+ if(eventType == EventType.RS2ZK_REGION_OPENED) {
+ TotesHRegionInfo hriCarrier = (TotesHRegionInfo)event;
+ regionName = hriCarrier.getHRegionInfo().getRegionNameAsString();
+ } else if(eventType == EventType.RS2ZK_REGION_CLOSED) {
+ TotesHRegionInfo hriCarrier = (TotesHRegionInfo)event;
+ regionName = hriCarrier.getHRegionInfo().getRegionNameAsString();
+ }
+ if(this.regionName.equals(regionName)) {
+ eventProcessed.set(true);
+ }
+ synchronized(eventProcessed) {
+ eventProcessed.notifyAll();
+ }
+ }
+ }
+ }
+
+ @Test (timeout=300000) public void testCloseRegion()
+ throws Exception {
+ LOG.info("Running testCloseRegion");
+ MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+ LOG.info("Number of region servers = " + cluster.getLiveRegionServerThreads().size());
+
+ int rsIdx = 0;
+ HRegionServer regionServer = TEST_UTIL.getHBaseCluster().getRegionServer(rsIdx);
+ Collection<HRegion> regions = regionServer.getOnlineRegions();
+ HRegion region;
+ while((region = regions.iterator().next()) != null) {
+ if(!region.getRegionInfo().isMetaRegion() && !region.getRegionInfo().isRootRegion()) {
+ break;
+ }
+ }
+ LOG.debug("Asking RS to close region " + region.getRegionNameAsString());
+
+ AtomicBoolean closeEventProcessed = new AtomicBoolean(false);
+ EventHandlerListener listener =
+ new CloseRegionEventListener(region.getRegionNameAsString(),
+ closeEventProcessed);
+ cluster.getMaster().executorService.registerListener(EventType.RS2ZK_REGION_CLOSED, listener);
+
+ cluster.getMaster().assignmentManager.unassign(region.getRegionInfo());
+
+ synchronized(closeEventProcessed) {
+ // wait for 3 minutes
+ closeEventProcessed.wait(3*60*1000);
+ }
+ if(!closeEventProcessed.get()) {
+ throw new Exception("Timed out, close event not called on master.");
+ }
+ else {
+ LOG.info("Done with test, RS informed master successfully.");
+ }
+ }
+
+ public static class CloseRegionEventListener implements EventHandlerListener {
+ private static final Log LOG = LogFactory.getLog(CloseRegionEventListener.class);
+ String regionToClose;
+ AtomicBoolean closeEventProcessed;
+
+ public CloseRegionEventListener(String regionToClose,
+ AtomicBoolean closeEventProcessed) {
+ this.regionToClose = regionToClose;
+ this.closeEventProcessed = closeEventProcessed;
+ }
+
+ @Override
+ public void afterProcess(EventHandler event) {
+ LOG.info("afterProcess(" + event + ")");
+ if(event.getEventType() == EventType.RS2ZK_REGION_CLOSED) {
+ LOG.info("Finished processing CLOSE REGION");
+ TotesHRegionInfo hriCarrier = (TotesHRegionInfo)event;
+ if(regionToClose.equals(hriCarrier.getHRegionInfo().getRegionNameAsString())) {
+ closeEventProcessed.set(true);
+ }
+ synchronized(closeEventProcessed) {
+ closeEventProcessed.notifyAll();
+ }
+ }
+ }
+
+ @Override
+ public void beforeProcess(EventHandler event) {
+ if(event.getEventType() == EventType.M2RS_CLOSE_REGION) {
+ LOG.info("Received CLOSE RPC and beginning to process it");
+ }
+ }
+ }
+
+ private static void waitUntilAllRegionsAssigned(final int countOfRegions)
+ throws IOException {
+ HTable meta = new HTable(TEST_UTIL.getConfiguration(),
+ HConstants.META_TABLE_NAME);
+ while (true) {
+ int rows = 0;
+ Scan scan = new Scan();
+ scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER);
+ ResultScanner s = meta.getScanner(scan);
+ for (Result r = null; (r = s.next()) != null;) {
+ byte [] b =
+ r.getValue(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER);
+ if (b == null || b.length <= 0) {
+ break;
+ }
+ rows++;
+ }
+ s.close();
+ // If I get to here and all rows have a Server, then all have been assigned.
+ if (rows == countOfRegions) {
+ break;
+ }
+ LOG.info("Found=" + rows);
+ Threads.sleep(1000);
+ }
+ }
+
+ /*
+ * Add to each of the regions in .META. a value. Key is the startrow of the
+ * region (except its 'aaa' for first region). Actual value is the row name.
+ * @param expected
+ * @return
+ * @throws IOException
+ */
+ private static int addToEachStartKey(final int expected) throws IOException {
+ HTable t = new HTable(TEST_UTIL.getConfiguration(), TABLENAME);
+ HTable meta = new HTable(TEST_UTIL.getConfiguration(),
+ HConstants.META_TABLE_NAME);
+ int rows = 0;
+ Scan scan = new Scan();
+ scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+ ResultScanner s = meta.getScanner(scan);
+ for (Result r = null; (r = s.next()) != null;) {
+ byte [] b =
+ r.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+ if (b == null || b.length <= 0) {
+ break;
+ }
+ HRegionInfo hri = Writables.getHRegionInfo(b);
+ // If start key, add 'aaa'.
+ byte [] row = getStartKey(hri);
+ Put p = new Put(row);
+ p.add(getTestFamily(), getTestQualifier(), row);
+ t.put(p);
+ rows++;
+ }
+ s.close();
+ Assert.assertEquals(expected, rows);
+ return rows;
+ }
+
+ private static byte [] getStartKey(final HRegionInfo hri) {
+ return Bytes.equals(HConstants.EMPTY_START_ROW, hri.getStartKey())?
+ Bytes.toBytes("aaa"): hri.getStartKey();
+ }
+
+ private static byte [] getTestFamily() {
+ return FAMILIES[0];
+ }
+
+ private static byte [] getTestQualifier() {
+ return getTestFamily();
+ }
+
+ public static void main(String args[]) throws Exception {
+ TestZKBasedOpenCloseRegion.beforeAllTests();
+
+ TestZKBasedOpenCloseRegion test = new TestZKBasedOpenCloseRegion();
+ test.setup();
+ test.testCloseRegion();
+
+ TestZKBasedOpenCloseRegion.afterAllTests();
+ }
+}