View Javadoc

1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
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.wal.HLog;
35  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
36  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
37  import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
38  import org.apache.hadoop.hbase.replication.ReplicationZookeeper;
39  import org.apache.hadoop.hbase.replication.master.ReplicationLogCleaner;
40  import org.apache.hadoop.hbase.util.Bytes;
41  import org.apache.zookeeper.KeeperException;
42  
43  import static org.apache.hadoop.hbase.HConstants.HBASE_MASTER_LOGCLEANER_PLUGINS;
44  import static org.apache.hadoop.hbase.HConstants.REPLICATION_ENABLE_KEY;
45  import static org.apache.hadoop.hbase.HConstants.REPLICATION_SCOPE_LOCAL;
46  
47  /**
48   * Gateway to Replication.  Used by {@link org.apache.hadoop.hbase.regionserver.HRegionServer}.
49   */
50  public class Replication implements WALActionsListener {
51    private final boolean replication;
52    private final ReplicationSourceManager replicationManager;
53    private final AtomicBoolean replicating = new AtomicBoolean(true);
54    private final ReplicationZookeeper zkHelper;
55    private final Configuration conf;
56    private ReplicationSink replicationSink;
57    // Hosting server
58    private final Server server;
59  
60    /**
61     * Instantiate the replication management (if rep is enabled).
62     * @param server Hosting server
63     * @param fs handle to the filesystem
64     * @param logDir
65     * @param oldLogDir directory where logs are archived
66     * @throws IOException
67     * @throws KeeperException 
68     */
69    public Replication(final Server server, final FileSystem fs,
70        final Path logDir, final Path oldLogDir)
71    throws IOException, KeeperException {
72      this.server = server;
73      this.conf = this.server.getConfiguration();
74      this.replication = isReplication(this.conf);
75      if (replication) {
76        this.zkHelper = new ReplicationZookeeper(server, this.replicating);
77        this.replicationManager = new ReplicationSourceManager(zkHelper, conf,
78            this.server, fs, this.replicating, logDir, oldLogDir) ;
79      } else {
80        this.replicationManager = null;
81        this.zkHelper = null;
82      }
83    }
84  
85    /**
86     * @param c Configuration to look at
87     * @return True if replication is enabled.
88     */
89    public static boolean isReplication(final Configuration c) {
90      return c.getBoolean(REPLICATION_ENABLE_KEY, false);
91    }
92  
93    /**
94     * Join with the replication threads
95     */
96    public void join() {
97      if (this.replication) {
98        this.replicationManager.join();
99      }
100   }
101 
102   /**
103    * Carry on the list of log entries down to the sink
104    * @param entries list of entries to replicate
105    * @throws IOException
106    */
107   public void replicateLogEntries(HLog.Entry[] entries) throws IOException {
108     if (this.replication) {
109       this.replicationSink.replicateEntries(entries);
110     }
111   }
112 
113   /**
114    * If replication is enabled and this cluster is a master,
115    * it starts
116    * @throws IOException
117    */
118   public void startReplicationServices() throws IOException {
119     if (this.replication) {
120       this.replicationManager.init();
121       this.replicationSink = new ReplicationSink(this.conf, this.server);
122     }
123   }
124 
125   /**
126    * Get the replication sources manager
127    * @return the manager if replication is enabled, else returns false
128    */
129   public ReplicationSourceManager getReplicationManager() {
130     return this.replicationManager;
131   }
132 
133   @Override
134   public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey,
135       WALEdit logEdit) {
136     // Not interested
137   }
138 
139   @Override
140   public void visitLogEntryBeforeWrite(HTableDescriptor htd, HLogKey logKey,
141                                        WALEdit logEdit) {
142     NavigableMap<byte[], Integer> scopes =
143         new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR);
144     byte[] family;
145     for (KeyValue kv : logEdit.getKeyValues()) {
146       family = kv.getFamily();
147       int scope = htd.getFamily(family).getScope();
148       if (scope != REPLICATION_SCOPE_LOCAL &&
149           !scopes.containsKey(family)) {
150         scopes.put(family, scope);
151       }
152     }
153     if (!scopes.isEmpty()) {
154       logEdit.setScopes(scopes);
155     }
156   }
157 
158   @Override
159   public void logRolled(Path p) throws IOException {
160     getReplicationManager().logRolled(p);
161   }
162 
163   /**
164    * This method modifies the master's configuration in order to inject
165    * replication-related features
166    * @param conf
167    */
168   public static void decorateMasterConfiguration(Configuration conf) {
169     if (!isReplication(conf)) {
170       return;
171     }
172     String plugins = conf.get(HBASE_MASTER_LOGCLEANER_PLUGINS);
173     if (!plugins.contains(ReplicationLogCleaner.class.toString())) {
174       conf.set(HBASE_MASTER_LOGCLEANER_PLUGINS,
175           plugins + "," + ReplicationLogCleaner.class.getCanonicalName());
176     }
177   }
178 
179   @Override
180   public void logRollRequested() {
181     // Not interested
182   }
183 
184   @Override
185   public void logCloseRequested() {
186     // not interested
187   }
188 }