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 org.apache.hadoop.conf.Configuration;
23  import org.apache.hadoop.fs.FileSystem;
24  import org.apache.hadoop.fs.Path;
25  import org.apache.hadoop.hbase.HConstants;
26  import org.apache.hadoop.hbase.HRegionInfo;
27  import org.apache.hadoop.hbase.HServerInfo;
28  import org.apache.hadoop.hbase.KeyValue;
29  import org.apache.hadoop.hbase.regionserver.wal.HLog;
30  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
31  import org.apache.hadoop.hbase.regionserver.wal.LogEntryVisitor;
32  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
33  import org.apache.hadoop.hbase.replication.ReplicationZookeeperWrapper;
34  import org.apache.hadoop.hbase.util.Bytes;
35  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWrapper;
36  
37  import java.io.IOException;
38  import java.util.NavigableMap;
39  import java.util.TreeMap;
40  import java.util.concurrent.atomic.AtomicBoolean;
41  
42  /**
43   * Replication serves as an umbrella over the setup of replication and
44   * is used by HRS.
45   */
46  public class Replication implements LogEntryVisitor {
47  
48    private final boolean replication;
49    private final ReplicationSourceManager replicationManager;
50    private boolean replicationMaster;
51    private final AtomicBoolean replicating = new AtomicBoolean(true);
52    private final ReplicationZookeeperWrapper zkHelper;
53    private final Configuration conf;
54    private final AtomicBoolean  stopRequested;
55    private ReplicationSink replicationSink;
56  
57    /**
58     * Instantiate the replication management (if rep is enabled).
59     * @param conf conf to use
60     * @param hsi the info if this region server
61     * @param fs handle to the filesystem
62     * @param oldLogDir directory where logs are archived
63     * @param stopRequested boolean that tells us if we are shutting down
64     * @throws IOException
65     */
66    public Replication(Configuration conf, HServerInfo hsi,
67                       FileSystem fs, Path logDir, Path oldLogDir,
68                       AtomicBoolean stopRequested) throws IOException {
69      this.conf = conf;
70      this.stopRequested = stopRequested;
71      this.replication =
72          conf.getBoolean(HConstants.REPLICATION_ENABLE_KEY, false);
73      if (replication) {
74        this.zkHelper = new ReplicationZookeeperWrapper(
75          ZooKeeperWrapper.getInstance(conf, hsi.getServerName()), conf,
76          this.replicating, hsi.getServerName());
77        this.replicationMaster = zkHelper.isReplicationMaster();
78        this.replicationManager = this.replicationMaster ?
79          new ReplicationSourceManager(zkHelper, conf, stopRequested,
80            fs, this.replicating, logDir, oldLogDir) : null;
81      } else {
82        replicationManager = null;
83        zkHelper = null;
84      }
85    }
86  
87    /**
88     * Join with the replication threads
89     */
90    public void join() {
91      if (this.replication) {
92        if (this.replicationMaster) {
93          this.replicationManager.join();
94        }
95        this.zkHelper.deleteOwnRSZNode();
96      }
97    }
98  
99    /**
100    * Carry on the list of log entries down to the sink
101    * @param entries list of entries to replicate
102    * @throws IOException
103    */
104   public void replicateLogEntries(HLog.Entry[] entries) throws IOException {
105     if (this.replication && !this.replicationMaster) {
106       this.replicationSink.replicateEntries(entries);
107     }
108   }
109 
110   /**
111    * If replication is enabled and this cluster is a master,
112    * it starts
113    * @throws IOException
114    */
115   public void startReplicationServices() throws IOException {
116     if (this.replication) {
117       if (this.replicationMaster) {
118         this.replicationManager.init();
119       } else {
120         this.replicationSink =
121             new ReplicationSink(this.conf, this.stopRequested);
122       }
123     }
124   }
125 
126   /**
127    * Get the replication sources manager
128    * @return the manager if replication is enabled, else returns false
129    */
130   public ReplicationSourceManager getReplicationManager() {
131     return replicationManager;
132   }
133 
134   @Override
135   public void visitLogEntryBeforeWrite(HRegionInfo info, HLogKey logKey,
136                                        WALEdit logEdit) {
137     NavigableMap<byte[], Integer> scopes =
138         new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR);
139     byte[] family;
140     for (KeyValue kv : logEdit.getKeyValues()) {
141       family = kv.getFamily();
142       int scope = info.getTableDesc().getFamily(family).getScope();
143       if (scope != HConstants.REPLICATION_SCOPE_LOCAL &&
144           !scopes.containsKey(family)) {
145         scopes.put(family, scope);
146       }
147     }
148     if (!scopes.isEmpty()) {
149       logEdit.setScopes(scopes);
150     }
151   }
152 
153   /**
154    * Add this class as a log entry visitor for HLog if replication is enabled
155    * @param hlog log that was add ourselves on
156    */
157   public void addLogEntryVisitor(HLog hlog) {
158     if (replication) {
159       hlog.addLogEntryVisitor(this);
160     }
161   }
162 }