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.regionserver;
21
22 import java.io.IOException;
23 import java.util.NavigableMap;
24 import java.util.TreeMap;
25 import java.util.concurrent.atomic.AtomicBoolean;
26
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.KeyValue;
33 import org.apache.hadoop.hbase.Server;
34 import org.apache.hadoop.hbase.regionserver.ReplicationSourceService;
35 import org.apache.hadoop.hbase.regionserver.ReplicationSinkService;
36 import org.apache.hadoop.hbase.regionserver.wal.HLog;
37 import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
38 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
39 import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
40 import org.apache.hadoop.hbase.replication.ReplicationZookeeper;
41 import org.apache.hadoop.hbase.replication.master.ReplicationLogCleaner;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.apache.zookeeper.KeeperException;
44
45 import static org.apache.hadoop.hbase.HConstants.HBASE_MASTER_LOGCLEANER_PLUGINS;
46 import static org.apache.hadoop.hbase.HConstants.REPLICATION_ENABLE_KEY;
47 import static org.apache.hadoop.hbase.HConstants.REPLICATION_SCOPE_LOCAL;
48
49
50
51
52 public class Replication implements WALActionsListener,
53 ReplicationSourceService, ReplicationSinkService {
54 private boolean replication;
55 private ReplicationSourceManager replicationManager;
56 private final AtomicBoolean replicating = new AtomicBoolean(true);
57 private ReplicationZookeeper zkHelper;
58 private Configuration conf;
59 private ReplicationSink replicationSink;
60
61 private Server server;
62
63
64
65
66
67
68
69
70
71 public Replication(final Server server, final FileSystem fs,
72 final Path logDir, final Path oldLogDir) throws IOException{
73 initialize(server, fs, logDir, oldLogDir);
74 }
75
76
77
78
79 public Replication() {
80 }
81
82 public void initialize(final Server server, final FileSystem fs,
83 final Path logDir, final Path oldLogDir) throws IOException {
84 this.server = server;
85 this.conf = this.server.getConfiguration();
86 this.replication = isReplication(this.conf);
87 if (replication) {
88 try {
89 this.zkHelper = new ReplicationZookeeper(server, this.replicating);
90 } catch (KeeperException ke) {
91 throw new IOException("Failed replication handler create " +
92 "(replicating=" + this.replicating, ke);
93 }
94 this.replicationManager = new ReplicationSourceManager(zkHelper, conf,
95 this.server, fs, this.replicating, logDir, oldLogDir) ;
96 } else {
97 this.replicationManager = null;
98 this.zkHelper = null;
99 }
100 }
101
102
103
104
105
106 public static boolean isReplication(final Configuration c) {
107 return c.getBoolean(REPLICATION_ENABLE_KEY, false);
108 }
109
110
111
112
113 public WALActionsListener getWALActionsListener() {
114 return this;
115 }
116
117
118
119 public void stopReplicationService() {
120 join();
121 }
122
123
124
125
126 public void join() {
127 if (this.replication) {
128 this.replicationManager.join();
129 if (this.replicationSink != null) {
130 this.replicationSink.stopReplicationSinkServices();
131 }
132 }
133 }
134
135
136
137
138
139
140 public void replicateLogEntries(HLog.Entry[] entries) throws IOException {
141 if (this.replication) {
142 this.replicationSink.replicateEntries(entries);
143 }
144 }
145
146
147
148
149
150
151 public void startReplicationService() throws IOException {
152 if (this.replication) {
153 this.replicationManager.init();
154 this.replicationSink = new ReplicationSink(this.conf, this.server);
155 }
156 }
157
158
159
160
161
162 public ReplicationSourceManager getReplicationManager() {
163 return this.replicationManager;
164 }
165
166 @Override
167 public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey,
168 WALEdit logEdit) {
169
170 }
171
172 @Override
173 public void visitLogEntryBeforeWrite(HTableDescriptor htd, HLogKey logKey,
174 WALEdit logEdit) {
175 NavigableMap<byte[], Integer> scopes =
176 new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR);
177 byte[] family;
178 for (KeyValue kv : logEdit.getKeyValues()) {
179 family = kv.getFamily();
180 int scope = htd.getFamily(family).getScope();
181 if (scope != REPLICATION_SCOPE_LOCAL &&
182 !scopes.containsKey(family)) {
183 scopes.put(family, scope);
184 }
185 }
186 if (!scopes.isEmpty()) {
187 logEdit.setScopes(scopes);
188 }
189 }
190
191 @Override
192 public void preLogRoll(Path oldPath, Path newPath) throws IOException {
193 getReplicationManager().preLogRoll(newPath);
194 }
195
196 @Override
197 public void postLogRoll(Path oldPath, Path newPath) throws IOException {
198 getReplicationManager().postLogRoll(newPath);
199 }
200
201 @Override
202 public void preLogArchive(Path oldPath, Path newPath) throws IOException {
203
204 }
205
206 @Override
207 public void postLogArchive(Path oldPath, Path newPath) throws IOException {
208
209 }
210
211
212
213
214
215
216 public static void decorateMasterConfiguration(Configuration conf) {
217 if (!isReplication(conf)) {
218 return;
219 }
220 String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);
221 String cleanerClass = ReplicationLogCleaner.class.getCanonicalName();
222 if (!plugins.contains(cleanerClass)) {
223 conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS, plugins + "," + cleanerClass);
224 }
225 }
226
227 @Override
228 public void logRollRequested() {
229
230 }
231
232 @Override
233 public void logCloseRequested() {
234
235 }
236 }