Example usage for org.apache.hadoop.hdfs.protocol LocatedBlock getStartOffset

List of usage examples for org.apache.hadoop.hdfs.protocol LocatedBlock getStartOffset

Introduction

In this page you can find the example usage for org.apache.hadoop.hdfs.protocol LocatedBlock getStartOffset.

Prototype

public long getStartOffset() 

Source Link

Usage

From source file:com.bigstep.datalake.JsonUtil.java

License:Apache License

/** Convert a LocatedBlock to a Json map. */
private static Map<String, Object> toJsonMap(final LocatedBlock locatedblock) throws IOException {
    if (locatedblock == null) {
        return null;
    }//from w ww  . ja v a2 s.  c o  m

    final Map<String, Object> m = new TreeMap<String, Object>();
    m.put("blockToken", toJsonMap(locatedblock.getBlockToken()));
    m.put("isCorrupt", locatedblock.isCorrupt());
    m.put("startOffset", locatedblock.getStartOffset());
    m.put("block", toJsonMap(locatedblock.getBlock()));
    m.put("locations", toJsonArray(locatedblock.getLocations()));
    m.put("cachedLocations", toJsonArray(locatedblock.getCachedLocations()));
    return m;
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

/**
 * Get blocks in the specified range./*from ww  w .  j  av a  2 s. c  o m*/
 * Includes only the complete blocks.
 * Fetch them from the namenode if not cached.
 */
private List<LocatedBlock> getFinalizedBlockRange(long offset, long length) throws IOException {
    synchronized (infoLock) {
        assert (locatedBlocks != null) : "locatedBlocks is null";
        List<LocatedBlock> blockRange = new ArrayList<LocatedBlock>();
        // search cached blocks first
        int blockIdx = locatedBlocks.findBlock(offset);
        if (blockIdx < 0) { // block is not cached
            blockIdx = LocatedBlocks.getInsertIndex(blockIdx);
        }
        long remaining = length;
        long curOff = offset;
        while (remaining > 0) {
            LocatedBlock blk = null;
            if (blockIdx < locatedBlocks.locatedBlockCount())
                blk = locatedBlocks.get(blockIdx);
            if (blk == null || curOff < blk.getStartOffset()) {
                LocatedBlocks newBlocks;
                newBlocks = dfsClient.getLocatedBlocks(src, curOff, remaining);
                locatedBlocks.insertRange(blockIdx, newBlocks.getLocatedBlocks());
                continue;
            }
            assert curOff >= blk.getStartOffset() : "Block not found";
            blockRange.add(blk);
            long bytesRead = blk.getStartOffset() + blk.getBlockSize() - curOff;
            remaining -= bytesRead;
            curOff += bytesRead;
            blockIdx++;
        }
        return blockRange;
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

/**
 * Open a DataInputStream to a DataNode so that it can be read from.
 * We get block ID and the IDs of the destinations at startup, from the namenode.
 *///from  w ww  .  j av a 2  s  . co  m
private synchronized DatanodeInfo blockSeekTo(long target) throws IOException {
    if (target >= getFileLength()) {
        throw new IOException("Attempted to read past end of file");
    }

    // Will be getting a new BlockReader.
    closeCurrentBlockReader();

    //
    // Connect to best DataNode for desired Block, with potential offset
    //
    DatanodeInfo chosenNode = null;
    int refetchToken = 1; // only need to get a new access token once
    int refetchEncryptionKey = 1; // only need to get a new encryption key once

    boolean connectFailedOnce = false;

    while (true) {
        //
        // Compute desired block
        //
        LocatedBlock targetBlock = getBlockAt(target);

        // update current position
        this.pos = target;
        this.blockEnd = targetBlock.getStartOffset() + targetBlock.getBlockSize() - 1;
        this.currentLocatedBlock = targetBlock;

        assert (target == pos) : "Wrong postion " + pos + " expect " + target;
        long offsetIntoBlock = target - targetBlock.getStartOffset();

        DNAddrPair retval = chooseDataNode(targetBlock, null);
        chosenNode = retval.info;
        InetSocketAddress targetAddr = retval.addr;
        StorageType storageType = retval.storageType;

        try {
            ExtendedBlock blk = targetBlock.getBlock();
            Token<BlockTokenIdentifier> accessToken = targetBlock.getBlockToken();
            CachingStrategy curCachingStrategy;
            boolean shortCircuitForbidden;
            synchronized (infoLock) {
                curCachingStrategy = cachingStrategy;
                shortCircuitForbidden = shortCircuitForbidden();
            }
            blockReader = new BlockReaderFactory(dfsClient.getConf()).setInetSocketAddress(targetAddr)
                    .setRemotePeerFactory(dfsClient).setDatanodeInfo(chosenNode).setStorageType(storageType)
                    .setFileName(src).setBlock(blk).setBlockToken(accessToken).setStartOffset(offsetIntoBlock)
                    .setVerifyChecksum(verifyChecksum).setClientName(dfsClient.clientName)
                    .setLength(blk.getNumBytes() - offsetIntoBlock).setCachingStrategy(curCachingStrategy)
                    .setAllowShortCircuitLocalReads(!shortCircuitForbidden)
                    .setClientCacheContext(dfsClient.getClientContext()).setUserGroupInformation(dfsClient.ugi)
                    .setConfiguration(dfsClient.getConfiguration()).build();
            if (connectFailedOnce) {
                DFSClient.LOG.info("Successfully connected to " + targetAddr + " for " + blk);
            }
            return chosenNode;
        } catch (IOException ex) {
            if (ex instanceof InvalidEncryptionKeyException && refetchEncryptionKey > 0) {
                DFSClient.LOG.info("Will fetch a new encryption key and retry, "
                        + "encryption key was invalid when connecting to " + targetAddr + " : " + ex);
                // The encryption key used is invalid.
                refetchEncryptionKey--;
                dfsClient.clearDataEncryptionKey();
            } else if (refetchToken > 0 && tokenRefetchNeeded(ex, targetAddr)) {
                refetchToken--;
                fetchBlockAt(target);
            } else {
                connectFailedOnce = true;
                DFSClient.LOG.warn("Failed to connect to " + targetAddr + " for block"
                        + ", add to deadNodes and continue. " + ex, ex);
                // Put chosen node into dead list, continue
                addToDeadNodes(chosenNode);
            }
        }
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

private DNAddrPair chooseDataNode(LocatedBlock block, Collection<DatanodeInfo> ignoredNodes)
        throws IOException {
    while (true) {
        try {//w w w .j  av  a2s  .  c o m
            return getBestNodeDNAddrPair(block, ignoredNodes);
        } catch (IOException ie) {
            String errMsg = getBestNodeDNAddrPairErrorString(block.getLocations(), deadNodes, ignoredNodes);
            String blockInfo = block.getBlock() + " file=" + src;
            if (failures >= dfsClient.getMaxBlockAcquireFailures()) {
                String description = "Could not obtain block: " + blockInfo;
                DFSClient.LOG.warn(description + errMsg + ". Throwing a BlockMissingException");
                throw new BlockMissingException(src, description, block.getStartOffset());
            }

            DatanodeInfo[] nodes = block.getLocations();
            if (nodes == null || nodes.length == 0) {
                DFSClient.LOG.info("No node available for " + blockInfo);
            }
            DFSClient.LOG.info("Could not obtain " + block.getBlock() + " from any node: " + ie + errMsg
                    + ". Will get new block locations from namenode and retry...");
            try {
                // Introducing a random factor to the wait time before another retry.
                // The wait time is dependent on # of failures and a random factor.
                // At the first time of getting a BlockMissingException, the wait time
                // is a random number between 0..3000 ms. If the first retry
                // still fails, we will wait 3000 ms grace period before the 2nd retry.
                // Also at the second retry, the waiting window is expanded to 6000 ms
                // alleviating the request rate from the server. Similarly the 3rd retry
                // will wait 6000ms grace period before retry and the waiting window is
                // expanded to 9000ms.
                final int timeWindow = dfsClient.getConf().getTimeWindow();
                double waitTime = timeWindow * failures + // grace period for the last round of attempt
                        timeWindow * (failures + 1) * DFSUtil.getRandom().nextDouble(); // expanding time window for each failure
                DFSClient.LOG.warn("DFS chooseDataNode: got # " + (failures + 1)
                        + " IOException, will wait for " + waitTime + " msec.");
                Thread.sleep((long) waitTime);
            } catch (InterruptedException iex) {
            }
            deadNodes.clear(); // 2nd option is to remove only nodes[blockId]
            openInfo();
            block = getBlockAt(block.getStartOffset());
            failures++;
            continue;
        }
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

private void fetchBlockByteRange(LocatedBlock block, long start, long end, byte[] buf, int offset,
        Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap) throws IOException {
    block = getBlockAt(block.getStartOffset());
    while (true) {
        DNAddrPair addressPair = chooseDataNode(block, null);
        try {//w  w  w  .  j  a  v a2 s.com
            actualGetFromOneDataNode(addressPair, block, start, end, buf, offset, corruptedBlockMap);
            return;
        } catch (IOException e) {
            // Ignore. Already processed inside the function.
            // Loop through to try the next node.
        }
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

private void actualGetFromOneDataNode(final DNAddrPair datanode, LocatedBlock block, final long start,
        final long end, byte[] buf, int offset, Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap)
        throws IOException {
    DFSClientFaultInjector.get().startFetchFromDatanode();
    int refetchToken = 1; // only need to get a new access token once
    int refetchEncryptionKey = 1; // only need to get a new encryption key once

    while (true) {
        // cached block locations may have been updated by chooseDataNode()
        // or fetchBlockAt(). Always get the latest list of locations at the
        // start of the loop.
        CachingStrategy curCachingStrategy;
        boolean allowShortCircuitLocalReads;
        block = getBlockAt(block.getStartOffset());
        synchronized (infoLock) {
            curCachingStrategy = cachingStrategy;
            allowShortCircuitLocalReads = !shortCircuitForbidden();
        }/* w  w w  .ja v a 2s  .c  o  m*/
        DatanodeInfo chosenNode = datanode.info;
        InetSocketAddress targetAddr = datanode.addr;
        StorageType storageType = datanode.storageType;
        BlockReader reader = null;

        try {
            DFSClientFaultInjector.get().fetchFromDatanodeException();
            Token<BlockTokenIdentifier> blockToken = block.getBlockToken();
            int len = (int) (end - start + 1);
            reader = new BlockReaderFactory(dfsClient.getConf()).setInetSocketAddress(targetAddr)
                    .setRemotePeerFactory(dfsClient).setDatanodeInfo(chosenNode).setStorageType(storageType)
                    .setFileName(src).setBlock(block.getBlock()).setBlockToken(blockToken).setStartOffset(start)
                    .setVerifyChecksum(verifyChecksum).setClientName(dfsClient.clientName).setLength(len)
                    .setCachingStrategy(curCachingStrategy)
                    .setAllowShortCircuitLocalReads(allowShortCircuitLocalReads)
                    .setClientCacheContext(dfsClient.getClientContext()).setUserGroupInformation(dfsClient.ugi)
                    .setConfiguration(dfsClient.getConfiguration()).build();
            int nread = reader.readAll(buf, offset, len);
            updateReadStatistics(readStatistics, nread, reader);

            if (nread != len) {
                throw new IOException(
                        "truncated return from reader.read(): " + "excpected " + len + ", got " + nread);
            }
            DFSClientFaultInjector.get().readFromDatanodeDelay();
            return;
        } catch (ChecksumException e) {
            String msg = "fetchBlockByteRange(). Got a checksum exception for " + src + " at "
                    + block.getBlock() + ":" + e.getPos() + " from " + chosenNode;
            DFSClient.LOG.warn(msg);
            // we want to remember what we have tried
            addIntoCorruptedBlockMap(block.getBlock(), chosenNode, corruptedBlockMap);
            addToDeadNodes(chosenNode);
            throw new IOException(msg);
        } catch (IOException e) {
            if (e instanceof InvalidEncryptionKeyException && refetchEncryptionKey > 0) {
                DFSClient.LOG.info("Will fetch a new encryption key and retry, "
                        + "encryption key was invalid when connecting to " + targetAddr + " : " + e);
                // The encryption key used is invalid.
                refetchEncryptionKey--;
                dfsClient.clearDataEncryptionKey();
                continue;
            } else if (refetchToken > 0 && tokenRefetchNeeded(e, targetAddr)) {
                refetchToken--;
                try {
                    fetchBlockAt(block.getStartOffset());
                } catch (IOException fbae) {
                    // ignore IOE, since we can retry it later in a loop
                }
                continue;
            } else {
                String msg = "Failed to connect to " + targetAddr + " for file " + src + " for block "
                        + block.getBlock() + ":" + e;
                DFSClient.LOG.warn("Connection failure: " + msg, e);
                addToDeadNodes(chosenNode);
                throw new IOException(msg);
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

/**
 * Like {@link #fetchBlockByteRange(LocatedBlock, long, long, byte[], int, Map)} except we start up a second, parallel, 'hedged' read
 * if the first read is taking longer than configured amount of
 * time. We then wait on which ever read returns first.
 *//* w w  w . ja va2 s.c  o  m*/
private void hedgedFetchBlockByteRange(LocatedBlock block, long start, long end, byte[] buf, int offset,
        Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap) throws IOException {
    ArrayList<Future<ByteBuffer>> futures = new ArrayList<Future<ByteBuffer>>();
    CompletionService<ByteBuffer> hedgedService = new ExecutorCompletionService<ByteBuffer>(
            dfsClient.getHedgedReadsThreadPool());
    ArrayList<DatanodeInfo> ignored = new ArrayList<DatanodeInfo>();
    ByteBuffer bb = null;
    int len = (int) (end - start + 1);
    int hedgedReadId = 0;
    block = getBlockAt(block.getStartOffset());
    while (true) {
        // see HDFS-6591, this metric is used to verify/catch unnecessary loops
        hedgedReadOpsLoopNumForTesting++;
        DNAddrPair chosenNode = null;
        // there is no request already executing.
        if (futures.isEmpty()) {
            // chooseDataNode is a commitment. If no node, we go to
            // the NN to reget block locations. Only go here on first read.
            chosenNode = chooseDataNode(block, ignored);
            bb = ByteBuffer.wrap(buf, offset, len);
            Callable<ByteBuffer> getFromDataNodeCallable = getFromOneDataNode(chosenNode, block, start, end, bb,
                    corruptedBlockMap, hedgedReadId++);
            Future<ByteBuffer> firstRequest = hedgedService.submit(getFromDataNodeCallable);
            futures.add(firstRequest);
            try {
                Future<ByteBuffer> future = hedgedService.poll(dfsClient.getHedgedReadTimeout(),
                        TimeUnit.MILLISECONDS);
                if (future != null) {
                    future.get();
                    return;
                }
                if (DFSClient.LOG.isDebugEnabled()) {
                    DFSClient.LOG.debug("Waited " + dfsClient.getHedgedReadTimeout() + "ms to read from "
                            + chosenNode.info + "; spawning hedged read");
                }
                // Ignore this node on next go around.
                ignored.add(chosenNode.info);
                dfsClient.getHedgedReadMetrics().incHedgedReadOps();
                continue; // no need to refresh block locations
            } catch (InterruptedException e) {
                // Ignore
            } catch (ExecutionException e) {
                // Ignore already logged in the call.
            }
        } else {
            // We are starting up a 'hedged' read. We have a read already
            // ongoing. Call getBestNodeDNAddrPair instead of chooseDataNode.
            // If no nodes to do hedged reads against, pass.
            try {
                try {
                    chosenNode = getBestNodeDNAddrPair(block, ignored);
                } catch (IOException ioe) {
                    chosenNode = chooseDataNode(block, ignored);
                }
                bb = ByteBuffer.allocate(len);
                Callable<ByteBuffer> getFromDataNodeCallable = getFromOneDataNode(chosenNode, block, start, end,
                        bb, corruptedBlockMap, hedgedReadId++);
                Future<ByteBuffer> oneMoreRequest = hedgedService.submit(getFromDataNodeCallable);
                futures.add(oneMoreRequest);
            } catch (IOException ioe) {
                if (DFSClient.LOG.isDebugEnabled()) {
                    DFSClient.LOG.debug("Failed getting node for hedged read: " + ioe.getMessage());
                }
            }
            // if not succeeded. Submit callables for each datanode in a loop, wait
            // for a fixed interval and get the result from the fastest one.
            try {
                ByteBuffer result = getFirstToComplete(hedgedService, futures);
                // cancel the rest.
                cancelAll(futures);
                if (result.array() != buf) { // compare the array pointers
                    dfsClient.getHedgedReadMetrics().incHedgedReadWins();
                    System.arraycopy(result.array(), result.position(), buf, offset, len);
                } else {
                    dfsClient.getHedgedReadMetrics().incHedgedReadOps();
                }
                return;
            } catch (InterruptedException ie) {
                // Ignore and retry
            }
            // We got here if exception. Ignore this node on next go around IFF
            // we found a chosenNode to hedge read against.
            if (chosenNode != null && chosenNode.info != null) {
                ignored.add(chosenNode.info);
            }
        }
    }
}

From source file:com.mellanox.r4h.DFSInputStream.java

License:Apache License

private int pread(long position, byte[] buffer, int offset, int length) throws IOException {
    // sanity checks
    dfsClient.checkOpen();/*from w  ww .j av a 2  s  .c o  m*/
    if (closed.get()) {
        throw new IOException("Stream closed");
    }
    failures = 0;
    long filelen = getFileLength();
    if ((position < 0) || (position >= filelen)) {
        return -1;
    }
    int realLen = length;
    if ((position + length) > filelen) {
        realLen = (int) (filelen - position);
    }

    // determine the block and byte range within the block
    // corresponding to position and realLen
    List<LocatedBlock> blockRange = getBlockRange(position, realLen);
    int remaining = realLen;
    Map<ExtendedBlock, Set<DatanodeInfo>> corruptedBlockMap = new HashMap<ExtendedBlock, Set<DatanodeInfo>>();
    for (LocatedBlock blk : blockRange) {
        long targetStart = position - blk.getStartOffset();
        long bytesToRead = Math.min(remaining, blk.getBlockSize() - targetStart);
        try {
            if (dfsClient.isHedgedReadsEnabled()) {
                hedgedFetchBlockByteRange(blk, targetStart, targetStart + bytesToRead - 1, buffer, offset,
                        corruptedBlockMap);
            } else {
                fetchBlockByteRange(blk, targetStart, targetStart + bytesToRead - 1, buffer, offset,
                        corruptedBlockMap);
            }
        } finally {
            // Check and report if any block replicas are corrupted.
            // BlockMissingException may be caught if all block replicas are
            // corrupted.
            reportCheckSumFailure(corruptedBlockMap, blk.getLocations().length);
        }

        remaining -= bytesToRead;
        position += bytesToRead;
        offset += bytesToRead;
    }
    assert remaining == 0 : "Wrong number of bytes read.";
    if (dfsClient.stats != null) {
        dfsClient.stats.incrementBytesRead(realLen);
    }
    return realLen;
}

From source file:io.hops.erasure_coding.TestMapReduceBlockRepairManager.java

License:Apache License

@Test
public void testCorruptedRepair() throws IOException, InterruptedException {
    DistributedFileSystem dfs = (DistributedFileSystem) getFileSystem();
    TestDfsClient testDfsClient = new TestDfsClient(getConfig());
    testDfsClient.injectIntoDfs(dfs);/*from   www . ja v  a 2  s. c o  m*/

    MapReduceEncodingManager encodingManager = new MapReduceEncodingManager(conf);

    Util.createRandomFile(dfs, testFile, seed, TEST_BLOCK_COUNT, DFS_TEST_BLOCK_SIZE);
    Codec.initializeCodecs(conf);
    FileStatus testFileStatus = dfs.getFileStatus(testFile);
    EncodingPolicy policy = new EncodingPolicy("src", (short) 1);
    encodingManager.encodeFile(policy, testFile, parityFile);

    // Busy waiting until the encoding is done
    while (encodingManager.computeReports().size() > 0) {
        ;
    }

    String path = testFileStatus.getPath().toUri().getPath();
    int blockToLoose = new Random(seed)
            .nextInt((int) (testFileStatus.getLen() / testFileStatus.getBlockSize()));
    LocatedBlock lb = dfs.getClient().getLocatedBlocks(path, 0, Long.MAX_VALUE).get(blockToLoose);
    DataNodeUtil.loseBlock(getCluster(), lb);
    List<LocatedBlock> lostBlocks = new ArrayList<LocatedBlock>();
    lostBlocks.add(lb);
    LocatedBlocks locatedBlocks = new LocatedBlocks(0, false, lostBlocks, null, true);
    testDfsClient.setMissingLocatedBlocks(locatedBlocks);
    LOG.info("Loosing block " + lb.toString());
    getCluster().triggerBlockReports();

    dfs.getClient().addBlockChecksum(testFile.toUri().getPath(),
            (int) (lb.getStartOffset() / lb.getBlockSize()), 0);

    MapReduceBlockRepairManager repairManager = new MapReduceBlockRepairManager(conf);
    repairManager.repairSourceBlocks("src", testFile, parityFile);

    while (true) {
        List<Report> reports = repairManager.computeReports();
        if (reports.size() == 0) {
            break;
        }
        LOG.info(reports.get(0).getStatus());
        System.out.println("WAIT");
        Thread.sleep(1000);
    }

    try {
        FSDataInputStream in = dfs.open(testFile);
        byte[] buff = new byte[TEST_BLOCK_COUNT * DFS_TEST_BLOCK_SIZE];
        in.readFully(0, buff);
        fail("Repair succeeded with bogus checksum.");
    } catch (BlockMissingException e) {
    }
}

From source file:org.openflamingo.remote.thrift.thriftfs.ThriftUtils.java

License:Apache License

public static Block toThrift(LocatedBlock block, String path, Map<DatanodeID, Integer> thriftPorts)
        throws java.io.IOException {
    if (block == null) {
        return new Block();
    }//  ww w  .  j  ava 2  s.  c om

    List<DatanodeInfo> nodes = new ArrayList<DatanodeInfo>();
    for (org.apache.hadoop.hdfs.protocol.DatanodeInfo n : block.getLocations()) {
        DatanodeInfo node = toThrift(n, thriftPorts);
        if (node.getThriftPort() != Constants.UNKNOWN_THRIFT_PORT) {
            nodes.add(node);
        }
    }

    org.apache.hadoop.hdfs.protocol.Block b = block.getBlock();
    return new Block(b.getBlockId(), path, b.getNumBytes(), b.getGenerationStamp(), nodes,
            block.getStartOffset(), block.getBlockToken().encodeToUrlString());
}