001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.master; 020 021import java.io.IOException; 022import java.util.List; 023import org.apache.hadoop.hbase.HConstants; 024import org.apache.hadoop.hbase.ServerName; 025import org.apache.hadoop.hbase.client.RegionInfo; 026import org.apache.hadoop.hbase.client.RegionInfoBuilder; 027import org.apache.hadoop.hbase.client.RegionReplicaUtil; 028import org.apache.hadoop.hbase.master.assignment.AssignmentManager; 029import org.apache.hadoop.hbase.zookeeper.MetaTableLocator; 030import org.apache.hadoop.hbase.zookeeper.ZKUtil; 031import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 032import org.apache.yetus.audience.InterfaceAudience; 033import org.apache.zookeeper.KeeperException; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037/** 038 * Used by the HMaster on startup to split meta logs and assign the meta table. 039 */ 040@InterfaceAudience.Private 041class MasterMetaBootstrap { 042 private static final Logger LOG = LoggerFactory.getLogger(MasterMetaBootstrap.class); 043 044 private final HMaster master; 045 046 public MasterMetaBootstrap(HMaster master) { 047 this.master = master; 048 } 049 050 /** 051 * For assigning hbase:meta replicas only. 052 * TODO: The way this assign runs, nothing but chance to stop all replicas showing up on same 053 * server as the hbase:meta region. 054 */ 055 void assignMetaReplicas() 056 throws IOException, InterruptedException, KeeperException { 057 int numReplicas = master.getConfiguration().getInt(HConstants.META_REPLICAS_NUM, 058 HConstants.DEFAULT_META_REPLICA_NUM); 059 if (numReplicas <= 1) { 060 // No replicaas to assign. Return. 061 return; 062 } 063 final AssignmentManager assignmentManager = master.getAssignmentManager(); 064 if (!assignmentManager.isMetaLoaded()) { 065 throw new IllegalStateException("hbase:meta must be initialized first before we can " + 066 "assign out its replicas"); 067 } 068 ServerName metaServername = 069 this.master.getMetaTableLocator().getMetaRegionLocation(this.master.getZooKeeper()); 070 for (int i = 1; i < numReplicas; i++) { 071 // Get current meta state for replica from zk. 072 RegionState metaState = MetaTableLocator.getMetaRegionState(master.getZooKeeper(), i); 073 RegionInfo hri = RegionReplicaUtil.getRegionInfoForReplica( 074 RegionInfoBuilder.FIRST_META_REGIONINFO, i); 075 LOG.debug(hri.getRegionNameAsString() + " replica region state from zookeeper=" + metaState); 076 if (metaServername.equals(metaState.getServerName())) { 077 metaState = null; 078 LOG.info(hri.getRegionNameAsString() + 079 " old location is same as current hbase:meta location; setting location as null..."); 080 } 081 // These assigns run inline. All is blocked till they complete. Only interrupt is shutting 082 // down hosting server which calls AM#stop. 083 if (metaState != null && metaState.getServerName() != null) { 084 // Try to retain old assignment. 085 assignmentManager.assign(hri, metaState.getServerName()); 086 } else { 087 assignmentManager.assign(hri); 088 } 089 } 090 unassignExcessMetaReplica(numReplicas); 091 } 092 093 private void unassignExcessMetaReplica(int numMetaReplicasConfigured) { 094 final ZKWatcher zooKeeper = master.getZooKeeper(); 095 // unassign the unneeded replicas (for e.g., if the previous master was configured 096 // with a replication of 3 and now it is 2, we need to unassign the 1 unneeded replica) 097 try { 098 List<String> metaReplicaZnodes = zooKeeper.getMetaReplicaNodes(); 099 for (String metaReplicaZnode : metaReplicaZnodes) { 100 int replicaId = zooKeeper.znodePaths.getMetaReplicaIdFromZnode(metaReplicaZnode); 101 if (replicaId >= numMetaReplicasConfigured) { 102 RegionState r = MetaTableLocator.getMetaRegionState(zooKeeper, replicaId); 103 LOG.info("Closing excess replica of meta region " + r.getRegion()); 104 // send a close and wait for a max of 30 seconds 105 ServerManager.closeRegionSilentlyAndWait(master.getClusterConnection(), 106 r.getServerName(), r.getRegion(), 30000); 107 ZKUtil.deleteNode(zooKeeper, zooKeeper.znodePaths.getZNodeForReplica(replicaId)); 108 } 109 } 110 } catch (Exception ex) { 111 // ignore the exception since we don't want the master to be wedged due to potential 112 // issues in the cleanup of the extra regions. We can do that cleanup via hbck or manually 113 LOG.warn("Ignoring exception " + ex); 114 } 115 } 116}