Index: src/java/org/apache/hadoop/hbase/HServerLoad.java =================================================================== --- src/java/org/apache/hadoop/hbase/HServerLoad.java (revision 656281) +++ src/java/org/apache/hadoop/hbase/HServerLoad.java (working copy) @@ -70,9 +70,18 @@ /** {@inheritDoc} */ @Override public String toString() { - return "requests: " + numberOfRequests + " regions: " + numberOfRegions; + return toString(1); } + /** + * Returns toString() with the number of requests divided by the message interval in seconds + * @param msgInterval + * @return The load as a String + */ + public String toString(int msgInterval) { + return "requests: " + numberOfRequests/msgInterval + " regions: " + numberOfRegions; + } + /** {@inheritDoc} */ @Override public boolean equals(Object o) { Index: src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java =================================================================== --- src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (revision 656281) +++ src/java/org/apache/hadoop/hbase/regionserver/HRegionServer.java (working copy) @@ -1266,6 +1266,14 @@ public boolean isStopRequested() { return stopRequested.get(); } + + /** + * + * @return the configuration + */ + public HBaseConfiguration getConfiguration() { + return conf; + } /** @return the write lock for the server */ ReentrantReadWriteLock.WriteLock getWriteLock() { Index: src/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- src/java/org/apache/hadoop/hbase/master/HMaster.java (revision 656281) +++ src/java/org/apache/hadoop/hbase/master/HMaster.java (working copy) @@ -301,6 +301,11 @@ public Map getServersToLoad() { return serverManager.getServersToLoad(); } + + /** @return The average load */ + public double getAverageLoad() { + return serverManager.getAverageLoad(); + } /** * @return Location of the -ROOT- region. Index: src/java/org/apache/hadoop/hbase/HServerAddress.java =================================================================== --- src/java/org/apache/hadoop/hbase/HServerAddress.java (revision 656281) +++ src/java/org/apache/hadoop/hbase/HServerAddress.java (working copy) @@ -89,7 +89,7 @@ stringValue = bindAddress + ":" + port; } - /** @return host name */ + /** @return bind address */ public String getBindAddress() { return address.getAddress().getHostAddress(); } @@ -98,6 +98,11 @@ public int getPort() { return address.getPort(); } + + /** @return host name */ + public String getHostname() { + return address.getHostName(); + } /** @return the InetSocketAddress */ public InetSocketAddress getInetSocketAddress() { Index: src/java/org/apache/hadoop/hbase/client/HTable.java =================================================================== --- src/java/org/apache/hadoop/hbase/client/HTable.java (revision 656281) +++ src/java/org/apache/hadoop/hbase/client/HTable.java (working copy) @@ -21,6 +21,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -34,6 +35,7 @@ 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.RemoteExceptionHandler; import org.apache.hadoop.hbase.filter.RowFilterInterface; @@ -223,13 +225,76 @@ throw e; } } while (startRow.compareTo(EMPTY_START_ROW) != 0); + + return keyList.toArray(new Text[keyList.size()]); + } + + /** + * Get all the regions and their address for this table + * @return A map of HRegionInfo with it's server address + * @throws IOException + */ + @SuppressWarnings("null") + public Map getRegionsInfo() throws IOException { + // TODO This code is a near exact copy of getStartKeys. To be refactored HBASE-626 + HashMap regionMap = new HashMap(); - Text[] arr = new Text[keyList.size()]; - for (int i = 0; i < keyList.size(); i++ ){ - arr[i] = keyList.get(i); - } + long scannerId = -1L; + + Text startRow = new Text(tableName.toString() + ",,999999999999999"); + HRegionLocation metaLocation = null; + HRegionInterface server; - return arr; + // scan over the each meta region + do { + try{ + // turn the start row into a location + metaLocation = + connection.locateRegion(META_TABLE_NAME, startRow); + + // connect to the server hosting the .META. region + server = + connection.getHRegionConnection(metaLocation.getServerAddress()); + + // open a scanner over the meta region + scannerId = server.openScanner( + metaLocation.getRegionInfo().getRegionName(), + new Text[]{COL_REGIONINFO}, tableName, LATEST_TIMESTAMP, + null); + + // iterate through the scanner, accumulating regions and their regionserver + while (true) { + RowResult values = server.next(scannerId); + if (values == null || values.size() == 0) { + break; + } + + HRegionInfo info = new HRegionInfo(); + info = (HRegionInfo) Writables.getWritable( + values.get(COL_REGIONINFO).getValue(), info); + + if (!info.getTableDesc().getName().equals(this.tableName)) { + break; + } + + if (info.isOffline() || info.isSplit()) { + continue; + } + regionMap.put(info, metaLocation.getServerAddress()); + } + + // close that remote scanner + server.close(scannerId); + + // advance the startRow to the end key of the current region + startRow = metaLocation.getRegionInfo().getEndKey(); + } catch (IOException e) { + // need retry logic? + throw e; + } + } while (startRow.compareTo(EMPTY_START_ROW) != 0); + + return regionMap; } /** Index: src/webapps/regionserver/regionserver.jsp =================================================================== --- src/webapps/regionserver/regionserver.jsp (revision 656281) +++ src/webapps/regionserver/regionserver.jsp (working copy) @@ -9,6 +9,7 @@ HRegionServer regionServer = (HRegionServer)getServletContext().getAttribute(HRegionServer.REGIONSERVER); HServerInfo serverInfo = regionServer.getServerInfo(); Map onlineRegions = regionServer.getOnlineRegions(); + int interval = regionServer.getConfiguration().getInt("hbase.regionserver.msginterval", 3000)/1000; %> @@ -29,15 +30,16 @@ Attribute NameValueDescription HBase Version<%= org.apache.hadoop.hbase.util.VersionInfo.getVersion() %>, r<%= org.apache.hadoop.hbase.util.VersionInfo.getRevision() %>HBase version and svn revision HBase Compiled<%= org.apache.hadoop.hbase.util.VersionInfo.getDate() %>, <%= org.apache.hadoop.hbase.util.VersionInfo.getUser() %>When HBase version was compiled and by whom -Load<%= serverInfo.getLoad().toString() %>Requests/hbase.regionserver.msginterval + count of loaded regions +Load<%= serverInfo.getLoad().toString(interval) %>Requests per second and count of loaded regions

Online Regions

<% if (onlineRegions != null && onlineRegions.size() > 0) { %> - + <% for (HRegion r: onlineRegions.values()) { %> - + + <% } %>
Region NameStart KeyEnd Key
Region NameEncoded NameStart KeyEnd Key
<%= r.getRegionName().toString() %><%= r.getStartKey().toString() %><%= r.getEndKey().toString() %>
<%= r.getRegionName().toString() %><%= r.getRegionInfo().getEncodedName() %><%= r.getStartKey().toString() %><%= r.getEndKey().toString() %>

Region names are made of the containing table's name, a comma, Index: src/webapps/master/table.jsp =================================================================== --- src/webapps/master/table.jsp (revision 0) +++ src/webapps/master/table.jsp (revision 0) @@ -0,0 +1,74 @@ +<%@ page contentType="text/html;charset=UTF-8" + import="org.apache.hadoop.io.Text" + import="org.apache.hadoop.hbase.HTableDescriptor" + import="org.apache.hadoop.hbase.client.HTable" + import="org.apache.hadoop.hbase.HRegionInfo" + import="org.apache.hadoop.hbase.HServerAddress" + import="org.apache.hadoop.hbase.HServerInfo" + import="org.apache.hadoop.hbase.master.HMaster" + import="org.apache.hadoop.hbase.master.MetaRegion" + import="java.io.IOException" + import="java.util.Map" + import="org.apache.hadoop.hbase.HConstants"%><% + HMaster master = (HMaster)getServletContext().getAttribute(HMaster.MASTER); + String tableName = request.getParameter("name"); + HTable table = new HTable(master.getConfiguration(), new Text(tableName)); + Map serverToServerInfos = + master.getServersToServerInfo(); + String tableHeader = ""; + HServerAddress rootLocation = master.getRootRegionLocation(); +%> + + + +HBase Table : <%= tableName %> + + + + + +

Table : <%= tableName %>

+ +
+ +

Regions

+ +<%if(tableName.equals(HConstants.ROOT_TABLE_NAME.toString())) {%> +<%= tableHeader %> +<% int infoPort = serverToServerInfos.get(rootLocation.getBindAddress()+":"+rootLocation.getPort()).getInfoPort(); + String url = "http://" + rootLocation.getBindAddress() + ":" + infoPort + "/";%> + +
NameRegion ServerEncoded NameStart KeyEnd Key
<%= tableName %><%= rootLocation.getHostname() %>nilnilnil
+<%} else if(tableName.equals(HConstants.META_TABLE_NAME.toString())) { %> +<%= tableHeader %> +<% Map onlineRegions = master.getOnlineMetaRegions(); + for (MetaRegion meta: onlineRegions.values()) { + int infoPort = serverToServerInfos.get(meta.getServer().getBindAddress()+":"+meta.getServer().getPort()).getInfoPort(); + String url = "http://" + meta.getServer().getBindAddress() + ":" + infoPort + "/";%> +<%= meta.getRegionName() %><%= meta.getServer().getHostname() %>nil<%= meta.getStartKey() %>nil +<% } %> + +<%} else { %> + +<% + try { + Map regions = table.getRegionsInfo(); + if(regions != null && regions.size() > 0) { %> +<%= tableHeader %> +<% for(Map.Entry hriEntry : regions.entrySet()) { %> +<% System.out.println(serverToServerInfos.keySet().toArray()[0].toString()); + System.out.println(hriEntry.getValue().getBindAddress()+":"+hriEntry.getValue().getPort()); + int infoPort = serverToServerInfos.get(hriEntry.getValue().getBindAddress()+":"+hriEntry.getValue().getPort()).getInfoPort(); + String url = "http://" + hriEntry.getValue().getBindAddress().toString() + ":" + infoPort + "/"; %> +<%= hriEntry.getKey().getRegionName()%><%= hriEntry.getValue().getHostname() %> + <%= hriEntry.getKey().getEncodedName()%> <%= hriEntry.getKey().getStartKey()%> + <%= hriEntry.getKey().getEndKey()%> +<% } %> + +<% } + } + catch(IOException ioe) { } + }%> + + Index: src/webapps/master/master.jsp =================================================================== --- src/webapps/master/master.jsp (revision 656281) +++ src/webapps/master/master.jsp (working copy) @@ -15,13 +15,11 @@ import="org.apache.hadoop.hbase.HTableDescriptor" %><% HMaster master = (HMaster)getServletContext().getAttribute(HMaster.MASTER); HBaseConfiguration conf = master.getConfiguration(); - TableFormatter formatter = new HtmlTableFormatter(out); - ShowCommand show = new ShowCommand(out, formatter, "tables"); HServerAddress rootLocation = master.getRootRegionLocation(); Map onlineRegions = master.getOnlineMetaRegions(); Map serverToServerInfos = master.getServersToServerInfo(); - int interval = conf.getInt("hbase.regionserver.msginterval", 6000)/1000; + int interval = conf.getInt("hbase.regionserver.msginterval", 3000)/1000; %> @@ -47,54 +45,61 @@ Hadoop Compiled<%= org.apache.hadoop.util.VersionInfo.getDate() %>, <%= org.apache.hadoop.util.VersionInfo.getUser() %>When Hadoop version was compiled and by whom Filesystem<%= conf.get("fs.default.name") %>Filesystem HBase is running on HBase Root Directory<%= master.getRootDir().toString() %>Location of HBase home directory +Load average<%= master.getAverageLoad() %>Average load across all region servers. Naive computation. -

Online META Regions

-<% if (rootLocation != null) { %> +

Catalog Tables

+<% + if (rootLocation != null) { %> - - + + <% - if (onlineRegions != null && onlineRegions.size() > 0) { %> - <% for (Map.Entry e: onlineRegions.entrySet()) { - MetaRegion meta = e.getValue(); - %> - - <% } - } %> + if (onlineRegions != null && onlineRegions.size() > 0) { %> + + +<% } %>
NameServer
<%= HConstants.ROOT_TABLE_NAME.toString() %><%= rootLocation.toString() %>
TableDescription
><%= HConstants.ROOT_TABLE_NAME.toString() %>The -ROOT- table holds references to all .META. regions.
<%= meta.getRegionName().toString() %><%= meta.getServer().toString() %>
><%= HConstants.META_TABLE_NAME.toString() %>The .META. table holds references to all User Table regions
+<%} %> + +

User Tables

+<% HTableDescriptor[] tables = new HBaseAdmin(conf).listTables(); + if(tables != null && tables.length > 0) { %> + + +<% for(HTableDescriptor htDesc : tables ) { %> + +<% } %> +

<%= tables.length %> table(s) in set.

+
TableDescription
><%= htDesc.getName() %> <%= htDesc.toString() %>
<% } %> -

Tables

-<% ReturnMsg msg = show.execute(conf); %> -

<%=msg %>

-

Region Servers

<% if (serverToServerInfos != null && serverToServerInfos.size() > 0) { %> -<% int totalRegions = 0; - int totalRequests = 0; +<% int totalRegions = 0; + int totalRequests = 0; %> - -<% for (Map.Entry e: serverToServerInfos.entrySet()) { - HServerInfo hsi = e.getValue(); +<% String[] serverNames = serverToServerInfos.keySet().toArray(new String[serverToServerInfos.size()]); + Arrays.sort(serverNames); + for (String serverName: serverNames) { + HServerInfo hsi = serverToServerInfos.get(serverName); String url = "http://" + hsi.getServerAddress().getBindAddress().toString() + ":" + hsi.getInfoPort() + "/"; - String load = hsi.getLoad().toString(); + String hostname = hsi.getServerAddress().getHostname(); totalRegions += hsi.getLoad().getNumberOfRegions(); - totalRequests += hsi.getLoad().getNumberOfRequests(); + totalRequests += hsi.getLoad().getNumberOfRequests() / interval; long startCode = hsi.getStartCode(); - String address = hsi.getServerAddress().toString(); %> - + <% } %>
>AddressStart CodeLoad
<%= address %><%= startCode %><%= load %>
<%= hostname %><%= startCode %><%= hsi.getLoad().toString(interval) %>
Total: servers: <%= serverToServerInfos.size() %> requests: <%= totalRequests %> regions: <%= totalRegions %>
-

Load is requests per hbase.regionsserver.msginterval (<%=interval%> second(s)) and count of regions loaded

+

Load is requests per second and count of regions loaded

<% } %> Index: src/webapps/master/WEB-INF/web.xml =================================================================== --- src/webapps/master/WEB-INF/web.xml (revision 656281) +++ src/webapps/master/WEB-INF/web.xml (working copy) @@ -19,6 +19,11 @@ org.apache.hadoop.hbase.generated.master.master_jsp + + org.apache.hadoop.hbase.generated.master.table_jsp + org.apache.hadoop.hbase.generated.master.table_jsp + + org.apache.hadoop.hbase.generated.master.hql_jsp /hql.jsp @@ -29,5 +34,10 @@ /master.jsp + + org.apache.hadoop.hbase.generated.master.table_jsp + /table.jsp + +