Search in sources :

Example 1 with ShortCircuitReplica

use of org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica in project hadoop by apache.

the class BlockReaderFactory method requestFileDescriptors.

/**
   * Request file descriptors from a DomainPeer.
   *
   * @param peer   The peer to use for communication.
   * @param slot   If non-null, the shared memory slot to associate with the
   *               new ShortCircuitReplica.
   *
   * @return  A ShortCircuitReplica object if we could communicate with the
   *          datanode; null, otherwise.
   * @throws  IOException If we encountered an I/O exception while communicating
   *          with the datanode.
   */
private ShortCircuitReplicaInfo requestFileDescriptors(DomainPeer peer, Slot slot) throws IOException {
    ShortCircuitCache cache = clientContext.getShortCircuitCache();
    final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(peer.getOutputStream()));
    SlotId slotId = slot == null ? null : slot.getSlotId();
    new Sender(out).requestShortCircuitFds(block, token, slotId, 1, failureInjector.getSupportsReceiptVerification());
    DataInputStream in = new DataInputStream(peer.getInputStream());
    BlockOpResponseProto resp = BlockOpResponseProto.parseFrom(PBHelperClient.vintPrefixed(in));
    DomainSocket sock = peer.getDomainSocket();
    failureInjector.injectRequestFileDescriptorsFailure();
    switch(resp.getStatus()) {
        case SUCCESS:
            byte[] buf = new byte[1];
            FileInputStream[] fis = new FileInputStream[2];
            sock.recvFileInputStreams(fis, buf, 0, buf.length);
            ShortCircuitReplica replica = null;
            try {
                ExtendedBlockId key = new ExtendedBlockId(block.getBlockId(), block.getBlockPoolId());
                if (buf[0] == USE_RECEIPT_VERIFICATION.getNumber()) {
                    LOG.trace("Sending receipt verification byte for slot {}", slot);
                    sock.getOutputStream().write(0);
                }
                replica = new ShortCircuitReplica(key, fis[0], fis[1], cache, Time.monotonicNow(), slot);
                return new ShortCircuitReplicaInfo(replica);
            } catch (IOException e) {
                // This indicates an error reading from disk, or a format error.  Since
                // it's not a socket communication problem, we return null rather than
                // throwing an exception.
                LOG.warn(this + ": error creating ShortCircuitReplica.", e);
                return null;
            } finally {
                if (replica == null) {
                    IOUtilsClient.cleanup(DFSClient.LOG, fis[0], fis[1]);
                }
            }
        case ERROR_UNSUPPORTED:
            if (!resp.hasShortCircuitAccessVersion()) {
                LOG.warn("short-circuit read access is disabled for " + "DataNode " + datanode + ".  reason: " + resp.getMessage());
                clientContext.getDomainSocketFactory().disableShortCircuitForPath(pathInfo.getPath());
            } else {
                LOG.warn("short-circuit read access for the file " + fileName + " is disabled for DataNode " + datanode + ".  reason: " + resp.getMessage());
            }
            return null;
        case ERROR_ACCESS_TOKEN:
            String msg = "access control error while " + "attempting to set up short-circuit access to " + fileName + resp.getMessage();
            LOG.debug("{}:{}", this, msg);
            return new ShortCircuitReplicaInfo(new InvalidToken(msg));
        default:
            LOG.warn(this + ": unknown response code " + resp.getStatus() + " while attempting to set up short-circuit access. " + resp.getMessage());
            clientContext.getDomainSocketFactory().disableShortCircuitForPath(pathInfo.getPath());
            return null;
    }
}
Also used : ExtendedBlockId(org.apache.hadoop.hdfs.ExtendedBlockId) DataOutputStream(java.io.DataOutputStream) BlockOpResponseProto(org.apache.hadoop.hdfs.protocol.proto.DataTransferProtos.BlockOpResponseProto) IOException(java.io.IOException) ShortCircuitCache(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache) DataInputStream(java.io.DataInputStream) FileInputStream(java.io.FileInputStream) Sender(org.apache.hadoop.hdfs.protocol.datatransfer.Sender) SlotId(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitShm.SlotId) ShortCircuitReplica(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica) DomainSocket(org.apache.hadoop.net.unix.DomainSocket) InvalidToken(org.apache.hadoop.security.token.SecretManager.InvalidToken) ShortCircuitReplicaInfo(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplicaInfo) BufferedOutputStream(java.io.BufferedOutputStream)

Example 2 with ShortCircuitReplica

use of org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica in project hadoop by apache.

the class TestEnhancedByteBufferAccess method testZeroCopyMmapCache.

@Test
public void testZeroCopyMmapCache() throws Exception {
    HdfsConfiguration conf = initZeroCopyTest();
    MiniDFSCluster cluster = null;
    final Path TEST_PATH = new Path("/a");
    final int TEST_FILE_LENGTH = 5 * BLOCK_SIZE;
    final int RANDOM_SEED = 23453;
    final String CONTEXT = "testZeroCopyMmapCacheContext";
    FSDataInputStream fsIn = null;
    ByteBuffer[] results = { null, null, null, null };
    DistributedFileSystem fs = null;
    conf.set(HdfsClientConfigKeys.DFS_CLIENT_CONTEXT, CONTEXT);
    cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build();
    cluster.waitActive();
    fs = cluster.getFileSystem();
    DFSTestUtil.createFile(fs, TEST_PATH, TEST_FILE_LENGTH, (short) 1, RANDOM_SEED);
    try {
        DFSTestUtil.waitReplication(fs, TEST_PATH, (short) 1);
    } catch (InterruptedException e) {
        Assert.fail("unexpected InterruptedException during " + "waitReplication: " + e);
    } catch (TimeoutException e) {
        Assert.fail("unexpected TimeoutException during " + "waitReplication: " + e);
    }
    fsIn = fs.open(TEST_PATH);
    byte[] original = new byte[TEST_FILE_LENGTH];
    IOUtils.readFully(fsIn, original, 0, TEST_FILE_LENGTH);
    fsIn.close();
    fsIn = fs.open(TEST_PATH);
    final ShortCircuitCache cache = ClientContext.get(CONTEXT, conf).getShortCircuitCache();
    cache.accept(new CountingVisitor(0, 5, 5, 0));
    results[0] = fsIn.read(null, BLOCK_SIZE, EnumSet.of(ReadOption.SKIP_CHECKSUMS));
    fsIn.seek(0);
    results[1] = fsIn.read(null, BLOCK_SIZE, EnumSet.of(ReadOption.SKIP_CHECKSUMS));
    // The mmap should be of the first block of the file.
    final ExtendedBlock firstBlock = DFSTestUtil.getFirstBlock(fs, TEST_PATH);
    cache.accept(new CacheVisitor() {

        @Override
        public void visit(int numOutstandingMmaps, Map<ExtendedBlockId, ShortCircuitReplica> replicas, Map<ExtendedBlockId, InvalidToken> failedLoads, LinkedMap evictable, LinkedMap evictableMmapped) {
            ShortCircuitReplica replica = replicas.get(new ExtendedBlockId(firstBlock.getBlockId(), firstBlock.getBlockPoolId()));
            Assert.assertNotNull(replica);
            Assert.assertTrue(replica.hasMmap());
            // The replica should not yet be evictable, since we have it open.
            Assert.assertNull(replica.getEvictableTimeNs());
        }
    });
    // Read more blocks.
    results[2] = fsIn.read(null, BLOCK_SIZE, EnumSet.of(ReadOption.SKIP_CHECKSUMS));
    results[3] = fsIn.read(null, BLOCK_SIZE, EnumSet.of(ReadOption.SKIP_CHECKSUMS));
    // we should have 3 mmaps, 1 evictable
    cache.accept(new CountingVisitor(3, 5, 2, 0));
    // using a very quick timeout)
    for (ByteBuffer buffer : results) {
        if (buffer != null) {
            fsIn.releaseBuffer(buffer);
        }
    }
    fsIn.close();
    GenericTestUtils.waitFor(new Supplier<Boolean>() {

        public Boolean get() {
            final MutableBoolean finished = new MutableBoolean(false);
            cache.accept(new CacheVisitor() {

                @Override
                public void visit(int numOutstandingMmaps, Map<ExtendedBlockId, ShortCircuitReplica> replicas, Map<ExtendedBlockId, InvalidToken> failedLoads, LinkedMap evictable, LinkedMap evictableMmapped) {
                    finished.setValue(evictableMmapped.isEmpty());
                }
            });
            return finished.booleanValue();
        }
    }, 10, 60000);
    cache.accept(new CountingVisitor(0, -1, -1, -1));
    fs.close();
    cluster.shutdown();
}
Also used : ExtendedBlockId(org.apache.hadoop.hdfs.ExtendedBlockId) LinkedMap(org.apache.commons.collections.map.LinkedMap) CacheVisitor(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache.CacheVisitor) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) TimeoutException(java.util.concurrent.TimeoutException) MiniDFSCluster(org.apache.hadoop.hdfs.MiniDFSCluster) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) ExtendedBlock(org.apache.hadoop.hdfs.protocol.ExtendedBlock) HdfsConfiguration(org.apache.hadoop.hdfs.HdfsConfiguration) DistributedFileSystem(org.apache.hadoop.hdfs.DistributedFileSystem) ShortCircuitCache(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache) ByteBuffer(java.nio.ByteBuffer) ShortCircuitReplica(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica) InvalidToken(org.apache.hadoop.security.token.SecretManager.InvalidToken) Map(java.util.Map) LinkedMap(org.apache.commons.collections.map.LinkedMap) Test(org.junit.Test)

Example 3 with ShortCircuitReplica

use of org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica in project hadoop by apache.

the class TestEnhancedByteBufferAccess method waitForReplicaAnchorStatus.

private void waitForReplicaAnchorStatus(final ShortCircuitCache cache, final ExtendedBlock block, final boolean expectedIsAnchorable, final boolean expectedIsAnchored, final int expectedOutstandingMmaps) throws Exception {
    GenericTestUtils.waitFor(new Supplier<Boolean>() {

        @Override
        public Boolean get() {
            final MutableBoolean result = new MutableBoolean(false);
            cache.accept(new CacheVisitor() {

                @Override
                public void visit(int numOutstandingMmaps, Map<ExtendedBlockId, ShortCircuitReplica> replicas, Map<ExtendedBlockId, InvalidToken> failedLoads, LinkedMap evictable, LinkedMap evictableMmapped) {
                    Assert.assertEquals(expectedOutstandingMmaps, numOutstandingMmaps);
                    ShortCircuitReplica replica = replicas.get(ExtendedBlockId.fromExtendedBlock(block));
                    Assert.assertNotNull(replica);
                    Slot slot = replica.getSlot();
                    if ((expectedIsAnchorable != slot.isAnchorable()) || (expectedIsAnchored != slot.isAnchored())) {
                        LOG.info("replica " + replica + " has isAnchorable = " + slot.isAnchorable() + ", isAnchored = " + slot.isAnchored() + ".  Waiting for isAnchorable = " + expectedIsAnchorable + ", isAnchored = " + expectedIsAnchored);
                        return;
                    }
                    result.setValue(true);
                }
            });
            return result.toBoolean();
        }
    }, 10, 60000);
}
Also used : ShortCircuitReplica(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) CacheVisitor(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache.CacheVisitor) Slot(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitShm.Slot) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) Map(java.util.Map) LinkedMap(org.apache.commons.collections.map.LinkedMap) LinkedMap(org.apache.commons.collections.map.LinkedMap)

Example 4 with ShortCircuitReplica

use of org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica in project hadoop by apache.

the class TestBlockReaderLocal method runBlockReaderLocalTest.

public void runBlockReaderLocalTest(BlockReaderLocalTest test, boolean checksum, long readahead) throws IOException {
    Assume.assumeThat(DomainSocket.getLoadingFailureReason(), equalTo(null));
    MiniDFSCluster cluster = null;
    HdfsConfiguration conf = new HdfsConfiguration();
    conf.setBoolean(HdfsClientConfigKeys.Read.ShortCircuit.SKIP_CHECKSUM_KEY, !checksum);
    conf.setLong(HdfsClientConfigKeys.DFS_BYTES_PER_CHECKSUM_KEY, BlockReaderLocalTest.BYTES_PER_CHECKSUM);
    conf.set(DFSConfigKeys.DFS_CHECKSUM_TYPE_KEY, "CRC32C");
    conf.setLong(HdfsClientConfigKeys.DFS_CLIENT_CACHE_READAHEAD, readahead);
    test.setConfiguration(conf);
    FileInputStream dataIn = null, metaIn = null;
    final Path TEST_PATH = new Path("/a");
    final long RANDOM_SEED = 4567L;
    BlockReaderLocal blockReaderLocal = null;
    FSDataInputStream fsIn = null;
    byte[] original = new byte[BlockReaderLocalTest.TEST_LENGTH];
    FileSystem fs = null;
    ShortCircuitShm shm = null;
    RandomAccessFile raf = null;
    try {
        cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build();
        cluster.waitActive();
        fs = cluster.getFileSystem();
        DFSTestUtil.createFile(fs, TEST_PATH, BlockReaderLocalTest.TEST_LENGTH, (short) 1, RANDOM_SEED);
        try {
            DFSTestUtil.waitReplication(fs, TEST_PATH, (short) 1);
        } catch (InterruptedException e) {
            Assert.fail("unexpected InterruptedException during " + "waitReplication: " + e);
        } catch (TimeoutException e) {
            Assert.fail("unexpected TimeoutException during " + "waitReplication: " + e);
        }
        fsIn = fs.open(TEST_PATH);
        IOUtils.readFully(fsIn, original, 0, BlockReaderLocalTest.TEST_LENGTH);
        fsIn.close();
        fsIn = null;
        ExtendedBlock block = DFSTestUtil.getFirstBlock(fs, TEST_PATH);
        File dataFile = cluster.getBlockFile(0, block);
        File metaFile = cluster.getBlockMetadataFile(0, block);
        ShortCircuitCache shortCircuitCache = ClientContext.getFromConf(conf).getShortCircuitCache();
        cluster.shutdown();
        cluster = null;
        test.setup(dataFile, checksum);
        FileInputStream[] streams = { new FileInputStream(dataFile), new FileInputStream(metaFile) };
        dataIn = streams[0];
        metaIn = streams[1];
        ExtendedBlockId key = new ExtendedBlockId(block.getBlockId(), block.getBlockPoolId());
        raf = new RandomAccessFile(new File(sockDir.getDir().getAbsolutePath(), UUID.randomUUID().toString()), "rw");
        raf.setLength(8192);
        FileInputStream shmStream = new FileInputStream(raf.getFD());
        shm = new ShortCircuitShm(ShmId.createRandom(), shmStream);
        ShortCircuitReplica replica = new ShortCircuitReplica(key, dataIn, metaIn, shortCircuitCache, Time.now(), shm.allocAndRegisterSlot(ExtendedBlockId.fromExtendedBlock(block)));
        blockReaderLocal = new BlockReaderLocal.Builder(new DfsClientConf.ShortCircuitConf(conf)).setFilename(TEST_PATH.getName()).setBlock(block).setShortCircuitReplica(replica).setCachingStrategy(new CachingStrategy(false, readahead)).setVerifyChecksum(checksum).setTracer(FsTracer.get(conf)).build();
        dataIn = null;
        metaIn = null;
        test.doTest(blockReaderLocal, original);
        // BlockReaderLocal should not alter the file position.
        Assert.assertEquals(0, streams[0].getChannel().position());
        Assert.assertEquals(0, streams[1].getChannel().position());
    } finally {
        if (fsIn != null)
            fsIn.close();
        if (fs != null)
            fs.close();
        if (cluster != null)
            cluster.shutdown();
        if (dataIn != null)
            dataIn.close();
        if (metaIn != null)
            metaIn.close();
        if (blockReaderLocal != null)
            blockReaderLocal.close();
        if (shm != null)
            shm.free();
        if (raf != null)
            raf.close();
    }
}
Also used : Path(org.apache.hadoop.fs.Path) MiniDFSCluster(org.apache.hadoop.hdfs.MiniDFSCluster) ExtendedBlockId(org.apache.hadoop.hdfs.ExtendedBlockId) ExtendedBlock(org.apache.hadoop.hdfs.protocol.ExtendedBlock) CachingStrategy(org.apache.hadoop.hdfs.server.datanode.CachingStrategy) HdfsConfiguration(org.apache.hadoop.hdfs.HdfsConfiguration) ShortCircuitShm(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitShm) ShortCircuitCache(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache) FileInputStream(java.io.FileInputStream) RandomAccessFile(java.io.RandomAccessFile) ShortCircuitReplica(org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica) FileSystem(org.apache.hadoop.fs.FileSystem) FSDataInputStream(org.apache.hadoop.fs.FSDataInputStream) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) TimeoutException(java.util.concurrent.TimeoutException)

Aggregations

ShortCircuitReplica (org.apache.hadoop.hdfs.shortcircuit.ShortCircuitReplica)4 ExtendedBlockId (org.apache.hadoop.hdfs.ExtendedBlockId)3 ShortCircuitCache (org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache)3 FileInputStream (java.io.FileInputStream)2 Map (java.util.Map)2 TimeoutException (java.util.concurrent.TimeoutException)2 LinkedMap (org.apache.commons.collections.map.LinkedMap)2 MutableBoolean (org.apache.commons.lang.mutable.MutableBoolean)2 HdfsConfiguration (org.apache.hadoop.hdfs.HdfsConfiguration)2 MiniDFSCluster (org.apache.hadoop.hdfs.MiniDFSCluster)2 ExtendedBlock (org.apache.hadoop.hdfs.protocol.ExtendedBlock)2 CacheVisitor (org.apache.hadoop.hdfs.shortcircuit.ShortCircuitCache.CacheVisitor)2 InvalidToken (org.apache.hadoop.security.token.SecretManager.InvalidToken)2 BufferedOutputStream (java.io.BufferedOutputStream)1 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1 File (java.io.File)1 IOException (java.io.IOException)1 RandomAccessFile (java.io.RandomAccessFile)1 ByteBuffer (java.nio.ByteBuffer)1