diff --git a/CHANGES.txt b/CHANGES.txt index d0440db97af..af311d7e1b7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -19,6 +19,8 @@ Release 0.20.0 - Unreleased HBASE-1367 Get rid of Thrift exception 'NotFound' HBASE-1381 Remove onelab and bloom filters files from hbase HBASE-1411 Remove HLogEdit. + HBASE-1357 If one sets the hbase.master to 0.0.0.0 non local regionservers + can't find the master BUG FIXES HBASE-1140 "ant clean test" fails (Nitay Joffe via Stack) @@ -297,6 +299,7 @@ Release 0.20.0 - Unreleased HBASE-1464 Add hbase.regionserver.logroll.period to hbase-default HBASE-1192 LRU-style map for the block cache (Jon Gray and Ryan Rawson via Stack) + HBASE-1445 Add the ability to start a master from any machine OPTIMIZATIONS HBASE-1412 Change values for delete column and column family in KeyValue diff --git a/conf/hbase-default.xml b/conf/hbase-default.xml index 8649693c605..ba6817ff092 100644 --- a/conf/hbase-default.xml +++ b/conf/hbase-default.xml @@ -30,18 +30,19 @@ E.g: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR - - hbase.master.hostname - local - The host that the HBase master runs at. - A value of 'local' runs the master and regionserver in a single process. - - hbase.master.port 60000 The port master should bind to. + + hbase.cluster.distributed + false + The mode the cluster will be in. Possible values are + false: standalone and pseudo-distributed setups with managed Zookeeper + true: fully-distributed with unmanaged Zookeeper Quorum (see hbase-env.sh) + + hbase.tmp.dir /tmp/hbase-${user.name} @@ -213,6 +214,21 @@ master for communication and display purposes. + + hbase.master.dns.interface + default + The name of the Network Interface from which a master + should report its IP address. + + + + hbase.master.dns.nameserver + default + The host name or IP address of the name server (DNS) + which a master should use to determine the host name used + for communication and display purposes. + + hbase.regionserver.globalMemcache.upperLimit 0.4 diff --git a/conf/zoo.cfg b/conf/zoo.cfg index 63db592f77c..1f3ca0439ad 100644 --- a/conf/zoo.cfg +++ b/conf/zoo.cfg @@ -11,4 +11,4 @@ dataDir=${hbase.tmp.dir}/zookeeper # the port at which the clients will connect clientPort=2181 -server.0=${hbase.master.hostname}:2888:3888 \ No newline at end of file +server.0=localhost:2888:3888 diff --git a/src/java/org/apache/hadoop/hbase/HConstants.java b/src/java/org/apache/hadoop/hbase/HConstants.java index 8f51b790371..f713fbbb3bb 100644 --- a/src/java/org/apache/hadoop/hbase/HConstants.java +++ b/src/java/org/apache/hadoop/hbase/HConstants.java @@ -52,21 +52,16 @@ public interface HConstants { // Configuration parameters - // TODO: URL for hbase master like hdfs URLs with host and port. - // Like jdbc URLs? URLs could be used to refer to table cells? - // jdbc:mysql://[host][,failoverhost...][:port]/[database] - // jdbc:mysql://[host][,failoverhost...][:port]/[database][?propertyName1][=propertyValue1][&propertyName2][=propertyValue2]... + //TODO: Is having HBase homed on port 60k OK? - // Key into HBaseConfiguration for the hbase.master address. - // TODO: Support 'local': i.e. default of all running in single - // process. Same for regionserver. TODO: Is having HBase homed - // on port 60k OK? + /** Cluster is in distributed mode or not */ + static final String CLUSTER_DISTRIBUTED = "hbase.cluster.distributed"; - /** Parameter name for master address */ - static final String MASTER_ADDRESS = "hbase.master"; - - /** Parameter name for master host name. */ - static final String MASTER_HOST_NAME = "hbase.master.hostname"; + /** Cluster is standalone or pseudo-distributed */ + static final String CLUSTER_IS_LOCAL = "false"; + + /** Cluster is fully-distributed */ + static final String CLUSTER_IS_DISTRIBUTED = "true"; /** default host address */ static final String DEFAULT_HOST = "0.0.0.0"; diff --git a/src/java/org/apache/hadoop/hbase/LocalHBaseCluster.java b/src/java/org/apache/hadoop/hbase/LocalHBaseCluster.java index 363902174e9..dfdcbb1f176 100644 --- a/src/java/org/apache/hadoop/hbase/LocalHBaseCluster.java +++ b/src/java/org/apache/hadoop/hbase/LocalHBaseCluster.java @@ -90,7 +90,6 @@ public class LocalHBaseCluster implements HConstants { final int noRegionServers) throws IOException { this.conf = conf; - doLocal(conf); // Create the master this.master = new HMaster(conf); // Start the HRegionServers. Always have region servers come up on @@ -316,47 +315,13 @@ public class LocalHBaseCluster implements HConstants { } } - /** - * Changes hbase.master from 'local' to 'localhost:PORT' in - * passed Configuration instance. - * @param c - * @return The passed c configuration modified if hbase.master - * value was 'local' otherwise, unaltered. - */ - private static HBaseConfiguration doLocal(final HBaseConfiguration c) { - if (!isLocal(c)) { - return c; - } - - // Need to rewrite address in Configuration if not done already. - String address = c.get(MASTER_ADDRESS); - if (address != null) { - String port = address.startsWith(LOCAL_COLON)? - address.substring(LOCAL_COLON.length()): - Integer.toString(DEFAULT_MASTER_PORT); - c.set(MASTER_ADDRESS, "localhost:" + port); - } - - // Need to rewrite host in Configuration if not done already. - String host = c.get(MASTER_HOST_NAME); - if (host != null && host.equals(LOCAL)) { - c.set(MASTER_HOST_NAME, "localhost"); - } - - return c; - } - /** * @param c Configuration to check. * @return True if a 'local' address in hbase.master value. */ public static boolean isLocal(final Configuration c) { - String address = c.get(MASTER_ADDRESS); - boolean addressIsLocal = address == null || address.equals(LOCAL) || - address.startsWith(LOCAL_COLON); - String host = c.get(MASTER_HOST_NAME); - boolean hostIsLocal = host == null || host.equals(LOCAL); - return addressIsLocal && hostIsLocal; + String mode = c.get(CLUSTER_DISTRIBUTED); + return mode == null || mode.equals(CLUSTER_IS_LOCAL); } /** diff --git a/src/java/org/apache/hadoop/hbase/master/HMaster.java b/src/java/org/apache/hadoop/hbase/master/HMaster.java index 6e8c613e4fa..54c0ccb042e 100644 --- a/src/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/src/java/org/apache/hadoop/hbase/master/HMaster.java @@ -85,6 +85,7 @@ import org.apache.hadoop.io.MapWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Writable; import org.apache.hadoop.ipc.RemoteException; +import org.apache.hadoop.net.DNS; import org.apache.hadoop.util.StringUtils; /** @@ -161,17 +162,12 @@ public class HMaster extends Thread implements HConstants, HMasterInterface, * @throws IOException */ public HMaster(HBaseConfiguration conf) throws IOException { - // find out our address. If it's set in config, use that, otherwise look it - // up in DNS. - String addressStr = conf.get(MASTER_ADDRESS); - if (addressStr == null) { - addressStr = conf.get(MASTER_HOST_NAME); - if (addressStr == null) { - addressStr = InetAddress.getLocalHost().getCanonicalHostName(); - } - addressStr += ":"; - addressStr += conf.get("hbase.master.port", Integer.toString(DEFAULT_MASTER_PORT)); - } + // find out our address up in DNS. + String addressStr = DNS.getDefaultHost( + conf.get("hbase.master.dns.interface","default"), + conf.get("hbase.master.dns.nameserver","default")); + addressStr += ":" + + conf.get("hbase.master.port", Integer.toString(DEFAULT_MASTER_PORT)); HServerAddress address = new HServerAddress(addressStr); LOG.info("My address is " + address); @@ -531,7 +527,7 @@ public class HMaster extends Thread implements HConstants, HMasterInterface, this.connection.getHRegionConnection(address, false); HServerInfo info = hri.getHServerInfo(); LOG.debug("Inspection found server " + info.getName()); - serverManager.recordNewServer(info); + serverManager.recordNewServer(info, true); HRegionInfo[] regions = hri.getRegionsAssignment(); for (HRegionInfo region : regions) { if(region.isRootRegion()) { @@ -1075,13 +1071,7 @@ public class HMaster extends Thread implements HConstants, HMasterInterface, // Process command-line args. TODO: Better cmd-line processing // (but hopefully something not as painful as cli options). - - final String addressArgKey = "--bind="; for (String cmd: args) { - if (cmd.startsWith(addressArgKey)) { - conf.set(MASTER_ADDRESS, cmd.substring(addressArgKey.length())); - continue; - } if (cmd.equals("start")) { try { diff --git a/src/java/org/apache/hadoop/hbase/master/ServerManager.java b/src/java/org/apache/hadoop/hbase/master/ServerManager.java index ff43a4f7007..bd462f49b5e 100644 --- a/src/java/org/apache/hadoop/hbase/master/ServerManager.java +++ b/src/java/org/apache/hadoop/hbase/master/ServerManager.java @@ -194,12 +194,23 @@ class ServerManager implements HConstants { recordNewServer(info); } + /** - * Adds the HSI to the RS list + * Adds the HSI to the RS list and creates an empty load * @param info The region server informations */ public void recordNewServer(HServerInfo info) { - HServerLoad load = new HServerLoad(); + recordNewServer(info, false); + } + + /** + * Adds the HSI to the RS list + * @param info The region server informations + * @param useInfoLoad True if the load from the info should be used + * like under a master failover + */ + public void recordNewServer(HServerInfo info, boolean useInfoLoad) { + HServerLoad load = useInfoLoad ? info.getLoad() : new HServerLoad(); String serverName = HServerInfo.getServerName(info); info.setLoad(load); // We must set this watcher here because it can be set on a fresh start diff --git a/src/java/org/apache/hadoop/hbase/zookeeper/HQuorumPeer.java b/src/java/org/apache/hadoop/hbase/zookeeper/HQuorumPeer.java index 9d17b36f0b1..165e128da60 100644 --- a/src/java/org/apache/hadoop/hbase/zookeeper/HQuorumPeer.java +++ b/src/java/org/apache/hadoop/hbase/zookeeper/HQuorumPeer.java @@ -101,6 +101,7 @@ public class HQuorumPeer implements HConstants { } for (Entry entry : properties.entrySet()) { String value = entry.getValue().toString().trim(); + String key = entry.getKey().toString().trim(); StringBuilder newValue = new StringBuilder(); int varStart = value.indexOf(VARIABLE_START); int varEnd = 0; @@ -123,19 +124,24 @@ public class HQuorumPeer implements HConstants { LOG.fatal(msg); throw new IOException(msg); } - // Special case for 'hbase.master.hostname' property being 'local' - if (variable.equals(HConstants.MASTER_HOST_NAME) && substituteValue.equals("local")) { - substituteValue = "localhost"; - } + newValue.append(substituteValue); varEnd += VARIABLE_END_LENGTH; varStart = value.indexOf(VARIABLE_START, varEnd); } - + // Special case for 'hbase.cluster.distributed' property being 'true' + if (key.startsWith("server.")) { + if(conf.get(CLUSTER_DISTRIBUTED).equals(CLUSTER_IS_DISTRIBUTED) && + value.startsWith("localhost")) { + String msg = "The server in zoo.cfg cannot be set to localhost " + + "in a fully-distributed setup because it won't be reachable. " + + "See \"Getting Started\" for more information."; + LOG.fatal(msg); + throw new IOException(msg); + } + } newValue.append(value.substring(varEnd)); - - String key = entry.getKey().toString().trim(); properties.setProperty(key, newValue.toString()); } return properties; diff --git a/src/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWrapper.java b/src/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWrapper.java index 0438a0076a4..c6050ed4075 100644 --- a/src/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWrapper.java +++ b/src/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperWrapper.java @@ -152,8 +152,8 @@ public class ZooKeeperWrapper implements HConstants { try { properties = HQuorumPeer.parseZooKeeperConfig(); } catch (IOException e) { - LOG.error("fail to read properties from " + ZOOKEEPER_CONFIG_NAME); - return; + LOG.fatal("Fail to read properties from " + ZOOKEEPER_CONFIG_NAME, e); + System.exit(-1); } String clientPort = null; @@ -532,9 +532,9 @@ public class ZooKeeperWrapper implements HConstants { zooKeeper.delete(joinPath(this.rsZNode, node), -1); } } catch (KeeperException e) { - LOG.warn("Failed to delete " + rsZNode + " znode in ZooKeeper: " + e); + LOG.warn("Failed to delete " + rsZNode + " znodes in ZooKeeper: " + e); } catch (InterruptedException e) { - LOG.warn("Failed to delete " + rsZNode + " znode in ZooKeeper: " + e); + LOG.warn("Failed to delete " + rsZNode + " znodes in ZooKeeper: " + e); } } diff --git a/src/java/overview.html b/src/java/overview.html index 1652bb2b474..ce6873bb4bc 100644 --- a/src/java/overview.html +++ b/src/java/overview.html @@ -79,15 +79,9 @@ operation, continue reading.

Distributed Operation

-

Distributed mode requires an instance of the Hadoop Distributed File System (DFS) and a ZooKeeper cluster. +

Distributed mode requires an instance of the Hadoop Distributed File System (DFS). See the Hadoop requirements and instructions for how to set up a DFS. -See the ZooKeeeper Getting Started Guide -for information about the ZooKeeper distributed coordination service. -If you do not configure a ZooKeeper cluster, HBase will manage a single instance -ZooKeeper service for you running on the master node. -This is intended for development and local testing only. -It SHOULD NOT be used in a fully-distributed production operation.

Pseudo-Distributed Operation

@@ -122,21 +116,19 @@ create them if you let it). For running a fully-distributed operation on more than one host, the following configurations must be made in addition to those described in the pseudo-distributed operation section above. +A Zookeeper cluster is also required to ensure higher availability. In hbase-site.xml, you must also configure -hbase.master.hostname to the host on which the HBase master runs -(read -about the HBase master, regionservers, etc). -For example, adding the below to your hbase-site.xml says the -master is up on the host example.org: +hbase.cluster.distributed to 'true'.

 <configuration>
   ...
   <property>
-    <name>hbase.master.hostname</name>
-    <value>example.org</value>
-    <description>The host that the HBase master runs at.
-      A value of 'local' runs the master and regionserver in a single process.
+    <name>hbase.cluster.distributed</name>
+    <value>true</value>
+    <description>The mode the cluster will be in. Possible values are
+      false: standalone and pseudo-distributed setups with managed Zookeeper
+      true: fully-distributed with unmanaged Zookeeper Quorum (see hbase-env.sh)
     </description>
   </property>
   ...
@@ -151,14 +143,35 @@ operation requires that you also modify ${HBASE_HOME}/conf/regionservers${HADOOP_HOME}/conf/slaves).
 

-Furthermore, you should configure a distributed ZooKeeper cluster. +Furthermore, you have to configure a distributed ZooKeeper cluster. The ZooKeeper configuration file is stored at ${HBASE_HOME}/conf/zoo.cfg. See the ZooKeeper Getting Started Guide for information about the format and options of that file. Specifically, look at the Running Replicated ZooKeeper section. -In ${HBASE_HOME}/conf/hbase-env.sh, set HBASE_MANAGES_ZK=false to tell HBase not to manage its own single instance ZooKeeper service. +In ${HBASE_HOME}/conf/hbase-env.sh, set the following to tell HBase not to manage its own single instance of ZooKeeper. +

+  ...
+# Tell HBase whether it should manage it's own instance of Zookeeper or not.
+export HBASE_MANAGES_ZK=false
+
+

+

+It's still possible to use HBase in order to start a single Zookeeper instance in fully-distributed operation. +The first thing to do is still to change ${HBASE_HOME}/conf/zoo.cfg and set a single node. +Note that leaving the value "localhost" will make it impossible to start HBase. +

+  ...
+server.0=example.org:2888:3888
+
+Then on the example.org server do the following before running HBase. +
+${HBASE_HOME}/bin/hbase-daemon.sh start zookeeper
+
+Be aware that this option is only recommanded for testing purposes as a failure +on that node would render HBase unusable.

-

Of note, if you have made HDFS client configuration on your hadoop cluster, hbase will not + +

Of note, if you have made HDFS client configuration on your hadoop cluster, HBase will not see this configuration unless you do one of the following:

  • Add a pointer to your HADOOP_CONF_DIR to CLASSPATH in hbase-env.sh
  • @@ -167,7 +180,7 @@ see this configuration unless you do one of the following:
An example of such an HDFS client configuration is dfs.replication. If for example, you want to run with a replication factor of 5, hbase will create files with the default of 3 unless -you do the above to make the configuration available to hbase. +you do the above to make the configuration available to HBase.

Running and Confirming Your Installation

diff --git a/src/test/org/apache/hadoop/hbase/PerformanceEvaluation.java b/src/test/org/apache/hadoop/hbase/PerformanceEvaluation.java index c531fc86c61..d2952619855 100644 --- a/src/test/org/apache/hadoop/hbase/PerformanceEvaluation.java +++ b/src/test/org/apache/hadoop/hbase/PerformanceEvaluation.java @@ -767,12 +767,6 @@ public class PerformanceEvaluation implements HConstants { errCode = 0; break; } - - final String masterArgKey = "--master="; - if (cmd.startsWith(masterArgKey)) { - this.conf.set(MASTER_ADDRESS, cmd.substring(masterArgKey.length())); - continue; - } final String miniClusterArgKey = "--miniCluster"; if (cmd.startsWith(miniClusterArgKey)) {