Search in sources :

Example 1 with WriteChunkRequestProto

use of org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto in project ozone by apache.

the class ContainerStateMachine method handleWriteChunk.

private CompletableFuture<Message> handleWriteChunk(ContainerCommandRequestProto requestProto, long entryIndex, long term, long startTime) {
    final WriteChunkRequestProto write = requestProto.getWriteChunk();
    RaftServer server = ratisServer.getServer();
    Preconditions.checkArgument(!write.getData().isEmpty());
    try {
        if (server.getDivision(gid).getInfo().isLeader()) {
            stateMachineDataCache.put(entryIndex, write.getData());
        }
    } catch (InterruptedException ioe) {
        Thread.currentThread().interrupt();
        return completeExceptionally(ioe);
    } catch (IOException ioe) {
        return completeExceptionally(ioe);
    }
    DispatcherContext context = new DispatcherContext.Builder().setTerm(term).setLogIndex(entryIndex).setStage(DispatcherContext.WriteChunkStage.WRITE_DATA).setContainer2BCSIDMap(container2BCSIDMap).build();
    CompletableFuture<Message> raftFuture = new CompletableFuture<>();
    // ensure the write chunk happens asynchronously in writeChunkExecutor pool
    // thread.
    CompletableFuture<ContainerCommandResponseProto> writeChunkFuture = CompletableFuture.supplyAsync(() -> {
        try {
            return runCommand(requestProto, context);
        } catch (Exception e) {
            LOG.error("{}: writeChunk writeStateMachineData failed: blockId" + "{} logIndex {} chunkName {}", gid, write.getBlockID(), entryIndex, write.getChunkData().getChunkName(), e);
            metrics.incNumWriteDataFails();
            // write chunks go in parallel. It's possible that one write chunk
            // see the stateMachine is marked unhealthy by other parallel thread
            stateMachineHealthy.set(false);
            raftFuture.completeExceptionally(e);
            throw e;
        }
    }, getChunkExecutor(requestProto.getWriteChunk()));
    writeChunkFutureMap.put(entryIndex, writeChunkFuture);
    if (LOG.isDebugEnabled()) {
        LOG.debug("{}: writeChunk writeStateMachineData : blockId" + "{} logIndex {} chunkName {}", gid, write.getBlockID(), entryIndex, write.getChunkData().getChunkName());
    }
    // Remove the future once it finishes execution from the
    // writeChunkFutureMap.
    writeChunkFuture.thenApply(r -> {
        if (r.getResult() != ContainerProtos.Result.SUCCESS && r.getResult() != ContainerProtos.Result.CONTAINER_NOT_OPEN && r.getResult() != ContainerProtos.Result.CLOSED_CONTAINER_IO) {
            StorageContainerException sce = new StorageContainerException(r.getMessage(), r.getResult());
            LOG.error(gid + ": writeChunk writeStateMachineData failed: blockId" + write.getBlockID() + " logIndex " + entryIndex + " chunkName " + write.getChunkData().getChunkName() + " Error message: " + r.getMessage() + " Container Result: " + r.getResult());
            metrics.incNumWriteDataFails();
            // If the write fails currently we mark the stateMachine as unhealthy.
            // This leads to pipeline close. Any change in that behavior requires
            // handling the entry for the write chunk in cache.
            stateMachineHealthy.set(false);
            raftFuture.completeExceptionally(sce);
        } else {
            metrics.incNumBytesWrittenCount(requestProto.getWriteChunk().getChunkData().getLen());
            if (LOG.isDebugEnabled()) {
                LOG.debug(gid + ": writeChunk writeStateMachineData  completed: blockId" + write.getBlockID() + " logIndex " + entryIndex + " chunkName " + write.getChunkData().getChunkName());
            }
            raftFuture.complete(r::toByteString);
            metrics.recordWriteStateMachineCompletion(Time.monotonicNowNanos() - startTime);
        }
        writeChunkFutureMap.remove(entryIndex);
        return r;
    });
    return raftFuture;
}
Also used : WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto) Message(org.apache.ratis.protocol.Message) ContainerCommandRequestMessage(org.apache.hadoop.hdds.ratis.ContainerCommandRequestMessage) RaftServer(org.apache.ratis.server.RaftServer) IOException(java.io.IOException) InvalidProtocolBufferException(org.apache.ratis.thirdparty.com.google.protobuf.InvalidProtocolBufferException) StateMachineException(org.apache.ratis.protocol.exceptions.StateMachineException) StorageContainerException(org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException) ContainerNotOpenException(org.apache.hadoop.hdds.scm.container.common.helpers.ContainerNotOpenException) IOException(java.io.IOException) ContainerCommandResponseProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto) CompletableFuture(java.util.concurrent.CompletableFuture) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ContainerController(org.apache.hadoop.ozone.container.ozoneimpl.ContainerController) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) CheckedSupplier(org.apache.ratis.util.function.CheckedSupplier) ContainerDispatcher(org.apache.hadoop.ozone.container.common.interfaces.ContainerDispatcher) Logger(org.slf4j.Logger) Consumer(java.util.function.Consumer) RaftServer(org.apache.ratis.server.RaftServer) StorageContainerException(org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException)

Example 2 with WriteChunkRequestProto

use of org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto in project ozone by apache.

the class ContainerStateMachine method startTransaction.

@Override
public TransactionContext startTransaction(RaftClientRequest request) throws IOException {
    long startTime = Time.monotonicNowNanos();
    final ContainerCommandRequestProto proto = message2ContainerCommandRequestProto(request.getMessage());
    Preconditions.checkArgument(request.getRaftGroupId().equals(gid));
    try {
        dispatcher.validateContainerCommand(proto);
    } catch (IOException ioe) {
        if (ioe instanceof ContainerNotOpenException) {
            metrics.incNumContainerNotOpenVerifyFailures();
        } else {
            metrics.incNumStartTransactionVerifyFailures();
            LOG.error("startTransaction validation failed on leader", ioe);
        }
        TransactionContext ctxt = TransactionContext.newBuilder().setClientRequest(request).setStateMachine(this).setServerRole(RaftPeerRole.LEADER).build();
        ctxt.setException(ioe);
        return ctxt;
    }
    if (proto.getCmdType() == Type.WriteChunk) {
        final WriteChunkRequestProto write = proto.getWriteChunk();
        // create the log entry proto
        final WriteChunkRequestProto commitWriteChunkProto = WriteChunkRequestProto.newBuilder().setBlockID(write.getBlockID()).setChunkData(write.getChunkData()).build();
        ContainerCommandRequestProto commitContainerCommandProto = ContainerCommandRequestProto.newBuilder(proto).setWriteChunk(commitWriteChunkProto).setTraceID(proto.getTraceID()).build();
        Preconditions.checkArgument(write.hasData());
        Preconditions.checkArgument(!write.getData().isEmpty());
        return TransactionContext.newBuilder().setClientRequest(request).setStateMachine(this).setServerRole(RaftPeerRole.LEADER).setStateMachineContext(startTime).setStateMachineData(write.getData()).setLogData(commitContainerCommandProto.toByteString()).build();
    } else {
        return TransactionContext.newBuilder().setClientRequest(request).setStateMachine(this).setServerRole(RaftPeerRole.LEADER).setStateMachineContext(startTime).setLogData(proto.toByteString()).build();
    }
}
Also used : WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto) TransactionContext(org.apache.ratis.statemachine.TransactionContext) ContainerCommandRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto) IOException(java.io.IOException) ContainerNotOpenException(org.apache.hadoop.hdds.scm.container.common.helpers.ContainerNotOpenException)

Example 3 with WriteChunkRequestProto

use of org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto in project ozone by apache.

the class TestHddsDispatcher method getReadChunkRequest.

/**
 * Creates container read chunk request using input container write chunk
 * request.
 *
 * @param writeChunkRequest - Input container write chunk request
 * @return container read chunk request
 */
private ContainerCommandRequestProto getReadChunkRequest(ContainerCommandRequestProto writeChunkRequest) {
    WriteChunkRequestProto writeChunk = writeChunkRequest.getWriteChunk();
    ContainerProtos.ReadChunkRequestProto.Builder readChunkRequest = ContainerProtos.ReadChunkRequestProto.newBuilder().setBlockID(writeChunk.getBlockID()).setChunkData(writeChunk.getChunkData()).setReadChunkVersion(ContainerProtos.ReadChunkVersion.V1);
    return ContainerCommandRequestProto.newBuilder().setCmdType(ContainerProtos.Type.ReadChunk).setContainerID(writeChunk.getBlockID().getContainerID()).setTraceID(writeChunkRequest.getTraceID()).setDatanodeUuid(writeChunkRequest.getDatanodeUuid()).setReadChunk(readChunkRequest).build();
}
Also used : WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto)

Example 4 with WriteChunkRequestProto

use of org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto in project ozone by apache.

the class ContainerStateMachine method write.

/*
   * writeStateMachineData calls are not synchronized with each other
   * and also with applyTransaction.
   */
@Override
public CompletableFuture<Message> write(LogEntryProto entry) {
    try {
        metrics.incNumWriteStateMachineOps();
        long writeStateMachineStartTime = Time.monotonicNowNanos();
        ContainerCommandRequestProto requestProto = getContainerCommandRequestProto(gid, entry.getStateMachineLogEntry().getLogData());
        WriteChunkRequestProto writeChunk = WriteChunkRequestProto.newBuilder(requestProto.getWriteChunk()).setData(getStateMachineData(entry.getStateMachineLogEntry())).build();
        requestProto = ContainerCommandRequestProto.newBuilder(requestProto).setWriteChunk(writeChunk).build();
        Type cmdType = requestProto.getCmdType();
        // CreateContainer will happen as a part of writeChunk only.
        switch(cmdType) {
            case WriteChunk:
                return handleWriteChunk(requestProto, entry.getIndex(), entry.getTerm(), writeStateMachineStartTime);
            default:
                throw new IllegalStateException("Cmd Type:" + cmdType + " should not have state machine data");
        }
    } catch (IOException e) {
        metrics.incNumWriteStateMachineFails();
        return completeExceptionally(e);
    }
}
Also used : WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto) Type(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type) ContainerCommandRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto) IOException(java.io.IOException)

Example 5 with WriteChunkRequestProto

use of org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto in project ozone by apache.

the class ContainerStateMachine method readStateMachineData.

private ByteString readStateMachineData(ContainerCommandRequestProto requestProto, long term, long index) throws IOException {
    // the stateMachine data is not present in the stateMachine cache,
    // increment the stateMachine cache miss count
    metrics.incNumReadStateMachineMissCount();
    WriteChunkRequestProto writeChunkRequestProto = requestProto.getWriteChunk();
    ContainerProtos.ChunkInfo chunkInfo = writeChunkRequestProto.getChunkData();
    // prepare the chunk to be read
    ReadChunkRequestProto.Builder readChunkRequestProto = ReadChunkRequestProto.newBuilder().setBlockID(writeChunkRequestProto.getBlockID()).setChunkData(chunkInfo).setReadChunkVersion(ContainerProtos.ReadChunkVersion.V1);
    ContainerCommandRequestProto dataContainerCommandProto = ContainerCommandRequestProto.newBuilder(requestProto).setCmdType(Type.ReadChunk).setReadChunk(readChunkRequestProto).build();
    DispatcherContext context = new DispatcherContext.Builder().setTerm(term).setLogIndex(index).setReadFromTmpFile(true).build();
    // read the chunk
    ContainerCommandResponseProto response = dispatchCommand(dataContainerCommandProto, context);
    if (response.getResult() != ContainerProtos.Result.SUCCESS) {
        StorageContainerException sce = new StorageContainerException(response.getMessage(), response.getResult());
        LOG.error("gid {} : ReadStateMachine failed. cmd {} logIndex {} msg : " + "{} Container Result: {}", gid, response.getCmdType(), index, response.getMessage(), response.getResult());
        stateMachineHealthy.set(false);
        throw sce;
    }
    ReadChunkResponseProto responseProto = response.getReadChunk();
    ByteString data;
    if (responseProto.hasData()) {
        data = responseProto.getData();
    } else {
        data = BufferUtils.concatByteStrings(responseProto.getDataBuffers().getBuffersList());
    }
    // assert that the response has data in it.
    Preconditions.checkNotNull(data, "read chunk data is null for chunk: %s", chunkInfo);
    Preconditions.checkState(data.size() == chunkInfo.getLen(), "read chunk len=%s does not match chunk expected len=%s for chunk:%s", data.size(), chunkInfo.getLen(), chunkInfo);
    return data;
}
Also used : WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto) ContainerProtos(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos) ReadChunkResponseProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkResponseProto) ByteString(org.apache.ratis.thirdparty.com.google.protobuf.ByteString) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ReadChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkRequestProto) ContainerCommandRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto) StorageContainerException(org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException) ContainerCommandResponseProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto)

Aggregations

WriteChunkRequestProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto)7 IOException (java.io.IOException)4 ContainerCommandRequestProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto)4 StorageContainerException (org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException)3 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)2 ContainerProtos (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos)2 ContainerCommandResponseProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto)2 ContainerNotOpenException (org.apache.hadoop.hdds.scm.container.common.helpers.ContainerNotOpenException)2 ByteString (org.apache.ratis.thirdparty.com.google.protobuf.ByteString)2 CompletableFuture (java.util.concurrent.CompletableFuture)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 Consumer (java.util.function.Consumer)1 BlockID (org.apache.hadoop.hdds.client.BlockID)1 PutSmallFileRequestProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.PutSmallFileRequestProto)1 ReadChunkRequestProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkRequestProto)1 ReadChunkResponseProto (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkResponseProto)1 Type (org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type)1 ContainerCommandRequestMessage (org.apache.hadoop.hdds.ratis.ContainerCommandRequestMessage)1 ChunkBuffer (org.apache.hadoop.ozone.common.ChunkBuffer)1 ChunkInfo (org.apache.hadoop.ozone.container.common.helpers.ChunkInfo)1