Search in sources :

Example 6 with IgfsBlockLocation

use of org.apache.ignite.igfs.IgfsBlockLocation in project ignite by apache.

the class HadoopIgfs20FileSystemAbstractSelfTest method testZeroReplicationFactor.

/**
 * @throws Exception If failed.
 */
public void testZeroReplicationFactor() throws Exception {
    // This test doesn't make sense for any mode except of PRIMARY.
    if (mode == PRIMARY) {
        Path igfsHome = new Path(primaryFsUri);
        Path file = new Path(igfsHome, "someFile");
        try (FSDataOutputStream out = fs.create(file, EnumSet.noneOf(CreateFlag.class), Options.CreateOpts.perms(FsPermission.getDefault()), Options.CreateOpts.repFac((short) 1))) {
            out.write(new byte[1024 * 1024]);
        }
        IgniteFileSystem igfs = grid(0).fileSystem("igfs");
        IgfsPath filePath = new IgfsPath("/someFile");
        IgfsFile fileInfo = igfs.info(filePath);
        Collection<IgfsBlockLocation> locations = igfs.affinity(filePath, 0, fileInfo.length());
        assertEquals(1, locations.size());
        IgfsBlockLocation location = F.first(locations);
        assertEquals(1, location.nodeIds().size());
    }
}
Also used : Path(org.apache.hadoop.fs.Path) IgfsPath(org.apache.ignite.igfs.IgfsPath) CreateFlag(org.apache.hadoop.fs.CreateFlag) IgfsPath(org.apache.ignite.igfs.IgfsPath) IgniteFileSystem(org.apache.ignite.IgniteFileSystem) FSDataOutputStream(org.apache.hadoop.fs.FSDataOutputStream) IgfsBlockLocation(org.apache.ignite.igfs.IgfsBlockLocation) IgfsFile(org.apache.ignite.igfs.IgfsFile)

Example 7 with IgfsBlockLocation

use of org.apache.ignite.igfs.IgfsBlockLocation in project ignite by apache.

the class IgniteHadoopWeightedMapReducePlanner method igfsAffinityNodesForSplit.

/**
 * Get IGFS affinity nodes for split if possible.
 * <p>
 * Order in the returned collection *is* significant, meaning that nodes containing more data
 * go first. This way, the 1st nodes in the collection considered to be preferable for scheduling.
 *
 * @param split Input split.
 * @return IGFS affinity or {@code null} if IGFS is not available.
 * @throws IgniteCheckedException If failed.
 */
@Nullable
private Collection<UUID> igfsAffinityNodesForSplit(HadoopInputSplit split) throws IgniteCheckedException {
    if (split instanceof HadoopFileBlock) {
        HadoopFileBlock split0 = (HadoopFileBlock) split;
        if (IgniteFileSystem.IGFS_SCHEME.equalsIgnoreCase(split0.file().getScheme())) {
            HadoopIgfsEndpoint endpoint = new HadoopIgfsEndpoint(split0.file().getAuthority());
            IgfsEx igfs = (IgfsEx) ((IgniteEx) ignite).igfsx(endpoint.igfs());
            if (igfs != null && !igfs.isProxy(split0.file())) {
                IgfsPath path = new IgfsPath(split0.file());
                if (igfs.exists(path)) {
                    Collection<IgfsBlockLocation> blocks;
                    try {
                        blocks = igfs.affinity(path, split0.start(), split0.length());
                    } catch (IgniteException e) {
                        throw new IgniteCheckedException("Failed to get IGFS file block affinity [path=" + path + ", start=" + split0.start() + ", len=" + split0.length() + ']', e);
                    }
                    assert blocks != null;
                    if (blocks.size() == 1)
                        return blocks.iterator().next().nodeIds();
                    else {
                        // The most "local" nodes go first.
                        Map<UUID, Long> idToLen = new HashMap<>();
                        for (IgfsBlockLocation block : blocks) {
                            for (UUID id : block.nodeIds()) {
                                Long len = idToLen.get(id);
                                idToLen.put(id, len == null ? block.length() : block.length() + len);
                            }
                        }
                        // Sort the nodes in non-ascending order by contained data lengths.
                        Map<NodeIdAndLength, UUID> res = new TreeMap<>();
                        for (Map.Entry<UUID, Long> idToLenEntry : idToLen.entrySet()) {
                            UUID id = idToLenEntry.getKey();
                            res.put(new NodeIdAndLength(id, idToLenEntry.getValue()), id);
                        }
                        return new LinkedHashSet<>(res.values());
                    }
                }
            }
        }
    }
    return null;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) HashMap(java.util.HashMap) IdentityHashMap(java.util.IdentityHashMap) HadoopIgfsEndpoint(org.apache.ignite.internal.processors.hadoop.igfs.HadoopIgfsEndpoint) IgfsBlockLocation(org.apache.ignite.igfs.IgfsBlockLocation) HadoopFileBlock(org.apache.ignite.internal.processors.hadoop.HadoopFileBlock) TreeMap(java.util.TreeMap) IgfsPath(org.apache.ignite.igfs.IgfsPath) IgfsEx(org.apache.ignite.internal.processors.igfs.IgfsEx) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) UUID(java.util.UUID) HashMap(java.util.HashMap) Map(java.util.Map) IdentityHashMap(java.util.IdentityHashMap) TreeMap(java.util.TreeMap) Nullable(org.jetbrains.annotations.Nullable)

Example 8 with IgfsBlockLocation

use of org.apache.ignite.igfs.IgfsBlockLocation in project ignite by apache.

the class LocalIgfsSecondaryFileSystem method affinity.

/**
 * {@inheritDoc}
 */
@Override
public Collection<IgfsBlockLocation> affinity(IgfsPath path, long start, long len, long maxLen) throws IgniteException {
    File f = fileForPath(path);
    if (!f.exists())
        throw new IgfsPathNotFoundException("File not found: " + path);
    // Create fake block & fake affinity for blocks
    long blockSize = igfs.configuration().getBlockSize();
    if (maxLen <= 0)
        maxLen = Long.MAX_VALUE;
    assert maxLen > 0 : "maxLen : " + maxLen;
    long end = start + len;
    Collection<IgfsBlockLocation> blocks = new ArrayList<>((int) (len / maxLen));
    IgfsDataManager data = igfs.context().data();
    Collection<ClusterNode> lastNodes = null;
    long lastBlockIdx = -1;
    IgfsBlockLocationImpl lastBlock = null;
    for (long offset = start; offset < end; ) {
        long blockIdx = offset / blockSize;
        // Each step is min of maxLen and end of block.
        long lenStep = Math.min(maxLen - (lastBlock != null ? lastBlock.length() : 0), (blockIdx + 1) * blockSize - offset);
        lenStep = Math.min(lenStep, end - offset);
        // Create fake affinity key to map blocks of secondary filesystem to nodes.
        LocalFileSystemBlockKey affKey = new LocalFileSystemBlockKey(path, blockIdx);
        if (blockIdx != lastBlockIdx) {
            Collection<ClusterNode> nodes = data.affinityNodes(affKey);
            if (!nodes.equals(lastNodes) && lastNodes != null && lastBlock != null) {
                blocks.add(lastBlock);
                lastBlock = null;
            }
            lastNodes = nodes;
            lastBlockIdx = blockIdx;
        }
        if (lastBlock == null)
            lastBlock = new IgfsBlockLocationImpl(offset, lenStep, lastNodes);
        else
            lastBlock.increaseLength(lenStep);
        if (lastBlock.length() == maxLen || lastBlock.start() + lastBlock.length() == end) {
            blocks.add(lastBlock);
            lastBlock = null;
        }
        offset += lenStep;
    }
    return blocks;
}
Also used : IgfsDataManager(org.apache.ignite.internal.processors.igfs.IgfsDataManager) ClusterNode(org.apache.ignite.cluster.ClusterNode) LocalFileSystemBlockKey(org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemBlockKey) IgfsBlockLocationImpl(org.apache.ignite.internal.processors.igfs.IgfsBlockLocationImpl) ArrayList(java.util.ArrayList) IgfsBlockLocation(org.apache.ignite.igfs.IgfsBlockLocation) IgfsPathNotFoundException(org.apache.ignite.igfs.IgfsPathNotFoundException) IgfsFile(org.apache.ignite.igfs.IgfsFile) LocalFileSystemIgfsFile(org.apache.ignite.internal.processors.igfs.secondary.local.LocalFileSystemIgfsFile) File(java.io.File)

Example 9 with IgfsBlockLocation

use of org.apache.ignite.igfs.IgfsBlockLocation in project ignite by apache.

the class IgfsDataManager method affinity.

/**
 * Resolve affinity nodes for specified part of file.
 *
 * @param info File info to resolve affinity nodes for.
 * @param start Start position in the file.
 * @param len File part length to get affinity for.
 * @param maxLen Maximum block length.
 * @return Affinity blocks locations.
 * @throws IgniteCheckedException If failed.
 */
public Collection<IgfsBlockLocation> affinity(IgfsEntryInfo info, long start, long len, long maxLen) throws IgniteCheckedException {
    assert info.isFile() : "Failed to get affinity (not a file): " + info;
    assert start >= 0 : "Start position should not be negative: " + start;
    assert len >= 0 : "Part length should not be negative: " + len;
    if (log.isDebugEnabled())
        log.debug("Calculating affinity for file [info=" + info + ", start=" + start + ", len=" + len + ']');
    // Skip affinity resolving, if no data requested.
    if (len == 0)
        return Collections.emptyList();
    if (maxLen > 0) {
        maxLen -= maxLen % info.blockSize();
        // If maxLen is smaller than block size, then adjust it to the block size.
        if (maxLen < info.blockSize())
            maxLen = info.blockSize();
    } else
        maxLen = 0;
    // In case when affinity key is not null the whole file resides on one node.
    if (info.affinityKey() != null) {
        Collection<IgfsBlockLocation> res = new LinkedList<>();
        splitBlocks(start, len, maxLen, dataCache.affinity().mapKeyToPrimaryAndBackups(new IgfsBlockKey(info.id(), info.affinityKey(), info.evictExclude(), 0)), res);
        return res;
    }
    // Need to merge ranges affinity with non-colocated affinity.
    Deque<IgfsBlockLocation> res = new LinkedList<>();
    if (info.fileMap().ranges().isEmpty()) {
        affinity0(info, start, len, maxLen, res);
        return res;
    }
    long pos = start;
    long end = start + len;
    for (IgfsFileAffinityRange range : info.fileMap().ranges()) {
        if (log.isDebugEnabled())
            log.debug("Checking range [range=" + range + ", pos=" + pos + ']');
        // If current position is less than range start, add non-colocated affinity ranges.
        if (range.less(pos)) {
            long partEnd = Math.min(end, range.startOffset());
            affinity0(info, pos, partEnd - pos, maxLen, res);
            pos = partEnd;
        }
        IgfsBlockLocation last = res.peekLast();
        if (range.belongs(pos)) {
            long partEnd = Math.min(range.endOffset() + 1, end);
            Collection<ClusterNode> affNodes = dataCache.affinity().mapKeyToPrimaryAndBackups(range.affinityKey());
            if (log.isDebugEnabled())
                log.debug("Calculated affinity for range [start=" + pos + ", end=" + partEnd + ", nodes=" + F.nodeIds(affNodes) + ", range=" + range + ", affNodes=" + F.nodeIds(affNodes) + ']');
            if (last != null && equal(last.nodeIds(), F.viewReadOnly(affNodes, F.node2id()))) {
                // Merge with the previous block in result.
                res.removeLast();
                splitBlocks(last.start(), last.length() + partEnd - pos, maxLen, affNodes, res);
            } else
                // Do not merge with the previous block.
                splitBlocks(pos, partEnd - pos, maxLen, affNodes, res);
            pos = partEnd;
        }
        if (log.isDebugEnabled())
            log.debug("Finished range check [range=" + range + ", pos=" + pos + ", res=" + res + ']');
        if (pos == end)
            break;
    }
    // Final chunk.
    if (pos != end)
        affinity0(info, pos, end, maxLen, res);
    return res;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgfsBlockLocation(org.apache.ignite.igfs.IgfsBlockLocation) LinkedList(java.util.LinkedList)

Example 10 with IgfsBlockLocation

use of org.apache.ignite.igfs.IgfsBlockLocation in project ignite by apache.

the class IgfsDataManager method affinity0.

/**
 * Calculates non-colocated affinity for given file info and given region of file.
 *
 * @param info File info.
 * @param start Start offset.
 * @param len Length.
 * @param maxLen Maximum allowed split length.
 * @param res Result collection to add regions to.
 */
private void affinity0(IgfsEntryInfo info, long start, long len, long maxLen, Deque<IgfsBlockLocation> res) {
    long firstGrpIdx = start / grpBlockSize;
    long limitGrpIdx = (start + len + grpBlockSize - 1) / grpBlockSize;
    if (limitGrpIdx - firstGrpIdx > Integer.MAX_VALUE)
        throw new IgfsException("Failed to get affinity (range is too wide)" + " [info=" + info + ", start=" + start + ", len=" + len + ']');
    if (log.isDebugEnabled())
        log.debug("Mapping file region [fileInfo=" + info + ", start=" + start + ", len=" + len + ']');
    for (long grpIdx = firstGrpIdx; grpIdx < limitGrpIdx; grpIdx++) {
        // Boundaries of the block.
        long blockStart;
        long blockLen;
        // The first block.
        if (grpIdx == firstGrpIdx) {
            blockStart = start % grpBlockSize;
            blockLen = Math.min(grpBlockSize - blockStart, len);
        } else // The last block.
        if (grpIdx == limitGrpIdx - 1) {
            blockStart = 0;
            blockLen = (start + len - 1) % grpBlockSize + 1;
        } else // Other blocks.
        {
            blockStart = 0;
            blockLen = grpBlockSize;
        }
        // Affinity for the first block in the group.
        IgfsBlockKey key = new IgfsBlockKey(info.id(), info.affinityKey(), info.evictExclude(), grpIdx * grpSize);
        Collection<ClusterNode> affNodes = dataCache.affinity().mapKeyToPrimaryAndBackups(key);
        if (log.isDebugEnabled())
            log.debug("Mapped key to nodes [key=" + key + ", nodes=" + F.nodeIds(affNodes) + ", blockStart=" + blockStart + ", blockLen=" + blockLen + ']');
        IgfsBlockLocation last = res.peekLast();
        // Merge with previous affinity block location?
        if (last != null && equal(last.nodeIds(), F.viewReadOnly(affNodes, F.node2id()))) {
            // Remove previous incomplete value.
            res.removeLast();
            // Update affinity block location with merged one.
            splitBlocks(last.start(), last.length() + blockLen, maxLen, affNodes, res);
        } else
            splitBlocks(grpIdx * grpBlockSize + blockStart, blockLen, maxLen, affNodes, res);
    }
    if (log.isDebugEnabled())
        log.debug("Calculated file affinity [info=" + info + ", start=" + start + ", len=" + len + ", res=" + res + ']');
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) IgfsException(org.apache.ignite.igfs.IgfsException) IgfsBlockLocation(org.apache.ignite.igfs.IgfsBlockLocation)

Aggregations

IgfsBlockLocation (org.apache.ignite.igfs.IgfsBlockLocation)17 IgfsPath (org.apache.ignite.igfs.IgfsPath)10 ClusterNode (org.apache.ignite.cluster.ClusterNode)6 IgfsFile (org.apache.ignite.igfs.IgfsFile)6 ArrayList (java.util.ArrayList)3 UUID (java.util.UUID)3 IgniteFileSystem (org.apache.ignite.IgniteFileSystem)3 OutputStream (java.io.OutputStream)2 HashMap (java.util.HashMap)2 BlockLocation (org.apache.hadoop.fs.BlockLocation)2 FSDataOutputStream (org.apache.hadoop.fs.FSDataOutputStream)2 Path (org.apache.hadoop.fs.Path)2 IgniteException (org.apache.ignite.IgniteException)2 IgfsOutputStream (org.apache.ignite.igfs.IgfsOutputStream)2 HadoopIgfsEndpoint (org.apache.ignite.internal.processors.hadoop.igfs.HadoopIgfsEndpoint)2 IgniteUuid (org.apache.ignite.lang.IgniteUuid)2 Nullable (org.jetbrains.annotations.Nullable)2 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 FileOutputStream (java.io.FileOutputStream)1