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.util.Threads; 027import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker; 028import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 029import org.apache.zookeeper.KeeperException; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033/** 034 * An implementation of HMaster that always runs as a stand by and never transitions to active. 035 */ 036public class AlwaysStandByHMaster extends HMaster { 037 /** 038 * An implementation of ActiveMasterManager that never transitions it's master to active state. It 039 * always remains as a stand by master. With the master registry implementation (HBASE-18095) it 040 * is expected to have at least one active / standby master always running at any point in time 041 * since they serve as the gateway for client connections. With this implementation, tests can 042 * simulate the scenario of not having an active master yet the client connections to the cluster 043 * succeed. 044 */ 045 private static class AlwaysStandByMasterManager extends ActiveMasterManager { 046 private static final Logger LOG = LoggerFactory.getLogger(AlwaysStandByMasterManager.class); 047 048 AlwaysStandByMasterManager(ZKWatcher watcher, ServerName sn, Server master) 049 throws InterruptedIOException { 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 } catch (IOException e) { 066 // pass, we will get notified when some other active master creates the znode. 067 } 068 Threads.sleepWithoutInterrupt(1000); 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("Cluster went down before this master became active"); 085 } 086 } 087 } 088 return false; 089 } 090 } 091 092 public AlwaysStandByHMaster(Configuration conf) throws IOException { 093 super(conf); 094 } 095 096 protected ActiveMasterManager createActiveMasterManager(ZKWatcher zk, ServerName sn, 097 org.apache.hadoop.hbase.Server server) throws InterruptedIOException { 098 return new AlwaysStandByMasterManager(zk, sn, server); 099 } 100}