1- /**
1+ /*
22 *
33 * Licensed to the Apache Software Foundation (ASF) under one
44 * or more contributor license agreements. See the NOTICE file
1717 * limitations under the License.
1818 */
1919package org .apache .hadoop .hbase .master ;
20-
2120import java .io .IOException ;
21+ import java .util .Optional ;
2222import java .util .concurrent .atomic .AtomicBoolean ;
23-
24- import org .apache .hadoop .hbase .zookeeper .MasterAddressTracker ;
25- import org .apache .hadoop .hbase .zookeeper .ZKUtil ;
26- import org .apache .hadoop .hbase .zookeeper .ZKWatcher ;
27- import org .apache .hadoop .hbase .zookeeper .ZNodePaths ;
28- import org .apache .yetus .audience .InterfaceAudience ;
2923import org .apache .hadoop .hbase .Server ;
3024import org .apache .hadoop .hbase .ServerName ;
3125import org .apache .hadoop .hbase .ZNodeClearer ;
3226import org .apache .hadoop .hbase .exceptions .DeserializationException ;
3327import org .apache .hadoop .hbase .monitoring .MonitoredTask ;
34- import org .apache .hadoop .hbase .shaded . protobuf . ProtobufUtil ;
28+ import org .apache .hadoop .hbase .zookeeper . MasterAddressTracker ;
3529import org .apache .hadoop .hbase .zookeeper .ZKListener ;
30+ import org .apache .hadoop .hbase .zookeeper .ZKUtil ;
31+ import org .apache .hadoop .hbase .zookeeper .ZKWatcher ;
32+ import org .apache .hadoop .hbase .zookeeper .ZNodePaths ;
33+ import org .apache .yetus .audience .InterfaceAudience ;
3634import org .apache .zookeeper .KeeperException ;
3735import org .slf4j .Logger ;
3836import org .slf4j .LoggerFactory ;
37+ import org .apache .hadoop .hbase .shaded .protobuf .ProtobufUtil ;
3938
4039/**
4140 * Handles everything on master-side related to master election.
@@ -57,12 +56,18 @@ public class ActiveMasterManager extends ZKListener {
5756 final AtomicBoolean clusterHasActiveMaster = new AtomicBoolean (false );
5857 final AtomicBoolean clusterShutDown = new AtomicBoolean (false );
5958
59+ // This server's information.
6060 private final ServerName sn ;
6161 private int infoPort ;
6262 private final Server master ;
6363
64+ // Active master's server name. Invalidated anytime active master changes (based on ZK
65+ // notifications) and lazily fetched on-demand.
66+ // ServerName is immutable, so we don't need heavy synchronization around it.
67+ private volatile ServerName activeMasterServerName ;
68+
6469 /**
65- * @param watcher
70+ * @param watcher ZK watcher
6671 * @param sn ServerName
6772 * @param master In an instance of a Master.
6873 */
@@ -106,6 +111,30 @@ void handle(final String path) {
106111 }
107112 }
108113
114+ /**
115+ * Fetches the active master's ServerName from zookeeper.
116+ */
117+ private void fetchAndSetActiveMasterServerName () {
118+ LOG .debug ("Attempting to fetch active master sn from zk" );
119+ try {
120+ activeMasterServerName = MasterAddressTracker .getMasterAddress (watcher );
121+ } catch (IOException | KeeperException e ) {
122+ // Log and ignore for now and re-fetch later if needed.
123+ LOG .error ("Error fetching active master information" , e );
124+ }
125+ }
126+
127+ public Optional <ServerName > getActiveMasterServerName () {
128+ if (!clusterHasActiveMaster .get ()) {
129+ return Optional .empty ();
130+ }
131+ if (activeMasterServerName == null ) {
132+ fetchAndSetActiveMasterServerName ();
133+ }
134+ // It could still be null, but return whatever we have.
135+ return Optional .ofNullable (activeMasterServerName );
136+ }
137+
109138 /**
110139 * Handle a change in the master node. Doesn't matter whether this was called
111140 * from a nodeCreated or nodeDeleted event because there are no guarantees
@@ -134,6 +163,9 @@ private void handleMasterNodeChange() {
134163 // Notify any thread waiting to become the active master
135164 clusterHasActiveMaster .notifyAll ();
136165 }
166+ // Reset the active master sn. Will be re-fetched later if needed.
167+ // We don't want to make a synchronous RPC under a monitor.
168+ activeMasterServerName = null ;
137169 }
138170 } catch (KeeperException ke ) {
139171 master .abort ("Received an unexpected KeeperException, aborting" , ke );
@@ -151,8 +183,8 @@ private void handleMasterNodeChange() {
151183 * @param checkInterval the interval to check if the master is stopped
152184 * @param startupStatus the monitor status to track the progress
153185 * @return True if no issue becoming active master else false if another
154- * master was running or if some other problem (zookeeper, stop flag has been
155- * set on this Master)
186+ * master was running or if some other problem (zookeeper, stop flag has been
187+ * set on this Master)
156188 */
157189 boolean blockUntilBecomingActiveMaster (
158190 int checkInterval , MonitoredTask startupStatus ) {
@@ -178,10 +210,14 @@ boolean blockUntilBecomingActiveMaster(
178210 // We are the master, return
179211 startupStatus .setStatus ("Successfully registered as active master." );
180212 this .clusterHasActiveMaster .set (true );
213+ activeMasterServerName = sn ;
181214 LOG .info ("Registered as active master=" + this .sn );
182215 return true ;
183216 }
184217
218+ // Invalidate the active master name so that subsequent requests do not get any stale
219+ // master information. Will be re-fetched if needed.
220+ activeMasterServerName = null ;
185221 // There is another active master running elsewhere or this is a restart
186222 // and the master ephemeral node has not expired yet.
187223 this .clusterHasActiveMaster .set (true );
@@ -208,7 +244,8 @@ boolean blockUntilBecomingActiveMaster(
208244 ZKUtil .deleteNode (this .watcher , this .watcher .getZNodePaths ().masterAddressZNode );
209245
210246 // We may have failed to delete the znode at the previous step, but
211- // we delete the file anyway: a second attempt to delete the znode is likely to fail again.
247+ // we delete the file anyway: a second attempt to delete the znode is likely to fail
248+ // again.
212249 ZNodeClearer .deleteMyEphemeralNodeOnDisk ();
213250 } else {
214251 msg = "Another master is the active master, " + currentMaster +
0 commit comments