View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.backup.regionserver;
20  
21  
22  import java.io.IOException;
23  import java.util.concurrent.ThreadPoolExecutor;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.conf.Configuration;
28  import org.apache.hadoop.hbase.CoordinatedStateManagerFactory;
29  import org.apache.hadoop.hbase.backup.master.LogRollMasterProcedureManager;
30  import org.apache.hadoop.hbase.coordination.BaseCoordinatedStateManager;
31  import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher;
32  import org.apache.hadoop.hbase.procedure.ProcedureMember;
33  import org.apache.hadoop.hbase.procedure.ProcedureMemberRpcs;
34  import org.apache.hadoop.hbase.procedure.RegionServerProcedureManager;
35  import org.apache.hadoop.hbase.procedure.Subprocedure;
36  import org.apache.hadoop.hbase.procedure.SubprocedureFactory;
37  import org.apache.hadoop.hbase.regionserver.HRegionServer;
38  import org.apache.hadoop.hbase.regionserver.RegionServerServices;
39  
40  /**
41   * This manager class handles the work dealing with backup for a {@link HRegionServer}.
42   * <p>
43   * This provides the mechanism necessary to kick off a backup specific {@link Subprocedure} that is
44   * responsible by this region server. If any failures occur with the subprocedure, the manager's
45   * procedure member notifies the procedure coordinator to abort all others.
46   * <p>
47   * On startup, requires {@link #start()} to be called.
48   * <p>
49   * On shutdown, requires org.apache.hadoop.hbase.procedure.ProcedureMember.close() to be
50   * called
51   */
52  public class LogRollRegionServerProcedureManager extends RegionServerProcedureManager {
53  
54    private static final Log LOG = LogFactory.getLog(LogRollRegionServerProcedureManager.class);
55  
56    /** Conf key for number of request threads to start backup on regionservers */
57    public static final String BACKUP_REQUEST_THREADS_KEY = "hbase.backup.region.pool.threads";
58    /** # of threads for backup work on the rs. */
59    public static final int BACKUP_REQUEST_THREADS_DEFAULT = 10;
60  
61    public static final String BACKUP_TIMEOUT_MILLIS_KEY = "hbase.backup.timeout";
62    public static final long BACKUP_TIMEOUT_MILLIS_DEFAULT = 60000;
63  
64    /** Conf key for millis between checks to see if backup work completed or if there are errors */
65    public static final String BACKUP_REQUEST_WAKE_MILLIS_KEY = "hbase.backup.region.wakefrequency";
66    /** Default amount of time to check for errors while regions finish backup work */
67    private static final long BACKUP_REQUEST_WAKE_MILLIS_DEFAULT = 500;
68  
69    private RegionServerServices rss;
70    private ProcedureMemberRpcs memberRpcs;
71    private ProcedureMember member;
72  
73    /**
74     * Create a default backup procedure manager
75     */
76    public LogRollRegionServerProcedureManager() {
77    }
78  
79    /**
80     * Start accepting backup procedure requests.
81     */
82    @Override
83    public void start() {
84      this.memberRpcs.start(rss.getServerName().toString(), member);
85      LOG.info("Started region server backup manager.");
86    }
87  
88    /**
89     * Close <tt>this</tt> and all running backup procedure tasks
90     * @param force forcefully stop all running tasks
91     * @throws IOException exception
92     */
93    @Override
94    public void stop(boolean force) throws IOException {
95      String mode = force ? "abruptly" : "gracefully";
96      LOG.info("Stopping RegionServerBackupManager " + mode + ".");
97  
98      try {
99        this.member.close();
100     } finally {
101       this.memberRpcs.close();
102     }
103   }
104 
105   /**
106    * If in a running state, creates the specified subprocedure for handling a backup procedure.
107    * @return Subprocedure to submit to the ProcedureMemeber.
108    */
109   public Subprocedure buildSubprocedure(byte[] data) {
110 
111     // don't run a backup if the parent is stop(ping)
112     if (rss.isStopping() || rss.isStopped()) {
113       throw new IllegalStateException("Can't start backup procedure on RS: " + rss.getServerName()
114         + ", because stopping/stopped!");
115     }
116 
117     LOG.info("Attempting to run a roll log procedure for backup.");
118     ForeignExceptionDispatcher errorDispatcher = new ForeignExceptionDispatcher();
119     Configuration conf = rss.getConfiguration();
120     long timeoutMillis = conf.getLong(BACKUP_TIMEOUT_MILLIS_KEY, BACKUP_TIMEOUT_MILLIS_DEFAULT);
121     long wakeMillis =
122         conf.getLong(BACKUP_REQUEST_WAKE_MILLIS_KEY, BACKUP_REQUEST_WAKE_MILLIS_DEFAULT);
123 
124     LogRollBackupSubprocedurePool taskManager =
125         new LogRollBackupSubprocedurePool(rss.getServerName().toString(), conf);
126     return new LogRollBackupSubprocedure(rss, member, errorDispatcher, wakeMillis, timeoutMillis,
127       taskManager, data);
128 
129   }
130 
131   /**
132    * Build the actual backup procedure runner that will do all the 'hard' work
133    */
134   public class BackupSubprocedureBuilder implements SubprocedureFactory {
135 
136     @Override
137     public Subprocedure buildSubprocedure(String name, byte[] data) {
138       return LogRollRegionServerProcedureManager.this.buildSubprocedure(data);
139     }
140   }
141 
142   @Override
143   public void initialize(RegionServerServices rss) throws IOException {
144     this.rss = rss;
145     BaseCoordinatedStateManager coordManager =
146         (BaseCoordinatedStateManager) CoordinatedStateManagerFactory.getCoordinatedStateManager(rss
147           .getConfiguration());
148     coordManager.initialize(rss);
149     this.memberRpcs =
150         coordManager
151         .getProcedureMemberRpcs(LogRollMasterProcedureManager.ROLLLOG_PROCEDURE_SIGNATURE);
152 
153     // read in the backup handler configuration properties
154     Configuration conf = rss.getConfiguration();
155     long keepAlive = conf.getLong(BACKUP_TIMEOUT_MILLIS_KEY, BACKUP_TIMEOUT_MILLIS_DEFAULT);
156     int opThreads = conf.getInt(BACKUP_REQUEST_THREADS_KEY, BACKUP_REQUEST_THREADS_DEFAULT);
157     // create the actual cohort member
158     ThreadPoolExecutor pool =
159         ProcedureMember.defaultPool(rss.getServerName().toString(), opThreads, keepAlive);
160     this.member = new ProcedureMember(memberRpcs, pool, new BackupSubprocedureBuilder());
161   }
162 
163   @Override
164   public String getProcedureSignature() {
165     return "backup-proc";
166   }
167 
168 }