1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.zookeeper;
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.NavigableMap;
26 import java.util.TreeMap;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.Abortable;
31 import org.apache.hadoop.hbase.ServerName;
32 import org.apache.hadoop.hbase.master.ServerManager;
33 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
34 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionServerInfo;
35 import org.apache.hadoop.hbase.util.Bytes;
36 import org.apache.zookeeper.KeeperException;
37
38
39
40
41
42
43
44
45
46
47
48 public class RegionServerTracker extends ZooKeeperListener {
49 private static final Log LOG = LogFactory.getLog(RegionServerTracker.class);
50 private NavigableMap<ServerName, RegionServerInfo> regionServers =
51 new TreeMap<ServerName, RegionServerInfo>();
52 private ServerManager serverManager;
53 private Abortable abortable;
54
55 public RegionServerTracker(ZooKeeperWatcher watcher,
56 Abortable abortable, ServerManager serverManager) {
57 super(watcher);
58 this.abortable = abortable;
59 this.serverManager = serverManager;
60 }
61
62
63
64
65
66
67
68
69
70 public void start() throws KeeperException, IOException {
71 watcher.registerListener(this);
72 List<String> servers =
73 ZKUtil.listChildrenAndWatchThem(watcher, watcher.rsZNode);
74 add(servers);
75 }
76
77 private void add(final List<String> servers) throws IOException {
78 synchronized(this.regionServers) {
79 this.regionServers.clear();
80 for (String n: servers) {
81 ServerName sn = ServerName.parseServerName(ZKUtil.getNodeName(n));
82 if (regionServers.get(sn) == null) {
83 RegionServerInfo.Builder rsInfoBuilder = RegionServerInfo.newBuilder();
84 try {
85 String nodePath = ZKUtil.joinZNode(watcher.rsZNode, n);
86 byte[] data = ZKUtil.getData(watcher, nodePath);
87 LOG.info("Added tracking of RS " + nodePath);
88 if (data != null && data.length > 0 && ProtobufUtil.isPBMagicPrefix(data)) {
89 int magicLen = ProtobufUtil.lengthOfPBMagic();
90 rsInfoBuilder.mergeFrom(data, magicLen, data.length - magicLen);
91 }
92 } catch (KeeperException e) {
93 LOG.warn("Get Rs info port from ephemeral node", e);
94 } catch (IOException e) {
95 LOG.warn("Illegal data from ephemeral node", e);
96 }
97 this.regionServers.put(sn, rsInfoBuilder.build());
98 }
99 }
100 }
101 }
102
103 private void remove(final ServerName sn) {
104 synchronized(this.regionServers) {
105 this.regionServers.remove(sn);
106 }
107 }
108
109 @Override
110 public void nodeDeleted(String path) {
111 if (path.startsWith(watcher.rsZNode)) {
112 String serverName = ZKUtil.getNodeName(path);
113 LOG.info("RegionServer ephemeral node deleted, processing expiration [" +
114 serverName + "]");
115 ServerName sn = ServerName.parseServerName(serverName);
116 if (!serverManager.isServerOnline(sn)) {
117 LOG.warn(serverName.toString() + " is not online or isn't known to the master."+
118 "The latter could be caused by a DNS misconfiguration.");
119 return;
120 }
121 remove(sn);
122 this.serverManager.expireServer(sn);
123 }
124 }
125
126 @Override
127 public void nodeChildrenChanged(String path) {
128 if (path.equals(watcher.rsZNode)) {
129 try {
130 List<String> servers =
131 ZKUtil.listChildrenAndWatchThem(watcher, watcher.rsZNode);
132 add(servers);
133 } catch (IOException e) {
134 abortable.abort("Unexpected zk exception getting RS nodes", e);
135 } catch (KeeperException e) {
136 abortable.abort("Unexpected zk exception getting RS nodes", e);
137 }
138 }
139 }
140
141 public RegionServerInfo getRegionServerInfo(final ServerName sn) {
142 return regionServers.get(sn);
143 }
144
145
146
147
148
149 public List<ServerName> getOnlineServers() {
150 synchronized (this.regionServers) {
151 return new ArrayList<ServerName>(this.regionServers.keySet());
152 }
153 }
154 }