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 org.apache.hadoop.conf.Configuration; 022import org.apache.hadoop.hbase.Server; 023import org.apache.hadoop.hbase.ServerName; 024import org.apache.hadoop.hbase.monitoring.MonitoredTask; 025import org.apache.hadoop.hbase.util.Threads; 026import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; 027import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 028import org.apache.zookeeper.KeeperException; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032/** 033 * An implementation of HMaster that always runs as a stand by and never transitions to active. 034 */ 035public class AlwaysStandByHMaster extends HMaster { 036 /** 037 * An implementation of ActiveMasterManager that never transitions it's master to active state. It 038 * always remains as a stand by master. With the master registry implementation (HBASE-18095) it 039 * is expected to have at least one active / standby master always running at any point in time 040 * since they serve as the gateway for client connections. 041 * 042 * With this implementation, tests can simulate the scenario of not having an active master yet 043 * the client connections to the cluster succeed. 044 */ 045 private static class AlwaysStandByMasterManager extends ActiveMasterManager { 046 private static final Logger LOG = 047 LoggerFactory.getLogger(AlwaysStandByMasterManager.class); 048 049 AlwaysStandByMasterManager(ZKWatcher watcher, ServerName sn, Server master) { 050 super(watcher, sn, master); 051 } 052 053 /** 054 * An implementation that never transitions to an active master. 055 */ 056 boolean blockUntilBecomingActiveMaster(int checkInterval, MonitoredTask startupStatus) { 057 while (!(master.isAborted() || master.isStopped())) { 058 startupStatus.setStatus("Forever looping to stay as a standby master."); 059 try { 060 activeMasterServerName = null; 061 try { 062 if (MasterAddressTracker.getMasterAddress(watcher) != null) { 063 clusterHasActiveMaster.set(true); 064 } 065 Threads.sleepWithoutInterrupt(100); 066 } catch (IOException e) { 067 // pass, we will get notified when some other active master creates the znode. 068 } 069 } catch (KeeperException e) { 070 master.abort("Received an unexpected KeeperException, aborting", e); 071 return false; 072 } 073 synchronized (this.clusterHasActiveMaster) { 074 while (clusterHasActiveMaster.get() && !master.isStopped()) { 075 try { 076 clusterHasActiveMaster.wait(checkInterval); 077 } catch (InterruptedException e) { 078 // We expect to be interrupted when a master dies, 079 // will fall out if so 080 LOG.debug("Interrupted waiting for master to die", e); 081 } 082 } 083 if (clusterShutDown.get()) { 084 this.master.stop( 085 "Cluster went down before this master became active"); 086 } 087 } 088 } 089 return false; 090 } 091 } 092 093 public AlwaysStandByHMaster(Configuration conf) throws IOException { 094 super(conf); 095 } 096 097 protected ActiveMasterManager createActiveMasterManager( 098 ZKWatcher zk, ServerName sn, org.apache.hadoop.hbase.Server server) { 099 return new AlwaysStandByMasterManager(zk, sn, server); 100 } 101}