ProvidedStorageMap(RwLock lock, BlockManager bm, Configuration conf) throws IOException { storageId = conf.get(DFSConfigKeys.DFS_PROVIDER_STORAGEUUID, DFSConfigKeys.DFS_PROVIDER_STORAGEUUID_DEFAULT); providedEnabled = conf.getBoolean( DFSConfigKeys.DFS_NAMENODE_PROVIDED_ENABLED, DFSConfigKeys.DFS_NAMENODE_PROVIDED_ENABLED_DEFAULT); if (!providedEnabled) { // disable mapping aliasMap = null; providedDescriptor = null; providedStorageInfo = null; return; } DatanodeStorage ds = new DatanodeStorage( storageId, State.NORMAL, StorageType.PROVIDED); providedDescriptor = new ProvidedDescriptor(); providedStorageInfo = providedDescriptor.createProvidedStorage(ds); this.defaultReplication = conf.getInt(DFSConfigKeys.DFS_REPLICATION_KEY, DFSConfigKeys.DFS_REPLICATION_DEFAULT); this.bm = bm; this.lock = lock; // load block reader into storage Class<? extends BlockAliasMap> aliasMapClass = conf.getClass( DFSConfigKeys.DFS_PROVIDED_ALIASMAP_CLASS, TextFileRegionAliasMap.class, BlockAliasMap.class); aliasMap = ReflectionUtils.newInstance(aliasMapClass, conf); LOG.info("Loaded alias map class: " + aliasMap.getClass() + " storage: " + providedStorageInfo); }
.activeProvidedDatanodes(); count++) { dn = chooseProvidedDatanode(excludedUUids); locs.add(new DatanodeInfoWithStorage(
DatanodeDescriptor choose(DatanodeDescriptor client) { return choose(client, Collections.<String>emptySet()); }
/** * @param dn datanode descriptor * @param s data node storage * @return the {@link DatanodeStorageInfo} for the specified datanode. * If {@code s} corresponds to a provided storage, the storage info * representing provided storage is returned. * @throws IOException */ DatanodeStorageInfo getStorage(DatanodeDescriptor dn, DatanodeStorage s) throws IOException { if (providedEnabled && storageId.equals(s.getStorageID())) { if (StorageType.PROVIDED.equals(s.getStorageType())) { if (providedStorageInfo.getState() == State.FAILED && s.getState() == State.NORMAL) { providedStorageInfo.setState(State.NORMAL); LOG.info("Provided storage transitioning to state " + State.NORMAL); } if (dn.getStorageInfo(s.getStorageID()) == null) { dn.injectStorage(providedStorageInfo); } processProvidedStorageReport(); return providedDescriptor.getProvidedStorage(dn, s); } LOG.warn("Reserved storage {} reported as non-provided from {}", s, dn); } return dn.getStorageInfo(s.getStorageID()); }
private void processProvidedStorageReport() throws IOException { assert lock.hasWriteLock() : "Not holding write lock"; if (providedStorageInfo.getBlockReportCount() == 0 || providedDescriptor.activeProvidedDatanodes() == 0) { LOG.info("Calling process first blk report from storage: " + providedStorageInfo); // first pass; periodic refresh should call bm.processReport BlockAliasMap.Reader<BlockAlias> reader = aliasMap.getReader(null, bm.getBlockPoolId()); if (reader != null) { bm.processFirstBlockReport(providedStorageInfo, new ProvidedBlockList(reader.iterator())); } } }
DatanodeDescriptor choose(DatanodeDescriptor client, Set<String> excludedUUids) { // exact match for now if (client != null && !excludedUUids.contains(client.getDatanodeUuid())) { DatanodeDescriptor dn = dns.get(client.getDatanodeUuid()); if (dn != null) { return dn; } } // prefer live nodes first. DatanodeDescriptor dn = chooseRandomNode(excludedUUids, true); if (dn == null) { dn = chooseRandomNode(excludedUUids, false); } return dn; }
@Override void setState(DatanodeStorage.State state) { if (state == State.FAILED) { // The state should change to FAILED only when there are no active // datanodes with PROVIDED storage. ProvidedDescriptor dn = (ProvidedDescriptor) getDatanodeDescriptor(); if (dn.activeProvidedDatanodes() == 0) { LOG.info("Provided storage {} transitioning to state {}", this, State.FAILED); super.setState(state); } } else { super.setState(state); } }
DatanodeDescriptor chooseRandom(DatanodeStorageInfo... excludedStorages) { Set<String> excludedNodes = new HashSet<>(); if (excludedStorages != null) { for (int i = 0; i < excludedStorages.length; i++) { DatanodeDescriptor dn = excludedStorages[i].getDatanodeDescriptor(); String uuid = dn.getDatanodeUuid(); excludedNodes.add(uuid); } } return choose(null, excludedNodes); }
@Override void addBlockToBeReplicated(Block block, DatanodeStorageInfo[] targets) { // pick a random datanode, delegate to it DatanodeDescriptor node = chooseRandom(targets); if (node != null) { node.addBlockToBeReplicated(block, targets); } else { LOG.error("Cannot find a source node to replicate block: " + block + " from"); } }
public void removeDatanode(DatanodeDescriptor dnToRemove) { if (providedEnabled) { assert lock.hasWriteLock() : "Not holding write lock"; providedDescriptor.remove(dnToRemove); // if all datanodes fail, set the block report count to 0 if (providedDescriptor.activeProvidedDatanodes() == 0) { providedStorageInfo.setBlockReportCount(0); } } }
@Override boolean removeBlock(BlockInfo b) { ProvidedDescriptor dn = (ProvidedDescriptor) getDatanodeDescriptor(); if (dn.activeProvidedDatanodes() == 0) { return super.removeBlock(b); } else { return false; } }
@Override LocatedBlocks build() { return build(providedDescriptor.chooseRandom()); } }
/** * Choose a datanode that reported a volume of {@link StorageType} PROVIDED. * * @return the {@link DatanodeDescriptor} corresponding to a datanode that * reported a volume with {@link StorageType} PROVIDED. If multiple * datanodes report a PROVIDED volume, one is chosen uniformly at * random. */ public DatanodeDescriptor chooseProvidedDatanode() { return providedDescriptor.chooseRandom(); }