diff --git a/src/java/org/apache/hadoop/hbase/master/HMaster.java b/src/java/org/apache/hadoop/hbase/master/HMaster.java index 9dbac0f..5295e68 100644 --- a/src/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/src/java/org/apache/hadoop/hbase/master/HMaster.java @@ -309,6 +309,10 @@ public class HMaster extends Thread implements HConstants, HMasterInterface, return serverManager.getServersToServerInfo(); } + public Map getServerAddressToServerInfo() { + return serverManager.getServerAddressToServerInfo(); + } + /** * @return Read-only map of servers to load. */ diff --git a/src/java/org/apache/hadoop/hbase/master/ServerManager.java b/src/java/org/apache/hadoop/hbase/master/ServerManager.java index d00a395..ef5181b 100644 --- a/src/java/org/apache/hadoop/hbase/master/ServerManager.java +++ b/src/java/org/apache/hadoop/hbase/master/ServerManager.java @@ -68,6 +68,9 @@ class ServerManager implements HConstants { /** The map of known server names to server info */ final Map serversToServerInfo = new ConcurrentHashMap(); + + final Map serverAddressToServerInfo = + new ConcurrentHashMap(); /** * Set of known dead servers. On znode expiration, servers are added here. @@ -123,7 +126,7 @@ class ServerManager implements HConstants { deadServers.contains(serverName)) { throw new Leases.LeaseStillHeldException(serverName); } - Watcher watcher = new ServerExpirer(serverName); + Watcher watcher = new ServerExpirer(serverName, info.getServerAddress()); zooKeeperWrapper.updateRSLocationGetWatch(info, watcher); LOG.info("Received start message from: " + serverName); @@ -161,6 +164,7 @@ class ServerManager implements HConstants { load = new HServerLoad(); info.setLoad(load); serversToServerInfo.put(serverName, info); + serverAddressToServerInfo.put(info.getServerAddress(), info); serversToLoad.put(serverName, load); synchronized (loadToServers) { Set servers = loadToServers.get(load); @@ -255,7 +259,7 @@ class ServerManager implements HConstants { } synchronized (serversToServerInfo) { - removeServerInfo(info.getServerName()); + removeServerInfo(info.getServerName(), info.getServerAddress()); serversToServerInfo.notifyAll(); } @@ -270,7 +274,8 @@ class ServerManager implements HConstants { synchronized (serversToServerInfo) { try { // HRegionServer is shutting down. - if (removeServerInfo(serverInfo.getServerName())) { + if (removeServerInfo(serverInfo.getServerName(), + serverInfo.getServerAddress())) { // Only process the exit message if the server still has registered info. // Otherwise we could end up processing the server exit twice. LOG.info("Region server " + serverInfo.getServerName() + @@ -320,6 +325,7 @@ class ServerManager implements HConstants { throws IOException { // Refresh the info object and the load information + serverAddressToServerInfo.put(serverInfo.getServerAddress(), serverInfo); serversToServerInfo.put(serverInfo.getServerName(), serverInfo); HServerLoad load = serversToLoad.get(serverInfo.getServerName()); @@ -567,8 +573,10 @@ class ServerManager implements HConstants { } /** Update a server load information because it's shutting down*/ - private boolean removeServerInfo(final String serverName) { + private boolean removeServerInfo(final String serverName, + final HServerAddress serverAddress) { boolean infoUpdated = false; + serverAddressToServerInfo.remove(serverAddress); HServerInfo info = serversToServerInfo.remove(serverName); // Only update load information once. // This method can be called a couple of times during shutdown. @@ -645,6 +653,13 @@ class ServerManager implements HConstants { } } + public Map getServerAddressToServerInfo() { + // we use this one because all the puts to this map are parallel/synced with the other map. + synchronized (serversToServerInfo) { + return Collections.unmodifiableMap(serverAddressToServerInfo); + } + } + /** * @return Read-only map of servers to load. */ @@ -691,15 +706,18 @@ class ServerManager implements HConstants { /** Watcher triggered when a RS znode is deleted */ private class ServerExpirer implements Watcher { private String server; + private HServerAddress serverAddress; - ServerExpirer(String server) { + ServerExpirer(String server, HServerAddress serverAddress) { this.server = server; + this.serverAddress = serverAddress; } public void process(WatchedEvent event) { if(event.getType().equals(EventType.NodeDeleted)) { LOG.info(server + " znode expired"); // Remove the server from the known servers list and update load info + serverAddressToServerInfo.remove(serverAddress); HServerInfo info = serversToServerInfo.remove(server); boolean rootServer = false; if (info != null) { diff --git a/src/webapps/master/table.jsp b/src/webapps/master/table.jsp index 1edefea..7632740 100644 --- a/src/webapps/master/table.jsp +++ b/src/webapps/master/table.jsp @@ -20,8 +20,8 @@ HBaseAdmin hbadmin = new HBaseAdmin(conf); String tableName = request.getParameter("name"); HTable table = new HTable(conf, tableName); - Map serverToServerInfos = - master.getServersToServerInfo(); + Map serverAddressToServerInfos = + master.getServerAddressToServerInfo(); String tableHeader = "

Table Regions

"; HServerAddress rootLocation = master.getRootRegionLocation(); %> @@ -32,9 +32,9 @@ <% -String action = request.getParameter("action"); -String key = request.getParameter("key"); -if ( action != null ) { + String action = request.getParameter("action"); + String key = request.getParameter("key"); + if ( action != null ) { %> @@ -80,49 +80,76 @@ if ( action != null ) {

Table: <%= tableName %>


-<%if(tableName.equals(Bytes.toString(HConstants.ROOT_TABLE_NAME))) {%> +<% + if(tableName.equals(Bytes.toString(HConstants.ROOT_TABLE_NAME))) { +%> <%= tableHeader %> -<% int infoPort = serverToServerInfos.get(rootLocation.getBindAddress()+":"+rootLocation.getPort()).getInfoPort(); - String url = "http://" + rootLocation.getHostname() + ":" + infoPort + "/";%> - +<% + int infoPort = serverAddressToServerInfos.get(rootLocation).getInfoPort(); + String url = "http://" + rootLocation.getHostname() + ":" + infoPort + "/"; +%> + + + + + + +
NameRegion ServerEncoded NameStart KeyEnd Key
<%= tableName %><%= rootLocation.getHostname() %>:<%= rootLocation.getPort() %>--
<%= tableName %><%= rootLocation.getHostname() %>:<%= rootLocation.getPort() %>--
-<%} else if(tableName.equals(Bytes.toString(HConstants.META_TABLE_NAME))) { %> +<% + } else if(tableName.equals(Bytes.toString(HConstants.META_TABLE_NAME))) { +%> <%= 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().getHostname() + ":" + infoPort + "/";%> -<%= Bytes.toString(meta.getRegionName()) %> - <%= meta.getServer().getHostname() %>:<%= meta.getServer().getPort() %> - -<%= Bytes.toString(meta.getStartKey()) %>- +<% + Map onlineRegions = master.getOnlineMetaRegions(); + for (MetaRegion meta: onlineRegions.values()) { + int infoPort = serverAddressToServerInfos.get(meta.getServer()).getInfoPort(); + String url = "http://" + meta.getServer().getHostname() + ":" + infoPort + "/"; +%> + + <%= Bytes.toString(meta.getRegionName()) %> + <%= meta.getServer().toString() %> + -<%= Bytes.toString(meta.getStartKey()) %>- + <% } %> <%} else { - try { %> + try { %>

Table Attributes

- - + +
Attribute NameValueDescription
Enabled<%= hbadmin.isTableEnabled(table.getTableName()) %>Is the table enabled
Attribute NameValueDescription
Enabled<%= hbadmin.isTableEnabled(table.getTableName()) %>Is the table enabled
-<% Map regions = table.getRegionsInfo(); - if(regions != null && regions.size() > 0) { %> +<% + Map regions = table.getRegionsInfo(); + if(regions != null && regions.size() > 0) { %> <%= tableHeader %> -<% for(Map.Entry hriEntry : regions.entrySet()) { %> -<% int infoPort = serverToServerInfos.get(hriEntry.getValue().getBindAddress()+":"+hriEntry.getValue().getPort()).getInfoPort(); - String urlRegionHistorian = "/regionhistorian.jsp?regionname="+hriEntry.getKey().getRegionNameAsString(); - String urlRegionServer = "http://" + hriEntry.getValue().getHostname().toString() + ":" + infoPort + "/"; %> -<%= hriEntry.getKey().getRegionNameAsString()%> - <%= hriEntry.getValue().getHostname() %>:<%= hriEntry.getValue().getPort() %> - <%= hriEntry.getKey().getEncodedName()%> <%= Bytes.toString(hriEntry.getKey().getStartKey())%> - <%= Bytes.toString(hriEntry.getKey().getEndKey())%> -<% } %> +<% + for(Map.Entry hriEntry : regions.entrySet()) { + + int infoPort = serverAddressToServerInfos.get( + hriEntry.getValue()).getInfoPort(); + + String urlRegionHistorian = + "/regionhistorian.jsp?regionname="+hriEntry.getKey().getRegionNameAsString(); + + String urlRegionServer = + "http://" + hriEntry.getValue().getHostname().toString() + ":" + infoPort + "/"; +%> + + <%= hriEntry.getKey().getRegionNameAsString()%> + <%= hriEntry.getValue().toString() %> + <%= hriEntry.getKey().getEncodedName()%> <%= Bytes.toString(hriEntry.getKey().getStartKey())%> + <%= Bytes.toString(hriEntry.getKey().getEndKey())%> + +<% } %> -<% } - } - catch(Exception ex) { - ex.printStackTrace(); - } - }%> +<% } +} catch(Exception ex) { + ex.printStackTrace(); +} +} // end else +%>


Actions: