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.replication.master;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.hadoop.conf.Configuration;
25 import org.apache.hadoop.fs.Path;
26 import org.apache.hadoop.hbase.Abortable;
27 import org.apache.hadoop.hbase.HConstants;
28 import org.apache.hadoop.hbase.client.HConnectionManager;
29 import org.apache.hadoop.hbase.master.cleaner.BaseLogCleanerDelegate;
30 import org.apache.hadoop.hbase.replication.ReplicationZookeeper;
31 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
32 import org.apache.zookeeper.KeeperException;
33
34 import java.io.IOException;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Set;
38
39
40
41
42
43 public class ReplicationLogCleaner extends BaseLogCleanerDelegate implements Abortable {
44 private static final Log LOG = LogFactory.getLog(ReplicationLogCleaner.class);
45 private ReplicationZookeeper zkHelper;
46 private Set<String> hlogs = new HashSet<String>();
47 private boolean stopped = false;
48 private boolean aborted;
49
50
51
52
53 public ReplicationLogCleaner() {}
54
55 @Override
56 public boolean isLogDeletable(Path filePath) {
57
58 try {
59 if (!zkHelper.getReplication()) {
60 return false;
61 }
62 } catch (KeeperException e) {
63 abort("Cannot get the state of replication", e);
64 return false;
65 }
66
67
68
69 if (this.getConf() == null) {
70 return true;
71 }
72 String log = filePath.getName();
73
74
75 if (this.hlogs.contains(log)) {
76 return false;
77 }
78
79
80
81
82 return !refreshHLogsAndSearch(log);
83 }
84
85
86
87
88
89
90
91
92 private boolean refreshHLogsAndSearch(String searchedLog) {
93 this.hlogs.clear();
94 final boolean lookForLog = searchedLog != null;
95 List<String> rss = zkHelper.getListOfReplicators();
96 if (rss == null) {
97 LOG.debug("Didn't find any region server that replicates, deleting: " +
98 searchedLog);
99 return false;
100 }
101 for (String rs: rss) {
102 List<String> listOfPeers = zkHelper.getListPeersForRS(rs);
103
104 if (listOfPeers == null) {
105 continue;
106 }
107 for (String id : listOfPeers) {
108 List<String> peersHlogs = zkHelper.getListHLogsForPeerForRS(rs, id);
109 if (peersHlogs != null) {
110 this.hlogs.addAll(peersHlogs);
111 }
112
113 if(lookForLog && this.hlogs.contains(searchedLog)) {
114 LOG.debug("Found log in ZK, keeping: " + searchedLog);
115 return true;
116 }
117 }
118 }
119 LOG.debug("Didn't find this log in ZK, deleting: " + searchedLog);
120 return false;
121 }
122
123 @Override
124 public void setConf(Configuration config) {
125
126 if (!config.getBoolean(HConstants.REPLICATION_ENABLE_KEY, false)) {
127 return;
128 }
129
130
131 Configuration conf = new Configuration(config);
132 super.setConf(conf);
133 try {
134 ZooKeeperWatcher zkw = new ZooKeeperWatcher(conf, "replicationLogCleaner", null);
135 this.zkHelper = new ReplicationZookeeper(this, conf, zkw);
136 } catch (KeeperException e) {
137 LOG.error("Error while configuring " + this.getClass().getName(), e);
138 } catch (IOException e) {
139 LOG.error("Error while configuring " + this.getClass().getName(), e);
140 }
141 refreshHLogsAndSearch(null);
142 }
143
144
145 @Override
146 public void stop(String why) {
147 if (this.stopped) return;
148 this.stopped = true;
149 if (this.zkHelper != null) {
150 LOG.info("Stopping " + this.zkHelper.getZookeeperWatcher());
151 this.zkHelper.getZookeeperWatcher().close();
152 }
153
154 HConnectionManager.deleteConnection(this.getConf());
155 }
156
157 @Override
158 public boolean isStopped() {
159 return this.stopped;
160 }
161
162 @Override
163 public void abort(String why, Throwable e) {
164 LOG.warn("Aborting ReplicationLogCleaner because " + why, e);
165 this.aborted = true;
166 stop(why);
167 }
168
169 @Override
170 public boolean isAborted() {
171 return this.aborted;
172 }
173 }