View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.zookeeper;
19  
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.NavigableSet;
23  import java.util.TreeSet;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.Abortable;
28  import org.apache.hadoop.hbase.ServerName;
29  import org.apache.hadoop.hbase.HServerAddress;
30  import org.apache.hadoop.hbase.master.ServerManager;
31  import org.apache.zookeeper.KeeperException;
32  
33  /**
34   * Tracks the list of draining region servers via ZK.
35   *
36   * <p>This class is responsible for watching for changes to the draining
37   * servers list.  It handles adds/deletes in the draining RS list and
38   * watches each node.
39   *
40   * <p>If an RS gets deleted from draining list, we call
41   * {@link ServerManager#removeServerFromDrainList(ServerName)}
42   *
43   * <p>If an RS gets added to the draining list, we add a watcher to it and call
44   * {@link ServerManager#addServerToDrainList(ServerName)}
45   *
46   */
47  public class DrainingServerTracker extends ZooKeeperListener {
48    private static final Log LOG = LogFactory.getLog(DrainingServerTracker.class);
49  
50    private ServerManager serverManager;
51    private NavigableSet<ServerName> drainingServers = new TreeSet<ServerName>();
52    private Abortable abortable;
53  
54    public DrainingServerTracker(ZooKeeperWatcher watcher,
55        Abortable abortable, ServerManager serverManager) {
56      super(watcher);
57      this.abortable = abortable;
58      this.serverManager = serverManager;
59    }
60  
61    /**
62     * Starts the tracking of draining RegionServers.
63     *
64     * <p>All Draining RSs will be tracked after this method is called.
65     *
66     * @throws KeeperException
67     */
68    public void start() throws KeeperException, IOException {
69      watcher.registerListener(this);
70      List<String> servers =
71        ZKUtil.listChildrenAndWatchThem(watcher, watcher.drainingZNode);
72      add(servers);
73    }
74  
75    private void add(final List<String> servers) throws IOException {
76      synchronized(this.drainingServers) {
77        this.drainingServers.clear();
78        for (String n: servers) {
79          final ServerName sn = new ServerName(ZKUtil.getNodeName(n));
80          this.drainingServers.add(sn);
81          this.serverManager.addServerToDrainList(sn);
82          LOG.info("Draining RS node created, adding to list [" +
83              sn + "]");
84  
85        }
86      }
87    }
88  
89    private void remove(final ServerName sn) {
90      synchronized(this.drainingServers) {
91        this.drainingServers.remove(sn);
92        this.serverManager.removeServerFromDrainList(sn);
93      }
94    }
95  
96    @Override
97    public void nodeDeleted(final String path) {
98      if(path.startsWith(watcher.drainingZNode)) {
99        final ServerName sn = new ServerName(ZKUtil.getNodeName(path));
100       LOG.info("Draining RS node deleted, removing from list [" +
101           sn + "]");
102       remove(sn);
103     }
104   }
105 
106   @Override
107   public void nodeChildrenChanged(final String path) {
108     if(path.equals(watcher.drainingZNode)) {
109       try {
110         final List<String> newNodes =
111           ZKUtil.listChildrenAndWatchThem(watcher, watcher.drainingZNode);
112         add(newNodes);
113       } catch (KeeperException e) {
114         abortable.abort("Unexpected zk exception getting RS nodes", e);
115       } catch (IOException e) {
116         abortable.abort("Unexpected zk exception getting RS nodes", e);
117       }
118     }
119   }
120 
121 }