Search in sources :

Example 21 with InputAttemptIdentifier

use of org.apache.tez.runtime.library.common.InputAttemptIdentifier in project tez by apache.

the class TestIFile method testConcatenatedZlibPadding.

// test concatenated zlib input - as in multiple map outputs during shuffle
// This specific input is valid but the decompressor can leave lingering
// bytes between segments. If the lingering bytes aren't handled correctly,
// the stream will get out-of-sync.
@Test(timeout = 5000)
public void testConcatenatedZlibPadding() throws IOException, URISyntaxException {
    byte[] bytes;
    long compTotal = 0;
    // Known raw and compressed lengths of input
    long[] raws = { 2392, 102314, 42576, 31432, 25090 };
    long[] compressed = { 723, 25396, 10926, 8203, 6665 };
    CompressionCodecFactory codecFactory = new CompressionCodecFactory(new Configuration());
    codec = codecFactory.getCodecByClassName("org.apache.hadoop.io.compress.DefaultCodec");
    URL url = getClass().getClassLoader().getResource("TestIFile_concatenated_compressed.bin");
    assertNotEquals("IFileinput file must exist", null, url);
    Path p = new Path(url.toURI());
    FSDataInputStream inStream = localFs.open(p);
    for (int i = 0; i < 5; i++) {
        bytes = new byte[(int) raws[i]];
        assertEquals("Compressed stream out-of-sync", inStream.getPos(), compTotal);
        IFile.Reader.readToMemory(bytes, inStream, (int) compressed[i], codec, false, -1);
        compTotal += compressed[i];
        // Now read the data
        InMemoryReader inMemReader = new InMemoryReader(null, new InputAttemptIdentifier(0, 0), bytes, 0, bytes.length);
        DataInputBuffer keyIn = new DataInputBuffer();
        DataInputBuffer valIn = new DataInputBuffer();
        Deserializer<Text> keyDeserializer;
        Deserializer<IntWritable> valDeserializer;
        SerializationFactory serializationFactory = new SerializationFactory(defaultConf);
        keyDeserializer = serializationFactory.getDeserializer(Text.class);
        valDeserializer = serializationFactory.getDeserializer(IntWritable.class);
        keyDeserializer.open(keyIn);
        valDeserializer.open(valIn);
        while (inMemReader.nextRawKey(keyIn)) {
            inMemReader.nextRawValue(valIn);
        }
    }
    inStream.close();
}
Also used : Path(org.apache.hadoop.fs.Path) InMemoryReader(org.apache.tez.runtime.library.common.shuffle.orderedgrouped.InMemoryReader) Configuration(org.apache.hadoop.conf.Configuration) SerializationFactory(org.apache.hadoop.io.serializer.SerializationFactory) InputAttemptIdentifier(org.apache.tez.runtime.library.common.InputAttemptIdentifier) Text(org.apache.hadoop.io.Text) URL(java.net.URL) DataInputBuffer(org.apache.hadoop.io.DataInputBuffer) CompressionCodecFactory(org.apache.hadoop.io.compress.CompressionCodecFactory) FSDataInputStream(org.apache.hadoop.fs.FSDataInputStream) IntWritable(org.apache.hadoop.io.IntWritable) Test(org.junit.Test)

Example 22 with InputAttemptIdentifier

use of org.apache.tez.runtime.library.common.InputAttemptIdentifier in project tez by apache.

the class ShuffleManager method constructFetcherForHost.

@VisibleForTesting
Fetcher constructFetcherForHost(InputHost inputHost, Configuration conf) {
    Path lockDisk = null;
    if (sharedFetchEnabled) {
        // pick a single lock disk from the edge name's hashcode + host hashcode
        final int h = Math.abs(Objects.hashCode(this.srcNameTrimmed, inputHost.getHost()));
        lockDisk = new Path(this.localDisks[h % this.localDisks.length], "locks");
    }
    FetcherBuilder fetcherBuilder = new FetcherBuilder(ShuffleManager.this, httpConnectionParams, inputManager, inputContext.getApplicationId(), inputContext.getDagIdentifier(), jobTokenSecretMgr, srcNameTrimmed, conf, localFs, localDirAllocator, lockDisk, localDiskFetchEnabled, sharedFetchEnabled, localhostName, shufflePort, asyncHttp, verifyDiskChecksum, compositeFetch);
    if (codec != null) {
        fetcherBuilder.setCompressionParameters(codec);
    }
    fetcherBuilder.setIFileParams(ifileReadAhead, ifileReadAheadLength);
    // Remove obsolete inputs from the list being given to the fetcher. Also
    // remove from the obsolete list.
    PartitionToInputs pendingInputsOfOnePartitionRange = inputHost.clearAndGetOnePartitionRange();
    int includedMaps = 0;
    for (Iterator<InputAttemptIdentifier> inputIter = pendingInputsOfOnePartitionRange.getInputs().iterator(); inputIter.hasNext(); ) {
        InputAttemptIdentifier input = inputIter.next();
        // For pipelined shuffle.
        if (!validateInputAttemptForPipelinedShuffle(input)) {
            continue;
        }
        // Avoid adding attempts which have already completed.
        boolean alreadyCompleted;
        if (input instanceof CompositeInputAttemptIdentifier) {
            CompositeInputAttemptIdentifier compositeInput = (CompositeInputAttemptIdentifier) input;
            int nextClearBit = completedInputSet.nextClearBit(compositeInput.getInputIdentifier());
            int maxClearBit = compositeInput.getInputIdentifier() + compositeInput.getInputIdentifierCount();
            alreadyCompleted = nextClearBit > maxClearBit;
        } else {
            alreadyCompleted = completedInputSet.get(input.getInputIdentifier());
        }
        // Avoid adding attempts which have already completed or have been marked as OBSOLETE
        if (alreadyCompleted || obsoletedInputs.contains(input)) {
            inputIter.remove();
            continue;
        }
        // Check if max threshold is met
        if (includedMaps >= maxTaskOutputAtOnce) {
            inputIter.remove();
            // add to inputHost
            inputHost.addKnownInput(pendingInputsOfOnePartitionRange.getPartition(), pendingInputsOfOnePartitionRange.getPartitionCount(), input);
        } else {
            includedMaps++;
        }
    }
    if (inputHost.getNumPendingPartitions() > 0) {
        // add it to queue
        pendingHosts.add(inputHost);
    }
    for (InputAttemptIdentifier input : pendingInputsOfOnePartitionRange.getInputs()) {
        ShuffleEventInfo eventInfo = shuffleInfoEventsMap.get(input.getInputIdentifier());
        if (eventInfo != null) {
            eventInfo.scheduledForDownload = true;
        }
    }
    fetcherBuilder.assignWork(inputHost.getHost(), inputHost.getPort(), pendingInputsOfOnePartitionRange.getPartition(), pendingInputsOfOnePartitionRange.getPartitionCount(), pendingInputsOfOnePartitionRange.getInputs());
    if (LOG.isDebugEnabled()) {
        LOG.debug("Created Fetcher for host: " + inputHost.getHost() + ", info: " + inputHost.getAdditionalInfo() + ", with inputs: " + pendingInputsOfOnePartitionRange);
    }
    return fetcherBuilder.build();
}
Also used : Path(org.apache.hadoop.fs.Path) CompositeInputAttemptIdentifier(org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier) CompositeInputAttemptIdentifier(org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier) InputAttemptIdentifier(org.apache.tez.runtime.library.common.InputAttemptIdentifier) FetcherBuilder(org.apache.tez.runtime.library.common.shuffle.Fetcher.FetcherBuilder) PartitionToInputs(org.apache.tez.runtime.library.common.shuffle.InputHost.PartitionToInputs) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 23 with InputAttemptIdentifier

use of org.apache.tez.runtime.library.common.InputAttemptIdentifier in project tez by apache.

the class ShuffleInputEventHandlerImpl method processInputFailedEvent.

private void processInputFailedEvent(InputFailedEvent ife) {
    InputAttemptIdentifier srcAttemptIdentifier = new InputAttemptIdentifier(ife.getTargetIndex(), ife.getVersion());
    shuffleManager.obsoleteKnownInput(srcAttemptIdentifier);
}
Also used : CompositeInputAttemptIdentifier(org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier) InputAttemptIdentifier(org.apache.tez.runtime.library.common.InputAttemptIdentifier)

Example 24 with InputAttemptIdentifier

use of org.apache.tez.runtime.library.common.InputAttemptIdentifier in project tez by apache.

the class ShuffleInputEventHandlerImpl method processCompositeRoutedDataMovementEvent.

private void processCompositeRoutedDataMovementEvent(CompositeRoutedDataMovementEvent crdme, DataMovementEventPayloadProto shufflePayload, BitSet emptyPartitionsBitSet) throws IOException {
    int partitionId = crdme.getSourceIndex();
    if (LOG.isDebugEnabled()) {
        LOG.debug("DME srcIdx: " + partitionId + ", targetIndex: " + crdme.getTargetIndex() + ", count:" + crdme.getCount() + ", attemptNum: " + crdme.getVersion() + ", payload: " + ShuffleUtils.stringify(shufflePayload));
    }
    if (shufflePayload.hasEmptyPartitions()) {
        CompositeInputAttemptIdentifier compositeInputAttemptIdentifier = constructInputAttemptIdentifier(crdme.getTargetIndex(), crdme.getCount(), crdme.getVersion(), shufflePayload, false);
        boolean allPartitionsEmpty = true;
        for (int i = 0; i < crdme.getCount(); i++) {
            int srcPartitionId = partitionId + i;
            allPartitionsEmpty &= emptyPartitionsBitSet.get(srcPartitionId);
            if (emptyPartitionsBitSet.get(srcPartitionId)) {
                InputAttemptIdentifier srcAttemptIdentifier = compositeInputAttemptIdentifier.expand(i);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Source partition: " + srcPartitionId + " did not generate any data. SrcAttempt: [" + srcAttemptIdentifier + "]. Not fetching.");
                }
                numDmeEventsNoData.getAndIncrement();
                shuffleManager.addCompletedInputWithNoData(srcAttemptIdentifier);
            }
        }
        if (allPartitionsEmpty) {
            return;
        }
    }
    CompositeInputAttemptIdentifier srcAttemptIdentifier = constructInputAttemptIdentifier(crdme.getTargetIndex(), crdme.getCount(), crdme.getVersion(), shufflePayload, (useSharedInputs && partitionId == 0));
    shuffleManager.addKnownInput(shufflePayload.getHost(), shufflePayload.getPort(), srcAttemptIdentifier, partitionId);
}
Also used : CompositeInputAttemptIdentifier(org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier) CompositeInputAttemptIdentifier(org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier) InputAttemptIdentifier(org.apache.tez.runtime.library.common.InputAttemptIdentifier)

Example 25 with InputAttemptIdentifier

use of org.apache.tez.runtime.library.common.InputAttemptIdentifier in project tez by apache.

the class FetcherOrderedGrouped method copyMapOutput.

protected InputAttemptIdentifier[] copyMapOutput(MapHost host, DataInputStream input, InputAttemptIdentifier inputAttemptIdentifier) throws FetcherReadTimeoutException {
    MapOutput mapOutput = null;
    InputAttemptIdentifier srcAttemptId = null;
    long decompressedLength = 0;
    long compressedLength = 0;
    try {
        long startTime = System.currentTimeMillis();
        int partitionCount = 1;
        if (this.compositeFetch) {
            // Multiple partitions are fetched
            partitionCount = WritableUtils.readVInt(input);
        }
        ArrayList<MapOutputStat> mapOutputStats = new ArrayList<>(partitionCount);
        for (int mapOutputIndex = 0; mapOutputIndex < partitionCount; mapOutputIndex++) {
            MapOutputStat mapOutputStat = null;
            try {
                // Read the shuffle header
                ShuffleHeader header = new ShuffleHeader();
                // TODO Review: Multiple header reads in case of status WAIT ?
                header.readFields(input);
                if (!header.mapId.startsWith(InputAttemptIdentifier.PATH_PREFIX)) {
                    if (!stopped) {
                        badIdErrs.increment(1);
                        LOG.warn("Invalid map id: " + header.mapId + ", expected to start with " + InputAttemptIdentifier.PATH_PREFIX + ", partition: " + header.forReduce);
                        return new InputAttemptIdentifier[] { getNextRemainingAttempt() };
                    } else {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Already shutdown. Ignoring invalid map id error");
                        }
                        return EMPTY_ATTEMPT_ID_ARRAY;
                    }
                }
                if (header.getCompressedLength() == 0) {
                    // Empty partitions are already accounted for
                    continue;
                }
                mapOutputStat = new MapOutputStat(scheduler.getIdentifierForFetchedOutput(header.mapId, header.forReduce), header.uncompressedLength, header.compressedLength, header.forReduce);
                mapOutputStats.add(mapOutputStat);
            } catch (IllegalArgumentException e) {
                if (!stopped) {
                    badIdErrs.increment(1);
                    LOG.warn("Invalid map id ", e);
                    // the remaining because we dont know where to start reading from. YARN-1773
                    return new InputAttemptIdentifier[] { getNextRemainingAttempt() };
                } else {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Already shutdown. Ignoring invalid map id error. Exception: " + e.getClass().getName() + ", Message: " + e.getMessage());
                    }
                    return EMPTY_ATTEMPT_ID_ARRAY;
                }
            }
            // Do some basic sanity verification
            if (!verifySanity(mapOutputStat.compressedLength, mapOutputStat.decompressedLength, mapOutputStat.forReduce, remaining, mapOutputStat.srcAttemptId)) {
                if (!stopped) {
                    srcAttemptId = mapOutputStat.srcAttemptId;
                    if (srcAttemptId == null) {
                        srcAttemptId = getNextRemainingAttempt();
                        LOG.warn("Was expecting " + srcAttemptId + " but got null");
                    }
                    assert (srcAttemptId != null);
                    return new InputAttemptIdentifier[] { srcAttemptId };
                } else {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Already stopped. Ignoring verification failure.");
                    }
                    return EMPTY_ATTEMPT_ID_ARRAY;
                }
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("header: " + mapOutputStat.srcAttemptId + ", len: " + mapOutputStat.compressedLength + ", decomp len: " + mapOutputStat.decompressedLength);
            }
        }
        for (MapOutputStat mapOutputStat : mapOutputStats) {
            // Get the location for the map output - either in-memory or on-disk
            srcAttemptId = mapOutputStat.srcAttemptId;
            decompressedLength = mapOutputStat.decompressedLength;
            compressedLength = mapOutputStat.compressedLength;
            try {
                mapOutput = allocator.reserve(srcAttemptId, decompressedLength, compressedLength, id);
            } catch (IOException e) {
                if (!stopped) {
                    // Kill the reduce attempt
                    ioErrs.increment(1);
                    scheduler.reportLocalError(e);
                } else {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Already stopped. Ignoring error from merger.reserve");
                    }
                }
                return EMPTY_ATTEMPT_ID_ARRAY;
            }
            // Check if we can shuffle *now* ...
            if (mapOutput.getType() == Type.WAIT) {
                LOG.info("fetcher#" + id + " - MergerManager returned Status.WAIT ...");
                // Not an error but wait to process data.
                return EMPTY_ATTEMPT_ID_ARRAY;
            }
            // Go!
            if (LOG.isDebugEnabled()) {
                LOG.debug("fetcher#" + id + " about to shuffle output of map " + mapOutput.getAttemptIdentifier() + " decomp: " + decompressedLength + " len: " + compressedLength + " to " + mapOutput.getType());
            }
            if (mapOutput.getType() == Type.MEMORY) {
                ShuffleUtils.shuffleToMemory(mapOutput.getMemory(), input, (int) decompressedLength, (int) compressedLength, codec, ifileReadAhead, ifileReadAheadLength, LOG, mapOutput.getAttemptIdentifier());
            } else if (mapOutput.getType() == Type.DISK) {
                ShuffleUtils.shuffleToDisk(mapOutput.getDisk(), host.getHostIdentifier(), input, compressedLength, decompressedLength, LOG, mapOutput.getAttemptIdentifier(), ifileReadAhead, ifileReadAheadLength, verifyDiskChecksum);
            } else {
                throw new IOException("Unknown mapOutput type while fetching shuffle data:" + mapOutput.getType());
            }
            // Inform the shuffle scheduler
            long endTime = System.currentTimeMillis();
            // Reset retryStartTime as map task make progress if retried before.
            retryStartTime = 0;
            scheduler.copySucceeded(srcAttemptId, host, compressedLength, decompressedLength, endTime - startTime, mapOutput, false);
        }
        remaining.remove(inputAttemptIdentifier.toString());
    } catch (IOException | InternalError ioe) {
        if (stopped) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Not reporting fetch failure for exception during data copy: [" + ioe.getClass().getName() + ", " + ioe.getMessage() + "]");
            }
            cleanupCurrentConnection(true);
            if (mapOutput != null) {
                // Release resources
                mapOutput.abort();
            }
            // Don't need to put back - since that's handled by the invoker
            return EMPTY_ATTEMPT_ID_ARRAY;
        }
        if (shouldRetry(host, ioe)) {
            // release mem/file handles
            if (mapOutput != null) {
                mapOutput.abort();
            }
            throw new FetcherReadTimeoutException(ioe);
        }
        ioErrs.increment(1);
        if (srcAttemptId == null || mapOutput == null) {
            LOG.info("fetcher#" + id + " failed to read map header" + srcAttemptId + " decomp: " + decompressedLength + ", " + compressedLength, ioe);
            if (srcAttemptId == null) {
                return remaining.values().toArray(new InputAttemptIdentifier[remaining.values().size()]);
            } else {
                return new InputAttemptIdentifier[] { srcAttemptId };
            }
        }
        LOG.warn("Failed to shuffle output of " + srcAttemptId + " from " + host.getHostIdentifier(), ioe);
        // Inform the shuffle-scheduler
        mapOutput.abort();
        return new InputAttemptIdentifier[] { srcAttemptId };
    }
    return null;
}
Also used : FetcherReadTimeoutException(org.apache.tez.runtime.library.exceptions.FetcherReadTimeoutException) ArrayList(java.util.ArrayList) InputAttemptIdentifier(org.apache.tez.runtime.library.common.InputAttemptIdentifier) IOException(java.io.IOException)

Aggregations

InputAttemptIdentifier (org.apache.tez.runtime.library.common.InputAttemptIdentifier)55 CompositeInputAttemptIdentifier (org.apache.tez.runtime.library.common.CompositeInputAttemptIdentifier)41 Test (org.junit.Test)31 TezConfiguration (org.apache.tez.dag.api.TezConfiguration)17 Configuration (org.apache.hadoop.conf.Configuration)16 InputContext (org.apache.tez.runtime.api.InputContext)16 IOException (java.io.IOException)15 TezRuntimeConfiguration (org.apache.tez.runtime.library.api.TezRuntimeConfiguration)15 Path (org.apache.hadoop.fs.Path)10 LinkedList (java.util.LinkedList)8 Matchers.anyString (org.mockito.Matchers.anyString)8 VisibleForTesting (com.google.common.annotations.VisibleForTesting)7 TezCounters (org.apache.tez.common.counters.TezCounters)7 Event (org.apache.tez.runtime.api.Event)7 DataMovementEvent (org.apache.tez.runtime.api.events.DataMovementEvent)7 TezIndexRecord (org.apache.tez.runtime.library.common.sort.impl.TezIndexRecord)6 InvocationOnMock (org.mockito.invocation.InvocationOnMock)6 FetcherReadTimeoutException (org.apache.tez.runtime.library.exceptions.FetcherReadTimeoutException)5 URL (java.net.URL)4 ArrayList (java.util.ArrayList)4