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/09/01 01:51:50 UTC
svn commit: r991397 [2/15] - in /hbase/trunk: ./ bin/ conf/
src/main/java/org/apache/hadoop/hbase/
src/main/java/org/apache/hadoop/hbase/avro/
src/main/java/org/apache/hadoop/hbase/catalog/
src/main/java/org/apache/hadoop/hbase/client/ src/main/java/or...
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java?rev=991397&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java Tue Aug 31 23:51:44 2010
@@ -0,0 +1,395 @@
+/**
+ * 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.catalog;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.Abortable;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HServerAddress;
+import org.apache.hadoop.hbase.HServerInfo;
+import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
+import org.apache.hadoop.hbase.NotServingRegionException;
+import org.apache.hadoop.hbase.client.RetriesExhaustedException;
+import org.apache.hadoop.hbase.client.ServerConnection;
+import org.apache.hadoop.hbase.ipc.HRegionInterface;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.zookeeper.MetaNodeTracker;
+import org.apache.hadoop.hbase.zookeeper.RootRegionTracker;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Tracks the availability of the catalog tables <code>-ROOT-</code> and
+ * <code>.META.</code>.
+ * <p>
+ * This class is "read-only" in that the locations of the catalog tables cannot
+ * be explicitly set. Instead, ZooKeeper is used to learn of the availability
+ * and location of ROOT. ROOT is used to learn of the location of META. If not
+ * available in ROOT, ZooKeeper is used to monitor for a new location of META.
+ */
+public class CatalogTracker {
+ private static final Log LOG = LogFactory.getLog(CatalogTracker.class);
+
+ private final ServerConnection connection;
+
+ private final ZooKeeperWatcher zookeeper;
+
+ private final RootRegionTracker rootRegionTracker;
+
+ private final MetaNodeTracker metaNodeTracker;
+
+ private final AtomicBoolean metaAvailable = new AtomicBoolean(false);
+ private HServerAddress metaLocation;
+
+ private final int defaultTimeout;
+
+ public static final byte [] ROOT_REGION =
+ HRegionInfo.ROOT_REGIONINFO.getRegionName();
+
+ public static final byte [] META_REGION =
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName();
+
+ /**
+ * Constructs the catalog tracker. Find current state of catalog tables and
+ * begin active tracking by executing {@link #start()}.
+ * @param zk
+ * @param connection server connection
+ * @param abortable if fatal exception
+ * @throws IOException
+ */
+ public CatalogTracker(final ZooKeeperWatcher zk,
+ final ServerConnection connection, final Abortable abortable,
+ final int defaultTimeout)
+ throws IOException {
+ this.zookeeper = zk;
+ this.connection = connection;
+ this.rootRegionTracker = new RootRegionTracker(zookeeper, abortable);
+ this.metaNodeTracker = new MetaNodeTracker(zookeeper, this);
+ this.defaultTimeout = defaultTimeout;
+ }
+
+ /**
+ * Starts the catalog tracker.
+ * <p>
+ * Determines current availability of catalog tables and ensures all further
+ * transitions of either region is tracked.
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public void start() throws IOException, InterruptedException {
+ // Register listeners with zk
+ zookeeper.registerListener(rootRegionTracker);
+ zookeeper.registerListener(metaNodeTracker);
+ // Start root tracking
+ rootRegionTracker.start();
+ // Determine meta assignment; may not work because root and meta not yet
+ // deployed.
+ getMetaServerConnection(true);
+ }
+
+ /**
+ * Gets the current location for <code>-ROOT-</code> or null if location is
+ * not currently available.
+ * @return location of root, null if not available
+ * @throws InterruptedException
+ */
+ public HServerAddress getRootLocation() throws InterruptedException {
+ return this.rootRegionTracker.getRootRegionLocation();
+ }
+
+ /**
+ * @return Location of meta or null if not yet available.
+ */
+ public HServerAddress getMetaLocation() {
+ return this.metaLocation;
+ }
+
+ /**
+ * Waits indefinitely for availability of <code>-ROOT-</code>. Used during
+ * cluster startup.
+ * @throws InterruptedException if interrupted while waiting
+ */
+ public void waitForRoot()
+ throws InterruptedException {
+ rootRegionTracker.getRootRegionLocation();
+ }
+
+ /**
+ * Gets the current location for <code>-ROOT-</code> if available and waits
+ * for up to the specified timeout if not immediately available. Returns null
+ * if the timeout elapses before root is available.
+ * @param timeout maximum time to wait for root availability, in milliseconds
+ * @return location of root
+ * @throws InterruptedException if interrupted while waiting
+ * @throws NotAllMetaRegionsOnlineException if root not available before
+ * timeout
+ */
+ public HServerAddress waitForRoot(final long timeout)
+ throws InterruptedException, NotAllMetaRegionsOnlineException {
+ HServerAddress address = rootRegionTracker.waitRootRegionLocation(timeout);
+ if (address == null) {
+ throw new NotAllMetaRegionsOnlineException("Timed out; " + timeout + "ms");
+ }
+ return address;
+ }
+
+ /**
+ * Gets a connection to the server hosting root, as reported by ZooKeeper,
+ * waiting up to the specified timeout for availability.
+ * @see #waitForRoot(long) for additional information
+ * @return connection to server hosting root
+ * @throws InterruptedException
+ * @throws NotAllMetaRegionsOnlineException if timed out waiting
+ * @throws IOException
+ */
+ public HRegionInterface waitForRootServerConnection(long timeout)
+ throws InterruptedException, NotAllMetaRegionsOnlineException, IOException {
+ return getCachedConnection(waitForRoot(timeout));
+ }
+
+ /**
+ * Gets a connection to the server hosting root, as reported by ZooKeeper,
+ * waiting for the default timeout specified on instantiation.
+ * @see #waitForRoot(long) for additional information
+ * @return connection to server hosting root
+ * @throws NotAllMetaRegionsOnlineException if timed out waiting
+ * @throws IOException
+ */
+ public HRegionInterface waitForRootServerConnectionDefault()
+ throws NotAllMetaRegionsOnlineException, IOException {
+ try {
+ return getCachedConnection(waitForRoot(defaultTimeout));
+ } catch (InterruptedException e) {
+ throw new NotAllMetaRegionsOnlineException("Interrupted");
+ }
+ }
+
+ /**
+ * Gets a connection to the server hosting root, as reported by ZooKeeper,
+ * if available. Returns null if no location is immediately available.
+ * @return connection to server hosting root, null if not available
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private HRegionInterface getRootServerConnection()
+ throws IOException, InterruptedException {
+ HServerAddress address = rootRegionTracker.getRootRegionLocation();
+ if (address == null) {
+ return null;
+ }
+ return getCachedConnection(address);
+ }
+
+ /**
+ * Gets a connection to the server currently hosting <code>.META.</code> or
+ * null if location is not currently available.
+ * <p>
+ * If a location is known, a connection to the cached location is returned.
+ * If refresh is true, the cached connection is verified first before
+ * returning. If the connection is not valid, it is reset and rechecked.
+ * <p>
+ * If no location for meta is currently known, method checks ROOT for a new
+ * location, verifies META is currently there, and returns a cached connection
+ * to the server hosting META.
+ *
+ * @return connection to server hosting meta, null if location not available
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private HRegionInterface getMetaServerConnection(boolean refresh)
+ throws IOException, InterruptedException {
+ synchronized(metaAvailable) {
+ if(metaAvailable.get()) {
+ HRegionInterface current = getCachedConnection(metaLocation);
+ if(!refresh) {
+ return current;
+ }
+ if(verifyRegionLocation(current, META_REGION)) {
+ return current;
+ }
+ resetMetaLocation();
+ }
+ HRegionInterface rootConnection = getRootServerConnection();
+ if(rootConnection == null) {
+ return null;
+ }
+ HServerAddress newLocation = MetaReader.readMetaLocation(rootConnection);
+ if(newLocation == null) {
+ return null;
+ }
+ HRegionInterface newConnection = getCachedConnection(newLocation);
+ if(verifyRegionLocation(newConnection, META_REGION)) {
+ setMetaLocation(newLocation);
+ return newConnection;
+ }
+ return null;
+ }
+ }
+
+ /**
+ * Waits indefinitely for availability of <code>.META.</code>. Used during
+ * cluster startup.
+ * @throws InterruptedException if interrupted while waiting
+ */
+ public void waitForMeta() throws InterruptedException {
+ synchronized(metaAvailable) {
+ while(!metaAvailable.get()) {
+ metaAvailable.wait();
+ }
+ }
+ }
+
+ /**
+ * Gets the current location for <code>.META.</code> if available and waits
+ * for up to the specified timeout if not immediately available. Throws an
+ * exception if timed out waiting.
+ * @param timeout maximum time to wait for meta availability, in milliseconds
+ * @return location of meta
+ * @throws InterruptedException if interrupted while waiting
+ * @throws IOException unexpected exception connecting to meta server
+ * @throws NotAllMetaRegionsOnlineException if meta not available before
+ * timeout
+ */
+ public HServerAddress waitForMeta(long timeout)
+ throws InterruptedException, IOException, NotAllMetaRegionsOnlineException {
+ long stop = System.currentTimeMillis() + timeout;
+ synchronized(metaAvailable) {
+ if(getMetaServerConnection(true) != null) {
+ return metaLocation;
+ }
+ while(!metaAvailable.get() &&
+ (timeout == 0 || System.currentTimeMillis() < stop)) {
+ metaAvailable.wait(timeout);
+ }
+ if(getMetaServerConnection(true) == null) {
+ throw new NotAllMetaRegionsOnlineException(
+ "Timed out (" + timeout + "ms");
+ }
+ return metaLocation;
+ }
+ }
+
+ /**
+ * Gets a connection to the server hosting meta, as reported by ZooKeeper,
+ * waiting up to the specified timeout for availability.
+ * @see #waitForMeta(long) for additional information
+ * @return connection to server hosting meta
+ * @throws InterruptedException
+ * @throws NotAllMetaRegionsOnlineException if timed out waiting
+ * @throws IOException
+ */
+ public HRegionInterface waitForMetaServerConnection(long timeout)
+ throws InterruptedException, NotAllMetaRegionsOnlineException, IOException {
+ return getCachedConnection(waitForMeta(timeout));
+ }
+
+ /**
+ * Gets a connection to the server hosting meta, as reported by ZooKeeper,
+ * waiting up to the specified timeout for availability.
+ * @see #waitForMeta(long) for additional information
+ * @return connection to server hosting meta
+ * @throws NotAllMetaRegionsOnlineException if timed out or interrupted
+ * @throws IOException
+ */
+ public HRegionInterface waitForMetaServerConnectionDefault()
+ throws NotAllMetaRegionsOnlineException, IOException {
+ try {
+ return getCachedConnection(waitForMeta(defaultTimeout));
+ } catch (InterruptedException e) {
+ throw new NotAllMetaRegionsOnlineException("Interrupted");
+ }
+ }
+
+ private void resetMetaLocation() {
+ LOG.info("Current cached META location is not valid, resetting");
+ metaAvailable.set(false);
+ metaLocation = null;
+ }
+
+ private void setMetaLocation(HServerAddress metaLocation) {
+ LOG.info("Found new META location, " + metaLocation);
+ metaAvailable.set(true);
+ this.metaLocation = metaLocation;
+ // no synchronization because these are private and already under lock
+ metaAvailable.notifyAll();
+ }
+
+ private HRegionInterface getCachedConnection(HServerAddress address)
+ throws IOException {
+ HRegionInterface protocol = null;
+ try {
+ protocol = connection.getHRegionConnection(address, false);
+ } catch (RetriesExhaustedException e) {
+ if (e.getCause() != null && e.getCause() instanceof ConnectException) {
+ // Catch this; presume it means the cached connection has gone bad.
+ } else {
+ throw e;
+ }
+ }
+ return protocol;
+ }
+
+ private boolean verifyRegionLocation(HRegionInterface metaServer,
+ byte [] regionName) {
+ try {
+ return metaServer.getRegionInfo(regionName) != null;
+ } catch (NotServingRegionException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Check if <code>hsi</code> was carrying <code>-ROOT-</code> or
+ * <code>.META.</code> and if so, clear out old locations.
+ * @param hsi Server that has crashed/shutdown.
+ * @throws InterruptedException
+ * @throws KeeperException
+ * @return Pair of booleans; if this server was carrying root, then first
+ * boolean is set, if server was carrying meta, then second boolean set.
+ */
+ public Pair<Boolean, Boolean> processServerShutdown(final HServerInfo hsi)
+ throws InterruptedException, KeeperException {
+ Pair<Boolean, Boolean> result = new Pair<Boolean, Boolean>(false, false);
+ HServerAddress rootHsa = getRootLocation();
+ if (rootHsa == null) {
+ LOG.info("-ROOT- is not assigned; continuing");
+ } else if (hsi.getServerAddress().equals(rootHsa)) {
+ result.setFirst(true);
+ LOG.info(hsi.getServerName() + " carrying -ROOT-; deleting " +
+ "-ROOT- location from meta");
+ RootLocationEditor.deleteRootLocation(this.zookeeper);
+ }
+ HServerAddress metaHsa = getMetaLocation();
+ if (metaHsa == null) {
+ LOG.info(".META. is not assigned; continuing");
+ } else if (hsi.getServerAddress().equals(metaHsa)) {
+ LOG.info(hsi.getServerName() + " carrying .META.; unsetting " +
+ ".META. location");
+ result.setSecond(true);
+ resetMetaLocation();
+ }
+ return result;
+ }
+}
\ No newline at end of file
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java?rev=991397&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaEditor.java Tue Aug 31 23:51:44 2010
@@ -0,0 +1,215 @@
+/**
+ * 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.catalog;
+
+import java.io.IOException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HServerInfo;
+import org.apache.hadoop.hbase.NotAllMetaRegionsOnlineException;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.ipc.HRegionInterface;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Writables;
+
+/**
+ * Writes region and assignment information to <code>.META.</code>.
+ * <p>
+ * Uses the {@link CatalogTracker} to obtain locations and connections to
+ * catalogs.
+ */
+public class MetaEditor {
+ private static final Log LOG = LogFactory.getLog(MetaEditor.class);
+
+ /**
+ * Adds a META row for the specified new region.
+ * @param info region information
+ * @throws IOException if problem connecting or updating meta
+ */
+ public static void addRegionToMeta(CatalogTracker catalogTracker,
+ HRegionInfo regionInfo)
+ throws IOException {
+ Put put = new Put(regionInfo.getRegionName());
+ put.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
+ Writables.getBytes(regionInfo));
+ catalogTracker.waitForMetaServerConnectionDefault().put(
+ CatalogTracker.META_REGION, put);
+ LOG.info("Added region " + regionInfo.getRegionNameAsString() + " to META");
+ }
+
+ /**
+ * Offline parent in meta.
+ * Used when splitting.
+ * @param catalogTracker
+ * @param parent
+ * @param a Split daughter region A
+ * @param b Split daughter region B
+ * @throws NotAllMetaRegionsOnlineException
+ * @throws IOException
+ */
+ public static void offlineParentInMeta(CatalogTracker catalogTracker,
+ HRegionInfo parent, final HRegionInfo a, final HRegionInfo b)
+ throws NotAllMetaRegionsOnlineException, IOException {
+ HRegionInfo copyOfParent = new HRegionInfo(parent);
+ copyOfParent.setOffline(true);
+ copyOfParent.setSplit(true);
+ Put put = new Put(copyOfParent.getRegionName());
+ addRegionInfo(put, copyOfParent);
+ put.add(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER,
+ HConstants.EMPTY_BYTE_ARRAY);
+ put.add(HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER,
+ HConstants.EMPTY_BYTE_ARRAY);
+ put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER,
+ Writables.getBytes(a));
+ put.add(HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER,
+ Writables.getBytes(b));
+ catalogTracker.waitForMetaServerConnectionDefault().put(CatalogTracker.META_REGION, put);
+ LOG.info("Offlined parent region " + parent.getRegionNameAsString() +
+ " in META");
+ }
+
+ public static void addDaughter(final CatalogTracker catalogTracker,
+ final HRegionInfo regionInfo, final HServerInfo serverInfo)
+ throws NotAllMetaRegionsOnlineException, IOException {
+ HRegionInterface server = catalogTracker.waitForMetaServerConnectionDefault();
+ byte [] catalogRegionName = CatalogTracker.META_REGION;
+ Put put = new Put(regionInfo.getRegionName());
+ addRegionInfo(put, regionInfo);
+ if (serverInfo != null) addLocation(put, serverInfo);
+ server.put(catalogRegionName, put);
+ LOG.info("Added daughter " + regionInfo.getRegionNameAsString() +
+ " in region " + Bytes.toString(catalogRegionName) + " with " +
+ "server=" + serverInfo.getHostnamePort() + ", " +
+ "startcode=" + serverInfo.getStartCode());
+ }
+
+ /**
+ * Updates the location of the specified META region in ROOT to be the
+ * specified server hostname and startcode.
+ * <p>
+ * Uses passed catalog tracker to get a connection to the server hosting
+ * ROOT and makes edits to that region.
+ *
+ * @param catalogTracker catalog tracker
+ * @param regionInfo region to update location of
+ * @param serverInfo server the region is located on
+ * @throws IOException
+ */
+ public static void updateMetaLocation(CatalogTracker catalogTracker,
+ HRegionInfo regionInfo, HServerInfo serverInfo)
+ throws IOException {
+ HRegionInterface server = catalogTracker.waitForRootServerConnectionDefault();
+ updateLocation(server, CatalogTracker.ROOT_REGION, regionInfo, serverInfo);
+ }
+
+ /**
+ * Updates the location of the specified region in META to be the specified
+ * server hostname and startcode.
+ * <p>
+ * Uses passed catalog tracker to get a connection to the server hosting
+ * META and makes edits to that region.
+ *
+ * @param catalogTracker catalog tracker
+ * @param regionInfo region to update location of
+ * @param serverInfo server the region is located on
+ * @throws IOException
+ */
+ public static void updateRegionLocation(CatalogTracker catalogTracker,
+ HRegionInfo regionInfo, HServerInfo serverInfo)
+ throws IOException {
+ updateLocation(catalogTracker.waitForMetaServerConnectionDefault(),
+ CatalogTracker.META_REGION, regionInfo, serverInfo);
+ }
+
+ /**
+ * Updates the location of the specified region to be the specified server.
+ * <p>
+ * Connects to the specified server which should be hosting the specified
+ * catalog region name to perform the edit.
+ *
+ * @param server connection to server hosting catalog region
+ * @param catalogRegionName name of catalog region being updated
+ * @param regionInfo region to update location of
+ * @param serverInfo server the region is located on
+ * @throws IOException
+ */
+ public static void updateLocation(HRegionInterface server,
+ byte [] catalogRegionName, HRegionInfo regionInfo, HServerInfo serverInfo)
+ throws IOException {
+ Put put = new Put(regionInfo.getRegionName());
+ addLocation(put, serverInfo);
+ server.put(catalogRegionName, put);
+ LOG.info("Updated row " + regionInfo.getRegionNameAsString() +
+ " in region " + Bytes.toString(catalogRegionName) + " with " +
+ "server=" + serverInfo.getHostnamePort() + ", " +
+ "startcode=" + serverInfo.getStartCode());
+ }
+
+ /**
+ * Deletes the specified region from META.
+ * @param catalogTracker
+ * @param regionInfo region to be deleted from META
+ * @throws IOException
+ */
+ public static void deleteRegion(CatalogTracker catalogTracker,
+ HRegionInfo regionInfo)
+ throws IOException {
+ Delete delete = new Delete(regionInfo.getRegionName());
+ catalogTracker.waitForMetaServerConnectionDefault().delete(
+ CatalogTracker.META_REGION, delete);
+
+ LOG.info("Deleted region " + regionInfo.getRegionNameAsString() + " from META");
+ }
+
+ /**
+ * Updates the region information for the specified region in META.
+ * @param catalogTracker
+ * @param regionInfo region to be updated in META
+ * @throws IOException
+ */
+ public static void updateRegionInfo(CatalogTracker catalogTracker,
+ HRegionInfo regionInfo)
+ throws IOException {
+ Put put = new Put(regionInfo.getRegionName());
+ addRegionInfo(put, regionInfo);
+ catalogTracker.waitForMetaServerConnectionDefault().put(
+ CatalogTracker.META_REGION, put);
+ LOG.info("Updated region " + regionInfo.getRegionNameAsString() + " in META");
+ }
+
+ private static Put addRegionInfo(final Put p, final HRegionInfo hri)
+ throws IOException {
+ p.add(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
+ Writables.getBytes(hri));
+ return p;
+ }
+
+ private static Put addLocation(final Put p, final HServerInfo hsi) {
+ p.add(HConstants.CATALOG_FAMILY, HConstants.SERVER_QUALIFIER,
+ Bytes.toBytes(hsi.getHostnamePort()));
+ p.add(HConstants.CATALOG_FAMILY, HConstants.STARTCODE_QUALIFIER,
+ Bytes.toBytes(hsi.getStartCode()));
+ return p;
+ }
+}
\ No newline at end of file
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java?rev=991397&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/MetaReader.java Tue Aug 31 23:51:44 2010
@@ -0,0 +1,309 @@
+/**
+ * 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.catalog;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HRegionInfo;
+import org.apache.hadoop.hbase.HServerAddress;
+import org.apache.hadoop.hbase.HServerInfo;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.ipc.HRegionInterface;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.hadoop.hbase.util.Writables;
+
+/**
+ * Reads region and assignment information from <code>.META.</code>.
+ * <p>
+ * Uses the {@link CatalogTracker} to obtain locations and connections to
+ * catalogs.
+ */
+public class MetaReader {
+ /**
+ * Performs a full scan of <code>.META.</code>.
+ * <p>
+ * Returns a map of every region to it's currently assigned server, according
+ * to META. If the region does not have an assignment it will have a null
+ * value in the map.
+ *
+ * @return map of regions to their currently assigned server
+ * @throws IOException
+ */
+ public static Map<HRegionInfo,HServerAddress> fullScan(
+ CatalogTracker catalogTracker)
+ throws IOException {
+ HRegionInterface metaServer =
+ catalogTracker.waitForMetaServerConnectionDefault();
+ Map<HRegionInfo,HServerAddress> allRegions =
+ new TreeMap<HRegionInfo,HServerAddress>();
+ Scan scan = new Scan();
+ scan.addFamily(HConstants.CATALOG_FAMILY);
+ long scannerid = metaServer.openScanner(
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
+ try {
+ Result data;
+ while((data = metaServer.next(scannerid)) != null) {
+ if (!data.isEmpty()) {
+ Pair<HRegionInfo,HServerAddress> region =
+ metaRowToRegionPair(data);
+ allRegions.put(region.getFirst(), region.getSecond());
+ }
+ }
+ } finally {
+ metaServer.close(scannerid);
+ }
+ return allRegions;
+ }
+
+ /**
+ * Reads the location of META from ROOT.
+ * @param metaServer connection to server hosting ROOT
+ * @return location of META in ROOT, null if not available
+ * @throws IOException
+ */
+ public static HServerAddress readMetaLocation(HRegionInterface metaServer)
+ throws IOException {
+ return readLocation(metaServer, CatalogTracker.ROOT_REGION,
+ CatalogTracker.META_REGION);
+ }
+
+ /**
+ * Reads the location of the specified region from META.
+ * @param catalogTracker
+ * @param regionName region to read location of
+ * @return location of region in META, null if not available
+ * @throws IOException
+ */
+ public static HServerAddress readRegionLocation(CatalogTracker catalogTracker,
+ byte [] regionName)
+ throws IOException {
+ return readLocation(catalogTracker.waitForMetaServerConnectionDefault(),
+ CatalogTracker.META_REGION, regionName);
+ }
+
+ private static HServerAddress readLocation(HRegionInterface metaServer,
+ byte [] catalogRegionName, byte [] regionName)
+ throws IOException {
+ Result r = null;
+ try {
+ r = metaServer.get(catalogRegionName,
+ new Get(regionName).addColumn(HConstants.CATALOG_FAMILY,
+ HConstants.SERVER_QUALIFIER));
+ } catch (java.net.ConnectException e) {
+ if (e.getMessage() != null &&
+ e.getMessage().contains("Connection refused")) {
+ // Treat this exception + message as unavailable catalog table. Catch it
+ // and fall through to return a null
+ } else {
+ throw e;
+ }
+ } catch (IOException e) {
+ if (e.getCause() != null && e.getCause() instanceof IOException &&
+ e.getCause().getMessage() != null &&
+ e.getCause().getMessage().contains("Connection reset by peer")) {
+ // Treat this exception + message as unavailable catalog table. Catch it
+ // and fall through to return a null
+ } else {
+ throw e;
+ }
+ }
+ if (r == null || r.isEmpty()) {
+ return null;
+ }
+ byte [] value = r.getValue(HConstants.CATALOG_FAMILY,
+ HConstants.SERVER_QUALIFIER);
+ return new HServerAddress(Bytes.toString(value));
+ }
+
+ /**
+ * Gets the region info and assignment for the specified region from META.
+ * @param catalogTracker
+ * @param regionName
+ * @return region info and assignment from META, null if not available
+ * @throws IOException
+ */
+ public static Pair<HRegionInfo, HServerAddress> getRegion(
+ CatalogTracker catalogTracker, byte [] regionName)
+ throws IOException {
+ Get get = new Get(regionName);
+ get.addFamily(HConstants.CATALOG_FAMILY);
+ Result r = catalogTracker.waitForMetaServerConnectionDefault().get(
+ CatalogTracker.META_REGION, get);
+ if(r == null || r.isEmpty()) {
+ return null;
+ }
+ return metaRowToRegionPair(r);
+ }
+
+ public static Pair<HRegionInfo, HServerAddress> metaRowToRegionPair(
+ Result data) throws IOException {
+ HRegionInfo info = Writables.getHRegionInfo(
+ data.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER));
+ final byte[] value = data.getValue(HConstants.CATALOG_FAMILY,
+ HConstants.SERVER_QUALIFIER);
+ if (value != null && value.length > 0) {
+ HServerAddress server = new HServerAddress(Bytes.toString(value));
+ return new Pair<HRegionInfo,HServerAddress>(info, server);
+ } else {
+ return new Pair<HRegionInfo, HServerAddress>(info, null);
+ }
+ }
+
+ /**
+ * Checks if the specified table exists. Looks at the META table hosted on
+ * the specified server.
+ * @param metaServer server hosting meta
+ * @param tableName table to check
+ * @return true if the table exists in meta, false if not
+ * @throws IOException
+ */
+ public static boolean tableExists(CatalogTracker catalogTracker,
+ String tableName)
+ throws IOException {
+ HRegionInterface metaServer =
+ catalogTracker.waitForMetaServerConnectionDefault();
+ byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
+ Scan scan = new Scan(firstRowInTable);
+ scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+ long scannerid = metaServer.openScanner(
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
+ try {
+ Result data = metaServer.next(scannerid);
+ if (data != null && data.size() > 0) {
+ HRegionInfo info = Writables.getHRegionInfo(
+ data.getValue(HConstants.CATALOG_FAMILY,
+ HConstants.REGIONINFO_QUALIFIER));
+ if (info.getTableDesc().getNameAsString().equals(tableName)) {
+ // A region for this table already exists. Ergo table exists.
+ return true;
+ }
+ }
+ return false;
+ } finally {
+ metaServer.close(scannerid);
+ }
+ }
+
+ /**
+ * Gets all of the regions of the specified table from META.
+ * @param catalogTracker
+ * @param tableName
+ * @return
+ * @throws IOException
+ */
+ public static List<HRegionInfo> getTableRegions(CatalogTracker catalogTracker,
+ byte [] tableName)
+ throws IOException {
+ HRegionInterface metaServer =
+ catalogTracker.waitForMetaServerConnectionDefault();
+ List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
+ String tableString = Bytes.toString(tableName);
+ byte[] firstRowInTable = Bytes.toBytes(tableString + ",,");
+ Scan scan = new Scan(firstRowInTable);
+ scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+ long scannerid = metaServer.openScanner(
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
+ try {
+ Result data;
+ while((data = metaServer.next(scannerid)) != null) {
+ if (data != null && data.size() > 0) {
+ HRegionInfo info = Writables.getHRegionInfo(
+ data.getValue(HConstants.CATALOG_FAMILY,
+ HConstants.REGIONINFO_QUALIFIER));
+ if (info.getTableDesc().getNameAsString().equals(tableString)) {
+ regions.add(info);
+ } else {
+ break;
+ }
+ }
+ }
+ return regions;
+ } finally {
+ metaServer.close(scannerid);
+ }
+ }
+
+ public static List<Pair<HRegionInfo, HServerAddress>>
+ getTableRegionsAndLocations(CatalogTracker catalogTracker, String tableName)
+ throws IOException {
+ HRegionInterface metaServer =
+ catalogTracker.waitForMetaServerConnectionDefault();
+ List<Pair<HRegionInfo, HServerAddress>> regions =
+ new ArrayList<Pair<HRegionInfo, HServerAddress>>();
+ byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
+ Scan scan = new Scan(firstRowInTable);
+ scan.addFamily(HConstants.CATALOG_FAMILY);
+ long scannerid = metaServer.openScanner(
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
+ try {
+ Result data;
+ while((data = metaServer.next(scannerid)) != null) {
+ if (data != null && data.size() > 0) {
+ Pair<HRegionInfo, HServerAddress> region = metaRowToRegionPair(data);
+ if (region.getFirst().getTableDesc().getNameAsString().equals(
+ tableName)) {
+ regions.add(region);
+ } else {
+ break;
+ }
+ }
+ }
+ return regions;
+ } finally {
+ metaServer.close(scannerid);
+ }
+ }
+
+ public static NavigableMap<HRegionInfo, Result>
+ getServerRegions(CatalogTracker catalogTracker, final HServerInfo hsi)
+ throws IOException {
+ HRegionInterface metaServer =
+ catalogTracker.waitForMetaServerConnectionDefault();
+ NavigableMap<HRegionInfo, Result> hris = new TreeMap<HRegionInfo, Result>();
+ Scan scan = new Scan();
+ scan.addFamily(HConstants.CATALOG_FAMILY);
+ long scannerid = metaServer.openScanner(
+ HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
+ try {
+ Result result;
+ while((result = metaServer.next(scannerid)) != null) {
+ if (result != null && result.size() > 0) {
+ Pair<HRegionInfo, HServerAddress> pair = metaRowToRegionPair(result);
+ if (!pair.getSecond().equals(hsi.getServerAddress())) continue;
+ hris.put(pair.getFirst(), result);
+ }
+ }
+ return hris;
+ } finally {
+ metaServer.close(scannerid);
+ }
+ }
+}
\ No newline at end of file
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/RootLocationEditor.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/RootLocationEditor.java?rev=991397&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/RootLocationEditor.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/catalog/RootLocationEditor.java Tue Aug 31 23:51:44 2010
@@ -0,0 +1,72 @@
+/**
+ * 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.catalog;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HServerAddress;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Makes changes to the location of <code>-ROOT-</code> in ZooKeeper.
+ */
+public class RootLocationEditor {
+ private static final Log LOG = LogFactory.getLog(RootLocationEditor.class);
+
+ /**
+ * Deletes the location of <code>-ROOT-</code> in ZooKeeper.
+ * @param zookeeper zookeeper reference
+ * @throws KeeperException unexpected zookeeper exception
+ */
+ public static void deleteRootLocation(ZooKeeperWatcher zookeeper)
+ throws KeeperException {
+ LOG.info("Unsetting ROOT region location in ZooKeeper");
+ try {
+ // Just delete the node. Don't need any watches, only we will create it.
+ ZKUtil.deleteNode(zookeeper, zookeeper.rootServerZNode);
+ } catch(KeeperException.NoNodeException nne) {
+ // Has already been deleted
+ }
+ }
+
+ /**
+ * Sets the location of <code>-ROOT-</code> in ZooKeeper to the
+ * specified server address.
+ * @param zookeeper zookeeper reference
+ * @param location server address hosting root
+ * @throws KeeperException unexpected zookeeper exception
+ */
+ public static void setRootLocation(ZooKeeperWatcher zookeeper,
+ HServerAddress location)
+ throws KeeperException {
+ LOG.info("Setting ROOT region location in ZooKeeper as " + location);
+ try {
+ ZKUtil.createAndWatch(zookeeper, zookeeper.rootServerZNode,
+ Bytes.toBytes(location.toString()));
+ } catch(KeeperException.NodeExistsException nee) {
+ LOG.debug("ROOT region location already existed, updated location");
+ ZKUtil.setData(zookeeper, zookeeper.rootServerZNode,
+ Bytes.toBytes(location.toString()));
+ }
+ }
+}
Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Action.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Action.java?rev=991397&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Action.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Action.java Tue Aug 31 23:51:44 2010
@@ -0,0 +1,100 @@
+/**
+ * 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.client;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.hadoop.hbase.io.HbaseObjectWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.io.Writable;
+
+/*
+ * A Get, Put or Delete associated with it's region. Used internally by
+ * {@link HTable::batch} to associate the action with it's region and maintain
+ * the index from the original request.
+ */
+public class Action implements Writable, Comparable {
+
+ private byte[] regionName;
+ private Row action;
+ private int originalIndex;
+ private Result result;
+
+ public Action() {
+ super();
+ }
+
+ public Action(byte[] regionName, Row action, int originalIndex) {
+ super();
+ this.regionName = regionName;
+ this.action = action;
+ this.originalIndex = originalIndex;
+ }
+
+ public byte[] getRegionName() {
+ return regionName;
+ }
+
+ public void setRegionName(byte[] regionName) {
+ this.regionName = regionName;
+ }
+
+ public Result getResult() {
+ return result;
+ }
+
+ public void setResult(Result result) {
+ this.result = result;
+ }
+
+ public Row getAction() {
+ return action;
+ }
+
+ public int getOriginalIndex() {
+ return originalIndex;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ return action.compareTo(((Action) o).getAction());
+ }
+
+ // ///////////////////////////////////////////////////////////////////////////
+ // Writable
+ // ///////////////////////////////////////////////////////////////////////////
+
+ public void write(final DataOutput out) throws IOException {
+ Bytes.writeByteArray(out, regionName);
+ HbaseObjectWritable.writeObject(out, action, Row.class, null);
+ out.writeInt(originalIndex);
+ HbaseObjectWritable.writeObject(out, result, Result.class, null);
+ }
+
+ public void readFields(final DataInput in) throws IOException {
+ this.regionName = Bytes.readByteArray(in);
+ this.action = (Row) HbaseObjectWritable.readObject(in, null);
+ this.originalIndex = in.readInt();
+ this.result = (Result) HbaseObjectWritable.readObject(in, null);
+ }
+
+}
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java?rev=991397&r1=991396&r2=991397&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/Get.java Tue Aug 31 23:51:44 2010
@@ -60,7 +60,7 @@ import java.util.TreeSet;
* <p>
* To add a filter, execute {@link #setFilter(Filter) setFilter}.
*/
-public class Get implements Writable, Row, Comparable<Row> {
+public class Get implements Writable {
private static final byte GET_VERSION = (byte)1;
private byte [] row = null;
@@ -325,11 +325,6 @@ public class Get implements Writable, Ro
return sb.toString();
}
- //Row
- public int compareTo(Row other) {
- return Bytes.compareTo(this.getRow(), other.getRow());
- }
-
//Writable
public void readFields(final DataInput in)
throws IOException {
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java?rev=991397&r1=991396&r2=991397&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java Tue Aug 31 23:51:44 2010
@@ -19,35 +19,39 @@
*/
package org.apache.hadoop.hbase.client;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.Abortable;
import org.apache.hadoop.hbase.ClusterStatus;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HRegionLocation;
+import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.RegionException;
import org.apache.hadoop.hbase.RemoteExceptionHandler;
import org.apache.hadoop.hbase.TableExistsException;
-import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.UnknownRegionException;
+import org.apache.hadoop.hbase.ZooKeeperConnectionException;
+import org.apache.hadoop.hbase.catalog.CatalogTracker;
+import org.apache.hadoop.hbase.catalog.MetaReader;
import org.apache.hadoop.hbase.ipc.HMasterInterface;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.MetaUtils;
+import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.util.Writables;
-import org.apache.hadoop.io.BooleanWritable;
-import org.apache.hadoop.io.Writable;
import org.apache.hadoop.ipc.RemoteException;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Map;
-import java.util.NavigableMap;
-
/**
* Provides an interface to manage HBase database table metadata + general
* administrative functions. Use HBaseAdmin to create, drop, list, enable and
@@ -55,27 +59,56 @@ import java.util.NavigableMap;
*
* See {@link HTable} to add, update, and delete data from an individual table.
*/
-public class HBaseAdmin {
+public class HBaseAdmin implements Abortable {
private final Log LOG = LogFactory.getLog(this.getClass().getName());
// private final HConnection connection;
final HConnection connection;
private volatile Configuration conf;
private final long pause;
private final int numRetries;
- private volatile HMasterInterface master;
+ /**
+ * Lazily instantiated. Use {@link #getCatalogTracker()} to ensure you get
+ * an instance rather than a null.
+ */
+ private CatalogTracker catalogTracker = null;
/**
* Constructor
*
* @param conf Configuration object
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
- public HBaseAdmin(Configuration conf) throws MasterNotRunningException {
+ public HBaseAdmin(Configuration conf)
+ throws MasterNotRunningException, ZooKeeperConnectionException {
this.connection = HConnectionManager.getConnection(conf);
this.conf = conf;
this.pause = conf.getLong("hbase.client.pause", 30 * 1000);
this.numRetries = conf.getInt("hbase.client.retries.number", 5);
- this.master = connection.getMaster();
+ this.connection.getMaster();
+ }
+
+ private synchronized CatalogTracker getCatalogTracker()
+ throws ZooKeeperConnectionException, IOException {
+ if (this.catalogTracker == null) {
+ this.catalogTracker = new CatalogTracker(this.connection.getZooKeeperWatcher(),
+ ServerConnectionManager.getConnection(conf), this,
+ this.conf.getInt("hbase.admin.catalog.timeout", 10 * 1000));
+ try {
+ this.catalogTracker.start();
+ } catch (InterruptedException e) {
+ // Let it out as an IOE for now until we redo all so tolerate IEs
+ Thread.currentThread().interrupt();
+ throw new IOException("Interrupted", e);
+ }
+ }
+ return this.catalogTracker;
+ }
+
+ @Override
+ public void abort(String why, Throwable e) {
+ // Currently does nothing but throw the passed message and exception
+ throw new RuntimeException(why, e);
}
/** @return HConnection used by this object. */
@@ -84,15 +117,21 @@ public class HBaseAdmin {
}
/**
+ * Get a connection to the currently set master.
* @return proxy connection to master server for this instance
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
- public HMasterInterface getMaster() throws MasterNotRunningException{
+ public HMasterInterface getMaster()
+ throws MasterNotRunningException, ZooKeeperConnectionException {
return this.connection.getMaster();
}
- /** @return - true if the master server is running */
- public boolean isMasterRunning() {
+ /** @return - true if the master server is running
+ * @throws ZooKeeperConnectionException
+ * @throws MasterNotRunningException */
+ public boolean isMasterRunning()
+ throws MasterNotRunningException, ZooKeeperConnectionException {
return this.connection.isMasterRunning();
}
@@ -100,9 +139,10 @@ public class HBaseAdmin {
* @param tableName Table to check.
* @return True if table exists already.
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
public boolean tableExists(final String tableName)
- throws MasterNotRunningException {
+ throws MasterNotRunningException, ZooKeeperConnectionException {
return tableExists(Bytes.toBytes(tableName));
}
@@ -110,12 +150,11 @@ public class HBaseAdmin {
* @param tableName Table to check.
* @return True if table exists already.
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
public boolean tableExists(final byte [] tableName)
- throws MasterNotRunningException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
+ throws MasterNotRunningException, ZooKeeperConnectionException {
+ connection.isMasterRunning();
return connection.tableExists(tableName);
}
@@ -147,8 +186,9 @@ public class HBaseAdmin {
private long getPauseTime(int tries) {
int triesCount = tries;
- if (triesCount >= HConstants.RETRY_BACKOFF.length)
+ if (triesCount >= HConstants.RETRY_BACKOFF.length) {
triesCount = HConstants.RETRY_BACKOFF.length - 1;
+ }
return this.pause * HConstants.RETRY_BACKOFF[triesCount];
}
@@ -257,7 +297,7 @@ public class HBaseAdmin {
try {
Thread.sleep(getPauseTime(tries));
} catch (InterruptedException e) {
- // continue
+ // Just continue; ignore the interruption.
}
}
}
@@ -277,12 +317,9 @@ public class HBaseAdmin {
*/
public void createTableAsync(HTableDescriptor desc, byte [][] splitKeys)
throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
HTableDescriptor.isLegalTableName(desc.getName());
try {
- this.master.createTable(desc, splitKeys);
+ getMaster().createTable(desc, splitKeys);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
@@ -307,13 +344,11 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void deleteTable(final byte [] tableName) throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
+ isMasterRunning();
HTableDescriptor.isLegalTableName(tableName);
HRegionLocation firstMetaServer = getFirstMetaServerForTable(tableName);
try {
- this.master.deleteTable(tableName);
+ getMaster().deleteTable(tableName);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
@@ -401,21 +436,20 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void enableTable(final byte [] tableName) throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
+ isMasterRunning();
// Wait until all regions are enabled
boolean enabled = false;
for (int tries = 0; tries < this.numRetries; tries++) {
-
try {
- this.master.enableTable(tableName);
+ getMaster().enableTable(tableName);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
enabled = isTableEnabled(tableName);
- if (enabled) break;
+ if (enabled) {
+ break;
+ }
long sleep = getPauseTime(tries);
if (LOG.isDebugEnabled()) {
LOG.debug("Sleeping= " + sleep + "ms, waiting for all regions to be " +
@@ -431,9 +465,10 @@ public class HBaseAdmin {
Bytes.toString(tableName));
}
}
- if (!enabled)
+ if (!enabled) {
throw new IOException("Unable to enable table " +
Bytes.toString(tableName));
+ }
LOG.info("Enabled table " + Bytes.toString(tableName));
}
@@ -458,20 +493,20 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void disableTable(final byte [] tableName) throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
+ isMasterRunning();
// Wait until all regions are disabled
boolean disabled = false;
for (int tries = 0; tries < this.numRetries; tries++) {
try {
- this.master.disableTable(tableName);
+ getMaster().disableTable(tableName);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
disabled = isTableDisabled(tableName);
- if (disabled) break;
+ if (disabled) {
+ break;
+ }
if (LOG.isDebugEnabled()) {
LOG.debug("Sleep. Waiting for all regions to be disabled from " +
Bytes.toString(tableName));
@@ -560,12 +595,9 @@ public class HBaseAdmin {
*/
public void addColumn(final byte [] tableName, HColumnDescriptor column)
throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
HTableDescriptor.isLegalTableName(tableName);
try {
- this.master.addColumn(tableName, column);
+ getMaster().addColumn(tableName, column);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
@@ -594,12 +626,8 @@ public class HBaseAdmin {
*/
public void deleteColumn(final byte [] tableName, final byte [] columnName)
throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
- HTableDescriptor.isLegalTableName(tableName);
try {
- this.master.deleteColumn(tableName, columnName);
+ getMaster().deleteColumn(tableName, columnName);
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
@@ -613,12 +641,25 @@ public class HBaseAdmin {
* @param columnName name of column to be modified
* @param descriptor new column descriptor to use
* @throws IOException if a remote or network exception occurs
+ * @deprecated The <code>columnName</code> is redundant. Use {@link #addColumn(String, HColumnDescriptor)}
*/
public void modifyColumn(final String tableName, final String columnName,
HColumnDescriptor descriptor)
throws IOException {
- modifyColumn(Bytes.toBytes(tableName), Bytes.toBytes(columnName),
- descriptor);
+ modifyColumn(tableName, descriptor);
+ }
+
+ /**
+ * Modify an existing column family on a table.
+ * Asynchronous operation.
+ *
+ * @param tableName name of table
+ * @param descriptor new column descriptor to use
+ * @throws IOException if a remote or network exception occurs
+ */
+ public void modifyColumn(final String tableName, HColumnDescriptor descriptor)
+ throws IOException {
+ modifyColumn(Bytes.toBytes(tableName), descriptor);
}
/**
@@ -629,56 +670,71 @@ public class HBaseAdmin {
* @param columnName name of column to be modified
* @param descriptor new column descriptor to use
* @throws IOException if a remote or network exception occurs
+ * @deprecated The <code>columnName</code> is redundant. Use {@link #modifyColumn(byte[], HColumnDescriptor)}
*/
public void modifyColumn(final byte [] tableName, final byte [] columnName,
HColumnDescriptor descriptor)
throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
- HTableDescriptor.isLegalTableName(tableName);
+ modifyColumn(tableName, descriptor);
+ }
+
+ /**
+ * Modify an existing column family on a table.
+ * Asynchronous operation.
+ *
+ * @param tableName name of table
+ * @param descriptor new column descriptor to use
+ * @throws IOException if a remote or network exception occurs
+ */
+ public void modifyColumn(final byte [] tableName, HColumnDescriptor descriptor)
+ throws IOException {
try {
- this.master.modifyColumn(tableName, columnName, descriptor);
- } catch (RemoteException e) {
- throw RemoteExceptionHandler.decodeRemoteException(e);
+ getMaster().modifyColumn(tableName, descriptor);
+ } catch (RemoteException re) {
+ // Convert RE exceptions in here; client shouldn't have to deal with them,
+ // at least w/ the type of exceptions that come out of this method:
+ // TableNotFoundException, etc.
+ throw RemoteExceptionHandler.decodeRemoteException(re);
}
}
/**
* Close a region. For expert-admins.
- * Asynchronous operation.
- *
* @param regionname region name to close
- * @param args Optional server name. Otherwise, we'll send close to the
- * server registered in .META.
+ * @param hostAndPort If supplied, we'll use this location rather than
+ * the one currently in <code>.META.</code>
* @throws IOException if a remote or network exception occurs
*/
- public void closeRegion(final String regionname, final Object... args)
+ public void closeRegion(final String regionname, final String hostAndPort)
throws IOException {
- closeRegion(Bytes.toBytes(regionname), args);
+ closeRegion(Bytes.toBytes(regionname), hostAndPort);
}
/**
* Close a region. For expert-admins.
- * Asynchronous operation.
- *
* @param regionname region name to close
- * @param args Optional server name. Otherwise, we'll send close to the
- * server registered in .META.
+ * @param hostAndPort If supplied, we'll use this location rather than
+ * the one currently in <code>.META.</code>
* @throws IOException if a remote or network exception occurs
*/
- public void closeRegion(final byte [] regionname, final Object... args)
+ public void closeRegion(final byte [] regionname, final String hostAndPort)
throws IOException {
- // Be careful. Must match the handler over in HMaster at MODIFY_CLOSE_REGION
- int len = (args == null)? 0: args.length;
- int xtraArgsCount = 1;
- Object [] newargs = new Object[len + xtraArgsCount];
- newargs[0] = regionname;
- if(args != null) {
- System.arraycopy(args, 0, newargs, xtraArgsCount, len);
+ if (hostAndPort != null) {
+ HServerAddress hsa = new HServerAddress(hostAndPort);
+ Pair<HRegionInfo, HServerAddress> pair =
+ MetaReader.getRegion(getCatalogTracker(), regionname);
+ closeRegion(hsa, pair.getFirst());
+ } else {
+ Pair<HRegionInfo, HServerAddress> pair =
+ MetaReader.getRegion(getCatalogTracker(), regionname);
+ closeRegion(pair.getSecond(), pair.getFirst());
}
- modifyTable(HConstants.META_TABLE_NAME, HConstants.Modify.CLOSE_REGION,
- newargs);
+ }
+
+ private void closeRegion(final HServerAddress hsa, final HRegionInfo hri)
+ throws IOException {
+ HRegionInterface rs = this.connection.getHRegionConnection(hsa);
+ rs.closeRegion(hri);
}
/**
@@ -700,7 +756,25 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void flush(final byte [] tableNameOrRegionName) throws IOException {
- modifyTable(tableNameOrRegionName, HConstants.Modify.TABLE_FLUSH);
+ boolean isRegionName = isRegionName(tableNameOrRegionName);
+ if (isRegionName) {
+ Pair<HRegionInfo, HServerAddress> pair =
+ MetaReader.getRegion(getCatalogTracker(), tableNameOrRegionName);
+ flush(pair.getSecond(), pair.getFirst());
+ } else {
+ List<Pair<HRegionInfo, HServerAddress>> pairs =
+ MetaReader.getTableRegionsAndLocations(getCatalogTracker(),
+ Bytes.toString(tableNameOrRegionName));
+ for (Pair<HRegionInfo, HServerAddress> pair: pairs) {
+ flush(pair.getSecond(), pair.getFirst());
+ }
+ }
+ }
+
+ private void flush(final HServerAddress hsa, final HRegionInfo hri)
+ throws IOException {
+ HRegionInterface rs = this.connection.getHRegionConnection(hsa);
+ rs.flushRegion(hri);
}
/**
@@ -722,7 +796,7 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void compact(final byte [] tableNameOrRegionName) throws IOException {
- modifyTable(tableNameOrRegionName, HConstants.Modify.TABLE_COMPACT);
+ compact(tableNameOrRegionName, false);
}
/**
@@ -746,7 +820,63 @@ public class HBaseAdmin {
*/
public void majorCompact(final byte [] tableNameOrRegionName)
throws IOException {
- modifyTable(tableNameOrRegionName, HConstants.Modify.TABLE_MAJOR_COMPACT);
+ compact(tableNameOrRegionName, true);
+ }
+
+ /**
+ * Compact a table or an individual region.
+ * Asynchronous operation.
+ *
+ * @param tableNameOrRegionName table or region to compact
+ * @param major True if we are to do a major compaction.
+ * @throws IOException if a remote or network exception occurs
+ */
+ private void compact(final byte [] tableNameOrRegionName, final boolean major)
+ throws IOException {
+ if (isRegionName(tableNameOrRegionName)) {
+ Pair<HRegionInfo, HServerAddress> pair =
+ MetaReader.getRegion(getCatalogTracker(), tableNameOrRegionName);
+ compact(pair.getSecond(), pair.getFirst(), major);
+ } else {
+ List<Pair<HRegionInfo, HServerAddress>> pairs =
+ MetaReader.getTableRegionsAndLocations(getCatalogTracker(),
+ Bytes.toString(tableNameOrRegionName));
+ for (Pair<HRegionInfo, HServerAddress> pair: pairs) {
+ compact(pair.getSecond(), pair.getFirst(), major);
+ }
+ }
+ }
+
+ private void compact(final HServerAddress hsa, final HRegionInfo hri,
+ final boolean major)
+ throws IOException {
+ HRegionInterface rs = this.connection.getHRegionConnection(hsa);
+ rs.compactRegion(hri, major);
+ }
+
+ /**
+ * Move the region <code>r</code> to <code>dest</code>.
+ * @param encodedRegionName The encoded region name.
+ * @param destServerName The servername of the destination regionserver
+ * @throws UnknownRegionException Thrown if we can't find a region named
+ * <code>encodedRegionName</code>
+ * @throws ZooKeeperConnectionException
+ * @throws MasterNotRunningException
+ */
+ public void move(final byte [] encodedRegionName, final byte [] destServerName)
+ throws UnknownRegionException, MasterNotRunningException, ZooKeeperConnectionException {
+ getMaster().move(encodedRegionName, destServerName);
+ }
+
+ /**
+ * @param b If true, enable balancer. If false, disable balancer.
+ * @return Previous balancer value
+ * @throws ZooKeeperConnectionException
+ * @throws MasterNotRunningException
+ */
+ public boolean balance(final boolean b)
+ throws MasterNotRunningException, ZooKeeperConnectionException {
+ return getMaster().balance(b);
}
/**
@@ -768,32 +898,31 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public void split(final byte [] tableNameOrRegionName) throws IOException {
- modifyTable(tableNameOrRegionName, HConstants.Modify.TABLE_SPLIT);
+ if (isRegionName(tableNameOrRegionName)) {
+ // Its a possible region name.
+ Pair<HRegionInfo, HServerAddress> pair =
+ MetaReader.getRegion(getCatalogTracker(), tableNameOrRegionName);
+ split(pair.getSecond(), pair.getFirst());
+ } else {
+ List<Pair<HRegionInfo, HServerAddress>> pairs =
+ MetaReader.getTableRegionsAndLocations(getCatalogTracker(),
+ Bytes.toString(tableNameOrRegionName));
+ for (Pair<HRegionInfo, HServerAddress> pair: pairs) {
+ split(pair.getSecond(), pair.getFirst());
+ }
+ }
}
- /*
- * Call modifyTable using passed tableName or region name String. If no
- * such table, presume we have been passed a region name.
- * @param tableNameOrRegionName
- * @param op
- * @throws IOException
- */
- private void modifyTable(final byte [] tableNameOrRegionName,
- final HConstants.Modify op)
+ private void split(final HServerAddress hsa, final HRegionInfo hri)
throws IOException {
- if (tableNameOrRegionName == null) {
- throw new IllegalArgumentException("Pass a table name or region name");
- }
- byte [] tableName = tableExists(tableNameOrRegionName)?
- tableNameOrRegionName: null;
- byte [] regionName = tableName == null? tableNameOrRegionName: null;
- Object [] args = regionName == null? null: new byte [][] {regionName};
- modifyTable(tableName == null? null: tableName, op, args);
+ HRegionInterface rs = this.connection.getHRegionConnection(hsa);
+ rs.splitRegion(hri);
}
/**
* Modify an existing table, more IRB friendly version.
- * Asynchronous operation.
+ * Asynchronous operation. This means that it may be a while before your
+ * schema change is updated across all of the table.
*
* @param tableName name of table.
* @param htd modified description of the table
@@ -801,107 +930,57 @@ public class HBaseAdmin {
*/
public void modifyTable(final byte [] tableName, HTableDescriptor htd)
throws IOException {
- modifyTable(tableName, HConstants.Modify.TABLE_SET_HTD, htd);
+ try {
+ getMaster().modifyTable(tableName, htd);
+ } catch (RemoteException re) {
+ // Convert RE exceptions in here; client shouldn't have to deal with them,
+ // at least w/ the type of exceptions that come out of this method:
+ // TableNotFoundException, etc.
+ throw RemoteExceptionHandler.decodeRemoteException(re);
+ }
}
/**
- * Modify an existing table.
- * Asynchronous operation.
- *
- * @param tableName name of table. May be null if we are operating on a
- * region.
- * @param op table modification operation
- * @param args operation specific arguments
- * @throws IOException if a remote or network exception occurs
+ * @param tableNameOrRegionName Name of a table or name of a region.
+ * @return True if <code>tableNameOrRegionName</code> is *possibly* a region
+ * name else false if a verified tablename (we call {@link #tableExists(byte[])};
+ * else we throw an exception.
+ * @throws ZooKeeperConnectionException
+ * @throws MasterNotRunningException
*/
- public void modifyTable(final byte [] tableName, HConstants.Modify op,
- Object... args)
- throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
- // Let pass if its a catalog table. Used by admins.
- if (tableName != null && !MetaUtils.isMetaTableName(tableName)) {
- // This will throw exception
- HTableDescriptor.isLegalTableName(tableName);
+ private boolean isRegionName(final byte [] tableNameOrRegionName)
+ throws MasterNotRunningException, ZooKeeperConnectionException {
+ if (tableNameOrRegionName == null) {
+ throw new IllegalArgumentException("Pass a table name or region name");
}
- Writable[] arr = null;
- try {
- switch (op) {
- case TABLE_SET_HTD:
- if (args == null || args.length < 1 ||
- !(args[0] instanceof HTableDescriptor)) {
- throw new IllegalArgumentException("SET_HTD requires a HTableDescriptor");
- }
- arr = new Writable[1];
- arr[0] = (HTableDescriptor)args[0];
- this.master.modifyTable(tableName, op, arr);
- break;
-
- case TABLE_COMPACT:
- case TABLE_SPLIT:
- case TABLE_MAJOR_COMPACT:
- case TABLE_FLUSH:
- if (args != null && args.length > 0) {
- arr = new Writable[1];
- if (args[0] instanceof byte[]) {
- arr[0] = new ImmutableBytesWritable((byte[])args[0]);
- } else if (args[0] instanceof ImmutableBytesWritable) {
- arr[0] = (ImmutableBytesWritable)args[0];
- } else if (args[0] instanceof String) {
- arr[0] = new ImmutableBytesWritable(Bytes.toBytes((String)args[0]));
- } else {
- throw new IllegalArgumentException("Requires byte[], String, or" +
- "ImmutableBytesWritable");
- }
- }
- this.master.modifyTable(tableName, op, arr);
- break;
-
- case CLOSE_REGION:
- if (args == null || args.length < 1) {
- throw new IllegalArgumentException("Requires at least a region name");
- }
- arr = new Writable[args.length];
- for (int i = 0; i < args.length; i++) {
- if (args[i] instanceof byte[]) {
- arr[i] = new ImmutableBytesWritable((byte[])args[i]);
- } else if (args[i] instanceof ImmutableBytesWritable) {
- arr[i] = (ImmutableBytesWritable)args[i];
- } else if (args[i] instanceof String) {
- arr[i] = new ImmutableBytesWritable(Bytes.toBytes((String)args[i]));
- } else if (args[i] instanceof Boolean) {
- arr[i] = new BooleanWritable((Boolean) args[i]);
- } else {
- throw new IllegalArgumentException("Requires byte [] or " +
- "ImmutableBytesWritable, not " + args[i]);
- }
- }
- this.master.modifyTable(tableName, op, arr);
- break;
+ return !tableExists(tableNameOrRegionName);
+ }
- default:
- throw new IOException("unknown modifyTable op " + op);
- }
+ /**
+ * Shuts down the HBase cluster
+ * @throws IOException if a remote or network exception occurs
+ */
+ public synchronized void shutdown() throws IOException {
+ isMasterRunning();
+ try {
+ getMaster().shutdown();
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
}
}
/**
- * Shuts down the HBase instance
+ * Shuts down the current HBase master only.
+ * Does not shutdown the cluster.
+ * @see #shutdown()
* @throws IOException if a remote or network exception occurs
*/
- public synchronized void shutdown() throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
+ public synchronized void stopMaster() throws IOException {
+ isMasterRunning();
try {
- this.master.shutdown();
+ getMaster().stopMaster();
} catch (RemoteException e) {
throw RemoteExceptionHandler.decodeRemoteException(e);
- } finally {
- this.master = null;
}
}
@@ -910,10 +989,7 @@ public class HBaseAdmin {
* @throws IOException if a remote or network exception occurs
*/
public ClusterStatus getClusterStatus() throws IOException {
- if (this.master == null) {
- throw new MasterNotRunningException("master has been shut down");
- }
- return this.master.getClusterStatus();
+ return getMaster().getClusterStatus();
}
private HRegionLocation getFirstMetaServerForTable(final byte [] tableName)
@@ -926,12 +1002,13 @@ public class HBaseAdmin {
* Check to see if HBase is running. Throw an exception if not.
*
* @param conf system configuration
- * @throws MasterNotRunningException if a remote or network exception occurs
+ * @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
public static void checkHBaseAvailable(Configuration conf)
- throws MasterNotRunningException {
+ throws MasterNotRunningException, ZooKeeperConnectionException {
Configuration copyOfConf = HBaseConfiguration.create(conf);
copyOfConf.setInt("hbase.client.retries.number", 1);
new HBaseAdmin(copyOfConf);
}
-}
+}
\ No newline at end of file
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseFsck.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseFsck.java?rev=991397&r1=991396&r2=991397&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseFsck.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HBaseFsck.java Tue Aug 31 23:51:44 2010
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.NavigableSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
@@ -42,6 +43,7 @@ import org.apache.hadoop.hbase.HServerIn
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.MasterNotRunningException;
+import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.MetaScanner.MetaScannerVisitor;
import org.apache.hadoop.hbase.ipc.HMasterInterface;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
@@ -73,9 +75,10 @@ public class HBaseFsck extends HBaseAdmi
*
* @param conf Configuration object
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
public HBaseFsck(Configuration conf)
- throws MasterNotRunningException, IOException {
+ throws MasterNotRunningException, ZooKeeperConnectionException, IOException {
super(conf);
this.conf = conf;
@@ -261,10 +264,10 @@ public class HBaseFsck extends HBaseAdmi
rsinfo.getServerAddress());
// list all online regions from this region server
- HRegionInfo[] regions = server.getRegionsAssignment();
+ NavigableSet<HRegionInfo> regions = server.getOnlineRegions();
if (details) {
System.out.print("\nRegionServer:" + rsinfo.getServerName() +
- " number of regions:" + regions.length);
+ " number of regions:" + regions.size());
for (HRegionInfo rinfo: regions) {
System.out.print("\n\t name:" + rinfo.getRegionNameAsString() +
" id:" + rinfo.getRegionId() +
Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnection.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnection.java?rev=991397&r1=991396&r2=991397&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnection.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/client/HConnection.java Tue Aug 31 23:51:44 2010
@@ -19,20 +19,21 @@
*/
package org.apache.hadoop.hbase.client;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HRegionLocation;
import org.apache.hadoop.hbase.HServerAddress;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
+import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.ipc.HMasterInterface;
import org.apache.hadoop.hbase.ipc.HRegionInterface;
-import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
/**
* Cluster connection.
@@ -40,29 +41,33 @@ import java.util.concurrent.ExecutorServ
*/
public interface HConnection {
/**
- * Retrieve ZooKeeperWrapper used by the connection.
- * @return ZooKeeperWrapper handle being used by the connection.
+ * Retrieve ZooKeeperWatcher used by the connection.
+ * @return ZooKeeperWatcher handle being used by the connection.
* @throws IOException if a remote or network exception occurs
*/
- public ZooKeeperWrapper getZooKeeperWrapper() throws IOException;
+ public ZooKeeperWatcher getZooKeeperWatcher() throws IOException;
/**
* @return proxy connection to master server for this instance
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
- public HMasterInterface getMaster() throws MasterNotRunningException;
+ public HMasterInterface getMaster()
+ throws MasterNotRunningException, ZooKeeperConnectionException;
/** @return - true if the master server is running */
- public boolean isMasterRunning();
+ public boolean isMasterRunning()
+ throws MasterNotRunningException, ZooKeeperConnectionException;
/**
* Checks if <code>tableName</code> exists.
* @param tableName Table to check.
* @return True if table exists already.
* @throws MasterNotRunningException if the master is not running
+ * @throws ZooKeeperConnectionException if unable to connect to zookeeper
*/
public boolean tableExists(final byte [] tableName)
- throws MasterNotRunningException;
+ throws MasterNotRunningException, ZooKeeperConnectionException;
/**
* A table that isTableEnabled == false and isTableDisabled == false
@@ -131,7 +136,7 @@ public interface HConnection {
* lives in, ignoring any value that might be in the cache.
* @param tableName name of the table <i>row</i> is in
* @param row row key you're trying to find the region of
- * @return HRegionLocation that describes where to find the reigon in
+ * @return HRegionLocation that describes where to find the region in
* question
* @throws IOException if a remote or network exception occurs
*/
@@ -140,6 +145,25 @@ public interface HConnection {
throws IOException;
/**
+ * Gets the location of the region of <i>regionName</i>.
+ * @param regionName name of the region to locate
+ * @return HRegionLocation that describes where to find the region in
+ * question
+ * @throws IOException if a remote or network exception occurs
+ */
+ public HRegionLocation locateRegion(final byte [] regionName)
+ throws IOException;
+
+ /**
+ * Gets the locations of all regions in the specified table, <i>tableName</i>.
+ * @param tableName table to get regions of
+ * @return list of region locations for all regions of table
+ * @throws IOException
+ */
+ public List<HRegionLocation> locateRegions(byte[] tableName)
+ throws IOException;
+
+ /**
* Establishes a connection to the region server at the specified address.
* @param regionServer - the server to connect to
* @return proxy for HRegionServer
@@ -197,21 +221,6 @@ public interface HConnection {
public <T> T getRegionServerWithoutRetries(ServerCallable<T> callable)
throws IOException, RuntimeException;
- /**
- * Process a mixed batch of Get, Put and Delete actions. All actions for a
- * RegionServer are forwarded in one RPC call.
- *
- * @param actions The collection of actions.
- * @param tableName Name of the hbase table
- * @param pool thread pool for parallel execution
- * @param results An empty array, same size as list. If an exception is thrown,
- * you can test here for partial results, and to determine which actions
- * processed successfully.
- * @throws IOException
- */
- public void processBatch(List<Row> actions, final byte[] tableName,
- ExecutorService pool, Result[] results)
- throws IOException;
/**
* Process a batch of Puts. Does the retries.
@@ -219,32 +228,20 @@ public interface HConnection {
* @param tableName The name of the table
* @return Count of committed Puts. On fault, < list.size().
* @throws IOException if a remote or network exception occurs
- * @deprecated Use HConnectionManager::processBatch instead.
*/
- public int processBatchOfRows(ArrayList<Put> list, byte[] tableName, ExecutorService pool)
+ public int processBatchOfRows(ArrayList<Put> list, byte[] tableName)
throws IOException;
/**
* Process a batch of Deletes. Does the retries.
* @param list A batch of Deletes to process.
- * @param tableName The name of the table
* @return Count of committed Deletes. On fault, < list.size().
+ * @param tableName The name of the table
* @throws IOException if a remote or network exception occurs
- * @deprecated Use HConnectionManager::processBatch instead.
*/
- public int processBatchOfDeletes(List<Delete> list, byte[] tableName, ExecutorService pool)
+ public int processBatchOfDeletes(List<Delete> list, byte[] tableName)
throws IOException;
- /**
- * Process a batch of Puts.
- *
- * @param list The collection of actions. The list is mutated: all successful Puts
- * are removed from the list.
- * @param tableName Name of the hbase table
- * @param pool Thread pool for parallel execution
- * @throws IOException
- * @deprecated Use HConnectionManager::processBatch instead.
- */
public void processBatchOfPuts(List<Put> list,
final byte[] tableName, ExecutorService pool) throws IOException;
@@ -261,7 +258,7 @@ public interface HConnection {
/**
* Check whether region cache prefetch is enabled or not.
* @param tableName name of table to check
- * @return true if table's region cache prefetch is enabled. Otherwise
+ * @return true if table's region cache prefecth is enabled. Otherwise
* it is disabled.
*/
public boolean getRegionCachePrefetch(final byte[] tableName);