001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.master; 019 020import java.io.IOException; 021import java.io.InterruptedIOException; 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.hbase.Server; 024import org.apache.hadoop.hbase.ServerName; 025import org.apache.hadoop.hbase.monitoring.MonitoredTask; 026import org.apache.hadoop.hbase.monitoring.TaskGroup; 027import org.apache.hadoop.hbase.util.Threads; 028import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; 029import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 030import org.apache.zookeeper.KeeperException; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034/** 035 * An implementation of HMaster that always runs as a stand by and never transitions to active. 036 */ 037public class AlwaysStandByHMaster extends HMaster { 038 /** 039 * An implementation of ActiveMasterManager that never transitions it's master to active state. It 040 * always remains as a stand by master. With the master registry implementation (HBASE-18095) it 041 * is expected to have at least one active / standby master always running at any point in time 042 * since they serve as the gateway for client connections. With this implementation, tests can 043 * simulate the scenario of not having an active master yet the client connections to the cluster 044 * succeed. 045 */ 046 private static class AlwaysStandByMasterManager extends ActiveMasterManager { 047 private static final Logger LOG = LoggerFactory.getLogger(AlwaysStandByMasterManager.class); 048 049 AlwaysStandByMasterManager(ZKWatcher watcher, ServerName sn, Server master) 050 throws InterruptedIOException { 051 super(watcher, sn, master); 052 } 053 054 /** 055 * An implementation that never transitions to an active master. 056 */ 057 @Override 058 boolean blockUntilBecomingActiveMaster(int checkInterval, TaskGroup startupTaskGroup) { 059 MonitoredTask loopTask = startupTaskGroup.addTask("Stay as a standby master."); 060 while (!(master.isAborted() || master.isStopped())) { 061 loopTask.setStatus("Forever looping to stay as a standby master."); 062 try { 063 activeMasterServerName = null; 064 try { 065 if (MasterAddressTracker.getMasterAddress(watcher) != null) { 066 clusterHasActiveMaster.set(true); 067 } 068 } catch (IOException e) { 069 // pass, we will get notified when some other active master creates the znode. 070 } 071 Threads.sleepWithoutInterrupt(1000); 072 } catch (KeeperException e) { 073 master.abort("Received an unexpected KeeperException, aborting", e); 074 return false; 075 } 076 synchronized (this.clusterHasActiveMaster) { 077 while (clusterHasActiveMaster.get() && !master.isStopped()) { 078 try { 079 clusterHasActiveMaster.wait(checkInterval); 080 } catch (InterruptedException e) { 081 // We expect to be interrupted when a master dies, 082 // will fall out if so 083 LOG.debug("Interrupted waiting for master to die", e); 084 } 085 } 086 if (clusterShutDown.get()) { 087 this.master.stop("Cluster went down before this master became active"); 088 } 089 } 090 } 091 return false; 092 } 093 } 094 095 public AlwaysStandByHMaster(Configuration conf) throws IOException { 096 super(conf); 097 } 098 099 protected ActiveMasterManager createActiveMasterManager(ZKWatcher zk, ServerName sn, 100 org.apache.hadoop.hbase.Server server) throws InterruptedIOException { 101 return new AlwaysStandByMasterManager(zk, sn, server); 102 } 103}