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.zookeeper; 019 020import static org.apache.hadoop.hbase.HConstants.DEFAULT_META_REPLICA_NUM; 021import static org.apache.hadoop.hbase.HConstants.DEFAULT_ZOOKEEPER_ZNODE_PARENT; 022import static org.apache.hadoop.hbase.HConstants.META_REPLICAS_NUM; 023import static org.apache.hadoop.hbase.HConstants.SPLIT_LOGDIR_NAME; 024import static org.apache.hadoop.hbase.HConstants.ZOOKEEPER_ZNODE_PARENT; 025import static org.apache.hadoop.hbase.client.RegionInfo.DEFAULT_REPLICA_ID; 026 027import java.util.Collection; 028import java.util.Optional; 029import java.util.stream.IntStream; 030import org.apache.hadoop.conf.Configuration; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.yetus.audience.InterfaceAudience; 033 034import org.apache.hbase.thirdparty.com.google.common.collect.ImmutableMap; 035 036/** 037 * Class that hold all the paths of znode for HBase. 038 */ 039@InterfaceAudience.Private 040public class ZNodePaths { 041 // TODO: Replace this with ZooKeeper constant when ZOOKEEPER-277 is resolved. 042 public static final char ZNODE_PATH_SEPARATOR = '/'; 043 044 public static final String META_ZNODE_PREFIX_CONF_KEY = "zookeeper.znode.metaserver"; 045 public static final String META_ZNODE_PREFIX = "meta-region-server"; 046 private static final String DEFAULT_SNAPSHOT_CLEANUP_ZNODE = "snapshot-cleanup"; 047 048 // base znode for this cluster 049 public final String baseZNode; 050 051 /** 052 * The prefix of meta znode. Does not include baseZNode. 053 * Its a 'prefix' because meta replica id integer can be tagged on the end (if 054 * no number present, it is 'default' replica). 055 */ 056 private final String metaZNodePrefix; 057 058 /** 059 * znodes containing the locations of the servers hosting the meta replicas 060 */ 061 private final ImmutableMap<Integer, String> metaReplicaZNodes; 062 063 // znode containing ephemeral nodes of the regionservers 064 public final String rsZNode; 065 // znode containing ephemeral nodes of the draining regionservers 066 public final String drainingZNode; 067 // znode of currently active master 068 public final String masterAddressZNode; 069 // znode of this master in backup master directory, if not the active master 070 public final String backupMasterAddressesZNode; 071 // znode containing the current cluster state 072 public final String clusterStateZNode; 073 // znode used for table disabling/enabling 074 // Still used in hbase2 by MirroringTableStateManager; it mirrors internal table state out to 075 // zookeeper for hbase1 clients to make use of. If no hbase1 clients disable. See 076 // MirroringTableStateManager. To be removed in hbase3. 077 @Deprecated 078 public final String tableZNode; 079 // znode containing the unique cluster ID 080 public final String clusterIdZNode; 081 // znode used for log splitting work assignment 082 public final String splitLogZNode; 083 // znode containing the state of the load balancer 084 public final String balancerZNode; 085 // znode containing the state of region normalizer 086 public final String regionNormalizerZNode; 087 // znode containing the state of all switches, currently there are split and merge child node. 088 public final String switchZNode; 089 // znode containing namespace descriptors 090 public final String namespaceZNode; 091 // znode of indicating master maintenance mode 092 public final String masterMaintZNode; 093 094 // znode containing all replication state. 095 public final String replicationZNode; 096 // znode containing a list of all remote slave (i.e. peer) clusters. 097 public final String peersZNode; 098 // znode containing all replication queues 099 public final String queuesZNode; 100 // znode containing queues of hfile references to be replicated 101 public final String hfileRefsZNode; 102 // znode containing the state of the snapshot auto-cleanup 103 final String snapshotCleanupZNode; 104 105 public ZNodePaths(Configuration conf) { 106 baseZNode = conf.get(ZOOKEEPER_ZNODE_PARENT, DEFAULT_ZOOKEEPER_ZNODE_PARENT); 107 ImmutableMap.Builder<Integer, String> builder = ImmutableMap.builder(); 108 metaZNodePrefix = conf.get(META_ZNODE_PREFIX_CONF_KEY, META_ZNODE_PREFIX); 109 String defaultMetaReplicaZNode = ZNodePaths.joinZNode(baseZNode, metaZNodePrefix); 110 builder.put(DEFAULT_REPLICA_ID, defaultMetaReplicaZNode); 111 int numMetaReplicas = conf.getInt(META_REPLICAS_NUM, DEFAULT_META_REPLICA_NUM); 112 IntStream.range(1, numMetaReplicas) 113 .forEachOrdered(i -> builder.put(i, defaultMetaReplicaZNode + "-" + i)); 114 metaReplicaZNodes = builder.build(); 115 rsZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.rs", "rs")); 116 drainingZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.draining.rs", "draining")); 117 masterAddressZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.master", "master")); 118 backupMasterAddressesZNode = 119 joinZNode(baseZNode, conf.get("zookeeper.znode.backup.masters", "backup-masters")); 120 clusterStateZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.state", "running")); 121 tableZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.tableEnableDisable", "table")); 122 clusterIdZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.clusterId", "hbaseid")); 123 splitLogZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.splitlog", SPLIT_LOGDIR_NAME)); 124 balancerZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.balancer", "balancer")); 125 regionNormalizerZNode = 126 joinZNode(baseZNode, conf.get("zookeeper.znode.regionNormalizer", "normalizer")); 127 switchZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.switch", "switch")); 128 namespaceZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.namespace", "namespace")); 129 masterMaintZNode = 130 joinZNode(baseZNode, conf.get("zookeeper.znode.masterMaintenance", "master-maintenance")); 131 replicationZNode = joinZNode(baseZNode, conf.get("zookeeper.znode.replication", "replication")); 132 peersZNode = 133 joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.peers", "peers")); 134 queuesZNode = joinZNode(replicationZNode, conf.get("zookeeper.znode.replication.rs", "rs")); 135 hfileRefsZNode = joinZNode(replicationZNode, 136 conf.get("zookeeper.znode.replication.hfile.refs", "hfile-refs")); 137 snapshotCleanupZNode = joinZNode(baseZNode, 138 conf.get("zookeeper.znode.snapshot.cleanup", DEFAULT_SNAPSHOT_CLEANUP_ZNODE)); 139 } 140 141 @Override 142 public String toString() { 143 return new StringBuilder() 144 .append("ZNodePaths [baseZNode=").append(baseZNode) 145 .append(", metaReplicaZNodes=").append(metaReplicaZNodes) 146 .append(", rsZNode=").append(rsZNode) 147 .append(", drainingZNode=").append(drainingZNode) 148 .append(", masterAddressZNode=").append(masterAddressZNode) 149 .append(", backupMasterAddressesZNode=").append(backupMasterAddressesZNode) 150 .append(", clusterStateZNode=").append(clusterStateZNode) 151 .append(", tableZNode=").append(tableZNode) 152 .append(", clusterIdZNode=").append(clusterIdZNode) 153 .append(", splitLogZNode=").append(splitLogZNode) 154 .append(", balancerZNode=").append(balancerZNode) 155 .append(", regionNormalizerZNode=").append(regionNormalizerZNode) 156 .append(", switchZNode=").append(switchZNode) 157 .append(", namespaceZNode=").append(namespaceZNode) 158 .append(", masterMaintZNode=").append(masterMaintZNode) 159 .append(", replicationZNode=").append(replicationZNode) 160 .append(", peersZNode=").append(peersZNode) 161 .append(", queuesZNode=").append(queuesZNode) 162 .append(", hfileRefsZNode=").append(hfileRefsZNode) 163 .append(", snapshotCleanupZNode=").append(snapshotCleanupZNode) 164 .append("]").toString(); 165 } 166 167 /** 168 * @return true if the znode is a meta region replica 169 */ 170 public boolean isAnyMetaReplicaZNode(String node) { 171 return this.metaReplicaZNodes.containsValue(node); 172 } 173 174 /** 175 * @return Meta Replica ZNodes 176 */ 177 public Collection<String> getMetaReplicaZNodes() { 178 return this.metaReplicaZNodes.values(); 179 } 180 181 /** 182 * @return the znode string corresponding to a replicaId 183 */ 184 public String getZNodeForReplica(int replicaId) { 185 // return a newly created path but don't update the cache of paths 186 // This is mostly needed for tests that attempt to create meta replicas 187 // from outside the master 188 return Optional.ofNullable(metaReplicaZNodes.get(replicaId)) 189 .orElseGet(() -> metaReplicaZNodes.get(DEFAULT_REPLICA_ID) + "-" + replicaId); 190 } 191 192 /** 193 * Parses the meta replicaId from the passed path. 194 * @param path the name of the full path which includes baseZNode. 195 * @return replicaId 196 */ 197 public int getMetaReplicaIdFromPath(String path) { 198 // Extract the znode from path. The prefix is of the following format. 199 // baseZNode + PATH_SEPARATOR. 200 int prefixLen = baseZNode.length() + 1; 201 return getMetaReplicaIdFromZnode(path.substring(prefixLen)); 202 } 203 204 /** 205 * Parse the meta replicaId from the passed znode 206 * @param znode the name of the znode, does not include baseZNode 207 * @return replicaId 208 */ 209 public int getMetaReplicaIdFromZnode(String znode) { 210 return znode.equals(metaZNodePrefix)? 211 RegionInfo.DEFAULT_REPLICA_ID: 212 Integer.parseInt(znode.substring(metaZNodePrefix.length() + 1)); 213 } 214 215 /** 216 * @return True if meta znode. 217 */ 218 public boolean isMetaZNodePrefix(String znode) { 219 return znode != null && znode.startsWith(this.metaZNodePrefix); 220 } 221 222 /** 223 * Returns whether the znode is supposed to be readable by the client and DOES NOT contain 224 * sensitive information (world readable). 225 */ 226 public boolean isClientReadable(String node) { 227 // Developer notice: These znodes are world readable. DO NOT add more znodes here UNLESS 228 // all clients need to access this data to work. Using zk for sharing data to clients (other 229 // than service lookup case is not a recommended design pattern. 230 return node.equals(baseZNode) || isAnyMetaReplicaZNode(node) || 231 node.equals(masterAddressZNode) || node.equals(clusterIdZNode) || node.equals(rsZNode) || 232 // /hbase/table and /hbase/table/foo is allowed, /hbase/table-lock is not 233 node.equals(tableZNode) || node.startsWith(tableZNode + "/"); 234 } 235 236 /** 237 * Join the prefix znode name with the suffix znode name to generate a proper full znode name. 238 * <p> 239 * Assumes prefix does not end with slash and suffix does not begin with it. 240 * @param prefix beginning of znode name 241 * @param suffix ending of znode name 242 * @return result of properly joining prefix with suffix 243 */ 244 public static String joinZNode(String prefix, String suffix) { 245 return prefix + ZNodePaths.ZNODE_PATH_SEPARATOR + suffix; 246 } 247}