Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  
  package org.apache.hadoop.hbase.master;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;
  
  
The ServerManager class manages info about region servers.

Maintains lists of online and dead servers. Processes the startups, shutdowns, and deaths of region servers.

Servers are distinguished in two different ways. A given server has a location, specified by hostname and port, and of which there can only be one online at any given time. A server instance is specified by the location (hostname and port) as well as the startcode (timestamp from when the server was started). This is used to differentiate a restarted instance of a given server from the original instance.

If a sever is known not to be running any more, it is called dead. The dead server needs to be handled by a ServerShutdownHandler. If the handler is not enabled yet, the server can't be handled right away so it is queued up. After the handler is enabled, the server will be submitted to a handler to handle. However, the handler may be just partially enabled. If so, the server cannot be fully processed, and be queued up for further processing. A server is fully processed only after the handler is fully enabled and has completed the handling.

  
  public class ServerManager {
    public static final String WAIT_ON_REGIONSERVERS_MAXTOSTART =
        "hbase.master.wait.on.regionservers.maxtostart";
  
    public static final String WAIT_ON_REGIONSERVERS_MINTOSTART =
       "hbase.master.wait.on.regionservers.mintostart";
 
   public static final String WAIT_ON_REGIONSERVERS_TIMEOUT =
       "hbase.master.wait.on.regionservers.timeout";
 
   public static final String WAIT_ON_REGIONSERVERS_INTERVAL =
       "hbase.master.wait.on.regionservers.interval";
 
   private static final Log LOG = LogFactory.getLog(ServerManager.class);
 
   // Set if we are to shutdown the cluster.
   private volatile boolean clusterShutdown = false;
 
   private final SortedMap<byte[], LongflushedSequenceIdByRegion =
     new ConcurrentSkipListMap<byte[], Long>(.);

  
Map of registered servers to their current load
 
     new ConcurrentHashMap<ServerNameServerLoad>();

  
Map of admin interfaces per registered regionserver; these interfaces we use to control regionservers out on the cluster
 
List of region servers <ServerName> that should not get any more new regions.
 
   private final ArrayList<ServerNamedrainingServers =
     new ArrayList<ServerName>();
 
   private final Server master;
   private final MasterServices services;
   private final HConnection connection;
 
   private final DeadServer deadservers = new DeadServer();
 
   private final long maxSkew;
   private final long warningSkew;
 
Set of region servers which are dead but not processed immediately. If one server died before master enables ServerShutdownHandler, the server will be added to this set and will be processed through calling processQueuedDeadServers() by master.

A dead server is a server instance known to be dead, not listed in the /hbase/rs znode any more. It may have not been submitted to ServerShutdownHandler yet because the handler is not enabled.

A dead server, which has been submitted to ServerShutdownHandler while the handler is not enabled, is queued up.

So this is a set of region servers known to be dead but not submitted to ServerShutdownHander for processing yet.

 
   private Set<ServerNamequeuedDeadServers = new HashSet<ServerName>();

  
Set of region servers which are dead and submitted to ServerShutdownHandler to process but not fully processed immediately.

If one server died before assignment manager finished the failover cleanup, the server will be added to this set and will be processed through calling processQueuedDeadServers() by assignment manager.

The Boolean value indicates whether log split is needed inside ServerShutdownHandler

ServerShutdownHandler processes a dead server submitted to the handler after the handler is enabled. It may not be able to complete the processing because meta is not yet online or master is currently in startup mode. In this case, the dead server will be parked in this set temporarily.

 
     = new ConcurrentHashMap<ServerNameBoolean>();

  
Listeners that are called on server events.
 
Constructor.

 
   public ServerManager(final Server masterfinal MasterServices services)
       throws IOException {
     this(masterservicestrue);
   }
 
   @SuppressWarnings("deprecation")
   ServerManager(final Server masterfinal MasterServices services,
       final boolean connectthrows IOException {
     this. = master;
     this. = services;
     Configuration c = master.getConfiguration();
      = c.getLong("hbase.master.maxclockskew", 30000);
      = c.getLong("hbase.master.warningclockskew", 10000);
     this. = connect ? HConnectionManager.getConnection(c) : null;
     int pingMaxAttempts = Math.max(1, master.getConfiguration().getInt(
       "hbase.master.maximum.ping.server.attempts", 10));
     int pingSleepInterval = Math.max(1, master.getConfiguration().getInt(
       "hbase.master.ping.server.retry.sleep.interval", 100));
     this. = new RetryCounterFactory(pingMaxAttemptspingSleepInterval);
   }

  
Add the listener to the notification list.

Parameters:
listener The ServerListener to register
 
   public void registerListener(final ServerListener listener) {
     this..add(listener);
   }

  
Remove the listener from the notification list.

Parameters:
listener The ServerListener to unregister
 
   public boolean unregisterListener(final ServerListener listener) {
     return this..remove(listener);
   }

  
Let the server manager know a new regionserver has come online

Parameters:
ia The remote address
port The remote port
serverStartcode
serverCurrentTime The current time of the region server in ms
Returns:
The ServerName we know this server as.
Throws:
java.io.IOException
 
   ServerName regionServerStartup(final InetAddress iafinal int port,
     final long serverStartcodelong serverCurrentTime)
   throws IOException {
     // Test for case where we get a region startup message from a regionserver
     // that has been quickly restarted but whose znode expiration handler has
     // not yet run, or from a server whose fail we are currently processing.
     // Test its host+port combo is present in serverAddresstoServerInfo.  If it
     // is, reject the server and trigger its expiration. The next time it comes
     // in, it should have been removed from serverAddressToServerInfo and queued
     // for processing by ProcessServerShutdown.
     ServerName sn = ServerName.valueOf(ia.getHostName(), portserverStartcode);
     checkClockSkew(snserverCurrentTime);
     checkIsDead(sn"STARTUP");
       .warn("THIS SHOULD NOT HAPPEN, RegionServerStartup"
         + " could not record the server: " + sn);
     }
     return sn;
   }

  
Updates last flushed sequence Ids for the regions on server sn

Parameters:
sn
hsl
 
   private void updateLastFlushedSequenceIds(ServerName snServerLoad hsl) {
     Map<byte[], RegionLoadregionsLoad = hsl.getRegionsLoad();
     for (Entry<byte[], RegionLoadentry : regionsLoad.entrySet()) {
       byte[] encodedRegionName = Bytes.toBytes(HRegionInfo.encodeRegionName(entry.getKey()));
       Long existingValue = .get(encodedRegionName);
       long l = entry.getValue().getCompleteSequenceId();
       if (existingValue != null) {
         if (l != -1 && l < existingValue) {
           .warn("RegionServer " + sn +
               " indicates a last flushed sequence id (" + entry.getValue() +
               ") that is less than the previous last flushed sequence id (" +
               existingValue + ") for region " +
               Bytes.toString(entry.getKey()) + " Ignoring.");
 
           continue// Don't let smaller sequence ids override greater sequence ids.
         }
       }
       .put(encodedRegionNamel);
     }
   }
 
       ServerLoad slthrows YouAreDeadException {
     checkIsDead(sn"REPORT");
     if (null == this..replace(snsl)) {
       // Already have this host+port combo and its just different start code?
       // Just let the server in. Presume master joining a running cluster.
       // recordNewServer is what happens at the end of reportServerStartup.
       // The only thing we are skipping is passing back to the regionserver
       // the ServerName to use. Here we presume a master has already done
       // that so we'll press on with whatever it gave us for ServerName.
       if (!checkAndRecordNewServer(snsl)) {
         .info("RegionServerReport ignored, could not record the server: " + sn);
         return// Not recorded, so no need to move on
       }
     }
   }

  
Check is a server of same host and port already exists, if not, or the existed one got a smaller start code, record it.

Parameters:
sn the server to check and record
sl the server load on the server
Returns:
true if the server is recorded, otherwise, false
 
       final ServerName serverNamefinal ServerLoad sl) {
     ServerName existingServer = null;
     synchronized (this.) {
       existingServer = findServerWithSameHostnamePortWithLock(serverName);
       if (existingServer != null && (existingServer.getStartcode() > serverName.getStartcode())) {
         .info("Server serverName=" + serverName + " rejected; we already have "
             + existingServer.toString() + " registered with same hostname and port");
         return false;
       }
       recordNewServerWithLock(serverNamesl);
     }
 
     // Tell our listeners that a server was added
     if (!this..isEmpty()) {
       for (ServerListener listener : this.) {
         listener.serverAdded(serverName);
       }
     }
 
     // Note that we assume that same ts means same server, and don't expire in that case.
     //  TODO: ts can theoretically collide due to clock shifts, so this is a bit hacky.
     if (existingServer != null && (existingServer.getStartcode() < serverName.getStartcode())) {
       .info("Triggering server recovery; existingServer " +
           existingServer + " looks stale, new server:" + serverName);
       expireServer(existingServer);
     }
     return true;
   }

  
Checks if the clock skew between the server and the master. If the clock skew exceeds the configured max, it will throw an exception; if it exceeds the configured warning threshold, it will log a warning but start normally.

Parameters:
serverName Incoming servers's name
serverCurrentTime
Throws:
org.apache.hadoop.hbase.ClockOutOfSyncException if the skew exceeds the configured max value
 
   private void checkClockSkew(final ServerName serverNamefinal long serverCurrentTime)
     long skew = Math.abs(System.currentTimeMillis() - serverCurrentTime);
     if (skew > ) {
       String message = "Server " + serverName + " has been " +
         "rejected; Reported time is too far out of sync with master.  " +
         "Time difference of " + skew + "ms > max allowed of " +  + "ms";
       .warn(message);
       throw new ClockOutOfSyncException(message);
     } else if (skew > ){
       String message = "Reported time for server " + serverName + " is out of sync with master " +
         "by " + skew + "ms. (Warning threshold is " +  + "ms; " +
         "error threshold is " +  + "ms)";
       .warn(message);
     }
   }

  
If this server is on the dead list, reject it with a YouAreDeadException. If it was dead but came back with a new start code, remove the old entry from the dead list.

Parameters:
serverName
what START or REPORT
Throws:
org.apache.hadoop.hbase.YouAreDeadException
 
   private void checkIsDead(final ServerName serverNamefinal String what)
       throws YouAreDeadException {
     if (this..isDeadServer(serverName)) {
       // host name, port and start code all match with existing one of the
       // dead servers. So, this server must be dead.
       String message = "Server " + what + " rejected; currently processing " +
           serverName + " as dead server";
       .debug(message);
       throw new YouAreDeadException(message);
     }
     // remove dead server with same hostname and port of newly checking in rs after master
     // initialization.See HBASE-5916 for more information.
     if ((this. == null || ((HMasterthis.).isInitialized())
         && this..cleanPreviousInstance(serverName)) {
       // This server has now become alive after we marked it as dead.
       // We removed it's previous entry from the dead list to reflect it.
       .debug(what + ":" + " Server " + serverName + " came back up," +
           " removed it from the dead servers list");
     }
   }

  
Assumes onlineServers is locked.

Returns:
ServerName with matching hostname and port.
 
       final ServerName serverName) {
     for (ServerName snthis..keySet()) {
       if (ServerName.isSameHostnameAndPort(serverNamesn)) return sn;
     }
     return null;
   }

  
Adds the onlineServers list. onlineServers should be locked.

Parameters:
serverName The remote servers name.
sl
Returns:
Server load from the removed server, if any.
 
   void recordNewServerWithLock(final ServerName serverNamefinal ServerLoad sl) {
     .info("Registering server=" + serverName);
     this..put(serverNamesl);
     this..remove(serverName);
   }
 
   public long getLastFlushedSequenceId(byte[] encodedRegionName) {
     long seqId = -1L;
     if (.containsKey(encodedRegionName)) {
       seqId = .get(encodedRegionName);
     }
     return seqId;
   }

  

Parameters:
serverName
Returns:
ServerLoad if serverName is known else null
 
   public ServerLoad getLoad(final ServerName serverName) {
     return this..get(serverName);
   }

  
Compute the average load across all region servers. Currently, this uses a very naive computation - just uses the number of regions being served, ignoring stats about number of requests.

Returns:
the average load
 
   public double getAverageLoad() {
     int totalLoad = 0;
     int numServers = 0;
     double averageLoad;
     for (ServerLoad slthis..values()) {
         numServers++;
         totalLoad += sl.getNumberOfRegions();
     }
     averageLoad = (double)totalLoad / (double)numServers;
     return averageLoad;
   }

  

Returns:
the count of active regionservers
 
   int countOfRegionServers() {
     // Presumes onlineServers is a concurrent map
     return this..size();
   }

  

Returns:
Read-only map of servers to serverinfo
 
     // Presumption is that iterating the returned Map is OK.
     synchronized (this.) {
       return Collections.unmodifiableMap(this.);
     }
   }
 
 
   public DeadServer getDeadServers() {
     return this.;
   }

  
Checks if any dead servers are currently in progress.

Returns:
true if any RS are being processed as dead, false if not
 
   public boolean areDeadServersInProgress() {
     return this..areDeadServersInProgress();
   }
 
     long previousLogTime = 0;
     int onlineServersCt;
     while ((onlineServersCt = .size()) > 0) {
 
       if (System.currentTimeMillis() > (previousLogTime + 1000)) {
         StringBuilder sb = new StringBuilder();
         // It's ok here to not sync on onlineServers - merely logging
         for (ServerName key : this..keySet()) {
           if (sb.length() > 0) {
             sb.append(", ");
           }
           sb.append(key);
         }
         .info("Waiting on regionserver(s) to go down " + sb.toString());
         previousLogTime = System.currentTimeMillis();
       }
 
       synchronized () {
         try {
           if (onlineServersCt == .size()) .wait(100);
         } catch (InterruptedException ignored) {
           // continue
         }
       }
     }
   }
 
   /*
    * Expire the passed server.  Add it to list of dead servers and queue a
    * shutdown processing.
    */
   public synchronized void expireServer(final ServerName serverName) {
       .info("Master doesn't enable ServerShutdownHandler during initialization, "
           + "delay expiring server " + serverName);
       this..add(serverName);
       return;
     }
     if (this..isDeadServer(serverName)) {
       // TODO: Can this happen?  It shouldn't be online in this case?
       .warn("Expiration of " + serverName +
           " but server shutdown already in progress");
       return;
     }
     synchronized () {
       if (!this..containsKey(serverName)) {
         .warn("Expiration of " + serverName + " but server not online");
       }
       // Remove the server from the known servers lists and update load info BUT
       // add to deadservers first; do this so it'll show in dead servers list if
       // not in online servers list.
       this..add(serverName);
       this..remove(serverName);
       .notifyAll();
     }
     this..remove(serverName);
     // If cluster is going down, yes, servers are going to be expiring; don't
     // process as a dead server
     if (this.) {
       .info("Cluster shutdown set; " + serverName +
         " expired; onlineServers=" + this..size());
       if (this..isEmpty()) {
         .stop("Cluster shutdown set; onlineServer=0");
       }
       return;
     }
 
     boolean carryingMeta = .getAssignmentManager().isCarryingMeta(serverName);
     if (carryingMeta) {
         this.this.serverName));
     } else {
         this.this.serverNametrue));
     }
     .debug("Added=" + serverName +
       " to dead servers, submitted shutdown handler to be executed meta=" + carryingMeta);
 
     // Tell our listeners that a server was removed
     if (!this..isEmpty()) {
       for (ServerListener listener : this.) {
         listener.serverRemoved(serverName);
       }
     }
   }
 
   public synchronized void processDeadServer(final ServerName serverName) {
     this.processDeadServer(serverNamefalse);
   }
 
   public synchronized void processDeadServer(final ServerName serverNameboolean shouldSplitHlog) {
     // When assignment manager is cleaning up the zookeeper nodes and rebuilding the
     // in-memory region states, region servers could be down. Meta table can and
     // should be re-assigned, log splitting can be done too. However, it is better to
     // wait till the cleanup is done before re-assigning user regions.
     //
     // We should not wait in the server shutdown handler thread since it can clog
     // the handler threads and meta table could not be re-assigned in case
     // the corresponding server is down. So we queue them up here instead.
       .put(serverNameshouldSplitHlog);
       return;
     }
 
     this..add(serverName);
       new ServerShutdownHandler(this.this.this.serverName,
           shouldSplitHlog));
   }

  
Process the servers which died during master's initialization. It will be called after HMaster#assignMeta and AssignmentManager#joinCluster.
 
   synchronized void processQueuedDeadServers() {
       .info("Master hasn't enabled ServerShutdownHandler");
     }
     Iterator<ServerNameserverIterator = .iterator();
     while (serverIterator.hasNext()) {
       ServerName tmpServerName = serverIterator.next();
       expireServer(tmpServerName);
       serverIterator.remove();
       .remove(tmpServerName);
     }
 
       .info("AssignmentManager hasn't finished failover cleanup; waiting");
     }
 
     for(ServerName tmpServerName : .keySet()){
       processDeadServer(tmpServerName.get(tmpServerName));
     }
   }
 
   /*
    * Remove the server from the drain list.
    */
   public boolean removeServerFromDrainList(final ServerName sn) {
     // Warn if the server (sn) is not online.  ServerName is of the form:
     // <hostname> , <port> , <startcode>
 
     if (!this.isServerOnline(sn)) {
       .warn("Server " + sn + " is not currently online. " +
                "Removing from draining list anyway, as requested.");
     }
     // Remove the server from the draining servers lists.
     return this..remove(sn);
   }
 
   /*
    * Add the server to the drain list.
    */
   public boolean addServerToDrainList(final ServerName sn) {
     // Warn if the server (sn) is not online.  ServerName is of the form:
     // <hostname> , <port> , <startcode>
 
     if (!this.isServerOnline(sn)) {
       .warn("Server " + sn + " is not currently online. " +
                "Ignoring request to add it to draining list.");
       return false;
     }
     // Add the server to the draining servers lists, if it's not already in
     // it.
     if (this..contains(sn)) {
       .warn("Server " + sn + " is already in the draining server list." +
                "Ignoring request to add it again.");
       return false;
     }
     return this..add(sn);
   }
 
   // RPC methods to region servers
 
  
Sends an OPEN RPC to the specified server to open the specified region.

Open should not fail but can if server just crashed.

Parameters:
server server to open a region
region region to open
versionOfOfflineNode that needs to be present in the offline node when RS tries to change the state from OFFLINE to other states.
favoredNodes
 
   public RegionOpeningState sendRegionOpen(final ServerName server,
       HRegionInfo regionint versionOfOfflineNodeList<ServerNamefavoredNodes)
   throws IOException {
     AdminService.BlockingInterface admin = getRsAdmin(server);
     if (admin == null) {
       .warn("Attempting to send OPEN RPC to server " + server.toString() +
         " failed because no RPC connection found to this server");
       return .;
     }
     OpenRegionRequest request = RequestConverter.buildOpenRegionRequest(server
       regionversionOfOfflineNodefavoredNodes
     try {
       OpenRegionResponse response = admin.openRegion(nullrequest);
       return ResponseConverter.getRegionOpeningState(response);
     } catch (ServiceException se) {
       throw ProtobufUtil.getRemoteException(se);
     }
   }

  
Sends an OPEN RPC to the specified server to open the specified region.

Open should not fail but can if server just crashed.

Parameters:
server server to open a region
regionOpenInfos info of a list of regions to open
Returns:
a list of region opening states
 
       List<Triple<HRegionInfoIntegerList<ServerName>>> regionOpenInfos)
   throws IOException {
     AdminService.BlockingInterface admin = getRsAdmin(server);
     if (admin == null) {
       .warn("Attempting to send OPEN RPC to server " + server.toString() +
         " failed because no RPC connection found to this server");
       return null;
     }
 
     OpenRegionRequest request = RequestConverter.buildOpenRegionRequest(serverregionOpenInfos,
     try {
       OpenRegionResponse response = admin.openRegion(nullrequest);
       return ResponseConverter.getRegionOpeningStateList(response);
     } catch (ServiceException se) {
       throw ProtobufUtil.getRemoteException(se);
     }
   }

  
Sends an CLOSE RPC to the specified server to close the specified region.

A region server could reject the close request because it either does not have the specified region or the region is being split.

Parameters:
server server to open a region
region region to open
versionOfClosingNode the version of znode to compare when RS transitions the znode from CLOSING state.
dest - if the region is moved to another server, the destination server. null otherwise.
Returns:
true if server acknowledged close, false if not
Throws:
java.io.IOException
 
   public boolean sendRegionClose(ServerName serverHRegionInfo region,
     int versionOfClosingNodeServerName destboolean transitionInZKthrows IOException {
     if (server == nullthrow new NullPointerException("Passed server is null");
     AdminService.BlockingInterface admin = getRsAdmin(server);
     if (admin == null) {
       throw new IOException("Attempting to send CLOSE RPC to server " +
         server.toString() + " for region " +
         region.getRegionNameAsString() +
         " failed because no RPC connection found to this server");
     }
     return ProtobufUtil.closeRegion(adminserverregion.getRegionName(),
       versionOfClosingNodedesttransitionInZK);
   }
 
   public boolean sendRegionClose(ServerName server,
       HRegionInfo regionint versionOfClosingNodethrows IOException {
     return sendRegionClose(serverregionversionOfClosingNodenulltrue);
   }

  
Sends an MERGE REGIONS RPC to the specified server to merge the specified regions.

A region server could reject the close request because it either does not have the specified region.

Parameters:
server server to merge regions
region_a region to merge
region_b region to merge
forcible true if do a compulsory merge, otherwise we will only merge two adjacent regions
Throws:
java.io.IOException
 
   public void sendRegionsMerge(ServerName serverHRegionInfo region_a,
       HRegionInfo region_bboolean forciblethrows IOException {
     if (server == null)
       throw new NullPointerException("Passed server is null");
     if (region_a == null || region_b == null)
       throw new NullPointerException("Passed region is null");
     AdminService.BlockingInterface admin = getRsAdmin(server);
     if (admin == null) {
       throw new IOException("Attempting to send MERGE REGIONS RPC to server "
           + server.toString() + " for region "
           + region_a.getRegionNameAsString() + ","
           + region_b.getRegionNameAsString()
           + " failed because no RPC connection found to this server");
     }
     ProtobufUtil.mergeRegions(adminregion_aregion_bforcible);
   }

  
Check if a region server is reachable and has the expected start code
 
   public boolean isServerReachable(ServerName server) {
     if (server == nullthrow new NullPointerException("Passed server is null");
 
     RetryCounter retryCounter = .create();
     while (retryCounter.shouldRetry()) {
       try {
         AdminService.BlockingInterface admin = getRsAdmin(server);
         if (admin != null) {
           ServerInfo info = ProtobufUtil.getServerInfo(admin);
           return info != null && info.hasServerName()
             && server.getStartcode() == info.getServerName().getStartCode();
         }
       } catch (IOException ioe) {
         .debug("Couldn't reach " + server + ", try=" + retryCounter.getAttemptTimes()
           + " of " + retryCounter.getMaxAttempts(), ioe);
         try {
           retryCounter.sleepUntilNextRetry();
         } catch(InterruptedException ie) {
           Thread.currentThread().interrupt();
         }
       }
     }
     return false;
   }

    

Parameters:
sn
Returns:
Admin interface for the remote regionserver named sn
Throws:
java.io.IOException
org.apache.hadoop.hbase.client.RetriesExhaustedException wrapping a ConnectException if failed
 
   throws IOException {
     AdminService.BlockingInterface admin = this..get(sn);
     if (admin == null) {
       .debug("New admin connection to " + sn.toString());
       admin = this..getAdmin(sn);
       this..put(snadmin);
     }
     return admin;
   }

  
Wait for the region servers to report in. We will wait until one of this condition is met: - the master is stopped - the 'hbase.master.wait.on.regionservers.maxtostart' number of region servers is reached - the 'hbase.master.wait.on.regionservers.mintostart' is reached AND there have been no new region server in for 'hbase.master.wait.on.regionservers.interval' time AND the 'hbase.master.wait.on.regionservers.timeout' is reached

 
   public void waitForRegionServers(MonitoredTask status)
   throws InterruptedException {
     final long interval = this..getConfiguration().
     final long timeout = this..getConfiguration().
     int minToStart = this..getConfiguration().
     if (minToStart < 1) {
       .warn(String.format(
         "The value of '%s' (%d) can not be less than 1, ignoring.",
         minToStart));
       minToStart = 1;
     }
     int maxToStart = this..getConfiguration().
     if (maxToStart < minToStart) {
         .warn(String.format(
             "The value of '%s' (%d) is set less than '%s' (%d), ignoring.",
             maxToStart,
             minToStart));
         maxToStart = .;
     }
 
     long now =  System.currentTimeMillis();
     final long startTime = now;
     long slept = 0;
     long lastLogTime = 0;
     long lastCountChange = startTime;
     int count = countOfRegionServers();
     int oldCount = 0;
     while (
       !this..isStopped() &&
         count < maxToStart &&
         (lastCountChange+interval > now || timeout > slept || count < minToStart)
       ){
 
       // Log some info at every interval time or if there is a change
       if (oldCount != count || lastLogTime+interval < now){
         lastLogTime = now;
         String msg =
           "Waiting for region servers count to settle; currently"+
             " checked in " + count + ", slept for " + slept + " ms," +
             " expecting minimum of " + minToStart + ", maximum of "maxToStart+
             ", timeout of "+timeout+" ms, interval of "+interval+" ms.";
         .info(msg);
         status.setStatus(msg);
       }
 
       // We sleep for some time
       final long sleepTime = 50;
       Thread.sleep(sleepTime);
       now =  System.currentTimeMillis();
       slept = now - startTime;
 
       oldCount = count;
       count = countOfRegionServers();
       if (count != oldCount) {
         lastCountChange = now;
       }
     }
 
     .info("Finished waiting for region servers count to settle;" +
       " checked in " + count + ", slept for " + slept + " ms," +
       " expecting minimum of " + minToStart + ", maximum of "maxToStart+","+
       " master is "+ (this..isStopped() ? "stopped.""running.")
     );
   }

  

Returns:
A copy of the internal list of online servers.
 
     // TODO: optimize the load balancer call so we don't need to make a new list
     // TODO: FIX. THIS IS POPULAR CALL.
     return new ArrayList<ServerName>(this..keySet());
   }

  

Returns:
A copy of the internal list of draining servers.
 
     return new ArrayList<ServerName>(this.);
   }

  

Returns:
A copy of the internal set of deadNotExpired servers.
 
     return new HashSet<ServerName>(this.);
   }

  
During startup, if we figure it is not a failover, i.e. there is no more HLog files to split, we won't try to recover these dead servers. So we just remove them from the queue. Use caution in calling this.
 
   }

  

Returns:
A copy of the internal map of requeuedDeadServers servers and their corresponding splitlog need flag.
 
     return Collections.unmodifiableMap(this.);
   }
 
   public boolean isServerOnline(ServerName serverName) {
     return serverName != null && .containsKey(serverName);
   }

  
Check if a server is known to be dead. A server can be online, or known to be dead, or unknown to this manager (i.e, not online, not known to be dead either. it is simply not tracked by the master any more, for example, a very old previous instance).
 
   public synchronized boolean isServerDead(ServerName serverName) {
     return serverName == null || .isDeadServer(serverName)
       || .contains(serverName)
       || .containsKey(serverName);
   }
 
   public void shutdownCluster() {
     this. = true;
     this..stop("Cluster shutdown requested");
   }
 
   public boolean isClusterShutdown() {
     return this.;
   }

  
Stop the ServerManager. Currently closes the connection to the master.
 
   public void stop() {
     if ( != null) {
       try {
         .close();
       } catch (IOException e) {
         .error("Attempt to close connection to master failed"e);
       }
     }
   }

  
Creates a list of possible destinations for a region. It contains the online servers, but not the draining or dying servers.

Parameters:
serverToExclude can be null if there is no server to exclude
 
   public List<ServerNamecreateDestinationServersList(final ServerName serverToExclude){
     final List<ServerNamedestServers = getOnlineServersList();
 
     if (serverToExclude != null){
       destServers.remove(serverToExclude);
     }
 
     // Loop through the draining server list and remove them from the server list
     final List<ServerNamedrainingServersCopy = getDrainingServersList();
     if (!drainingServersCopy.isEmpty()) {
       for (final ServerName serverdrainingServersCopy) {
        destServers.remove(server);
      }
    }
    // Remove the deadNotExpired servers from the server list.
    removeDeadNotExpiredServers(destServers);
    return destServers;
  }

  
Calls createDestinationServersList() without server to exclude.
    return createDestinationServersList(null);
  }

    
Loop through the deadNotExpired server list and remove them from the servers. This function should be used carefully outside of this class. You should use a high level method such as createDestinationServersList() instead of managing you own list.
    Set<ServerNamedeadNotExpiredServersCopy = this.getDeadNotExpiredServers();
    if (!deadNotExpiredServersCopy.isEmpty()) {
      for (ServerName server : deadNotExpiredServersCopy) {
        .debug("Removing dead but not expired server: " + server
          + " from eligible server pool.");
        servers.remove(server);
      }
    }
  }

  
To clear any dead server with same host name and port of any online server
    for (ServerName serverName : getOnlineServersList()) {
    }
  }
New to GrepCode? Check out our FAQ X