1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.replication;
20
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.concurrent.CopyOnWriteArrayList;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.Abortable;
30 import org.apache.hadoop.hbase.Stoppable;
31 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
32 import org.apache.hadoop.hbase.zookeeper.ZooKeeperListener;
33 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
34 import org.apache.zookeeper.KeeperException;
35
36
37
38
39
40
41 @InterfaceAudience.Private
42 public class ReplicationTrackerZKImpl extends ReplicationStateZKBase implements ReplicationTracker {
43
44 private static final Log LOG = LogFactory.getLog(ReplicationTrackerZKImpl.class);
45
46 private final Stoppable stopper;
47
48 private final List<ReplicationListener> listeners =
49 new CopyOnWriteArrayList<ReplicationListener>();
50
51 private final ArrayList<String> otherRegionServers = new ArrayList<String>();
52 private final ReplicationPeers replicationPeers;
53
54 public ReplicationTrackerZKImpl(ZooKeeperWatcher zookeeper,
55 final ReplicationPeers replicationPeers, Configuration conf, Abortable abortable,
56 Stoppable stopper) {
57 super(zookeeper, conf, abortable);
58 this.replicationPeers = replicationPeers;
59 this.stopper = stopper;
60 this.zookeeper.registerListener(new OtherRegionServerWatcher(this.zookeeper));
61 this.zookeeper.registerListener(new PeersWatcher(this.zookeeper));
62 }
63
64 @Override
65 public void registerListener(ReplicationListener listener) {
66 listeners.add(listener);
67 }
68
69 @Override
70 public void removeListener(ReplicationListener listener) {
71 listeners.remove(listener);
72 }
73
74
75
76
77 @Override
78 public List<String> getListOfRegionServers() {
79 refreshOtherRegionServersList();
80
81 List<String> list = null;
82 synchronized (otherRegionServers) {
83 list = new ArrayList<String>(otherRegionServers);
84 }
85 return list;
86 }
87
88
89
90
91
92 public class OtherRegionServerWatcher extends ZooKeeperListener {
93
94
95
96
97 public OtherRegionServerWatcher(ZooKeeperWatcher watcher) {
98 super(watcher);
99 }
100
101
102
103
104
105 @Override
106 public void nodeCreated(String path) {
107 refreshListIfRightPath(path);
108 }
109
110
111
112
113
114 @Override
115 public void nodeDeleted(String path) {
116 if (stopper.isStopped()) {
117 return;
118 }
119 boolean cont = refreshListIfRightPath(path);
120 if (!cont) {
121 return;
122 }
123 LOG.info(path + " znode expired, triggering replicatorRemoved event");
124 for (ReplicationListener rl : listeners) {
125 rl.regionServerRemoved(getZNodeName(path));
126 }
127 }
128
129
130
131
132
133 @Override
134 public void nodeChildrenChanged(String path) {
135 if (stopper.isStopped()) {
136 return;
137 }
138 refreshListIfRightPath(path);
139 }
140
141 private boolean refreshListIfRightPath(String path) {
142 if (!path.startsWith(this.watcher.rsZNode)) {
143 return false;
144 }
145 return refreshOtherRegionServersList();
146 }
147 }
148
149
150
151
152 public class PeersWatcher extends ZooKeeperListener {
153
154
155
156
157 public PeersWatcher(ZooKeeperWatcher watcher) {
158 super(watcher);
159 }
160
161
162
163
164
165 @Override
166 public void nodeDeleted(String path) {
167 List<String> peers = refreshPeersList(path);
168 if (peers == null) {
169 return;
170 }
171 if (isPeerPath(path)) {
172 String id = getZNodeName(path);
173 LOG.info(path + " znode expired, triggering peerRemoved event");
174 for (ReplicationListener rl : listeners) {
175 rl.peerRemoved(id);
176 }
177 }
178 }
179
180
181
182
183
184 @Override
185 public void nodeChildrenChanged(String path) {
186 List<String> peers = refreshPeersList(path);
187 if (peers == null) {
188 return;
189 }
190 LOG.info(path + " znode expired, triggering peerListChanged event");
191 for (ReplicationListener rl : listeners) {
192 rl.peerListChanged(peers);
193 }
194 }
195 }
196
197
198
199
200
201
202
203 private List<String> refreshPeersList(String path) {
204 if (!path.startsWith(getPeersZNode())) {
205 return null;
206 }
207 return this.replicationPeers.getAllPeerIds();
208 }
209
210 private String getPeersZNode() {
211 return this.peersZNode;
212 }
213
214
215
216
217
218
219 private String getZNodeName(String fullPath) {
220 String[] parts = fullPath.split("/");
221 return parts.length > 0 ? parts[parts.length - 1] : "";
222 }
223
224
225
226
227
228
229
230 private boolean refreshOtherRegionServersList() {
231 List<String> newRsList = getRegisteredRegionServers();
232 if (newRsList == null) {
233 return false;
234 } else {
235 synchronized (otherRegionServers) {
236 otherRegionServers.clear();
237 otherRegionServers.addAll(newRsList);
238 }
239 }
240 return true;
241 }
242
243
244
245
246
247 private List<String> getRegisteredRegionServers() {
248 List<String> result = null;
249 try {
250 result = ZKUtil.listChildrenAndWatchThem(this.zookeeper, this.zookeeper.rsZNode);
251 } catch (KeeperException e) {
252 this.abortable.abort("Get list of registered region servers", e);
253 }
254 return result;
255 }
256 }