Search in sources :

Example 1 with Cache

use of org.apache.hadoop.hdds.utils.Cache in project ozone by apache.

the class ContainerStateMachine method applyTransaction.

/*
   * ApplyTransaction calls in Ratis are sequential.
   */
@Override
public CompletableFuture<Message> applyTransaction(TransactionContext trx) {
    long index = trx.getLogEntry().getIndex();
    try {
        // Remove the stateMachine data once both followers have caught up. If any
        // one of the follower is behind, the pending queue will max out as
        // configurable limit on pending request size and count and then will
        // block and client will backoff as a result of that.
        removeStateMachineDataIfNeeded(index);
        // as soon as its applied and such entry exists in the cache.
        if (!waitOnBothFollowers) {
            stateMachineDataCache.removeIf(k -> k >= index);
        }
        DispatcherContext.Builder builder = new DispatcherContext.Builder().setTerm(trx.getLogEntry().getTerm()).setLogIndex(index);
        long applyTxnStartTime = Time.monotonicNowNanos();
        applyTransactionSemaphore.acquire();
        metrics.incNumApplyTransactionsOps();
        ContainerCommandRequestProto requestProto = getContainerCommandRequestProto(gid, trx.getStateMachineLogEntry().getLogData());
        Type cmdType = requestProto.getCmdType();
        // Make sure that in write chunk, the user data is not set
        if (cmdType == Type.WriteChunk) {
            Preconditions.checkArgument(requestProto.getWriteChunk().getData().isEmpty());
            builder.setStage(DispatcherContext.WriteChunkStage.COMMIT_DATA);
        }
        if (cmdType == Type.WriteChunk || cmdType == Type.PutSmallFile || cmdType == Type.PutBlock || cmdType == Type.CreateContainer) {
            builder.setContainer2BCSIDMap(container2BCSIDMap);
        }
        CompletableFuture<Message> applyTransactionFuture = new CompletableFuture<>();
        final Consumer<Exception> exceptionHandler = e -> {
            LOG.error("gid {} : ApplyTransaction failed. cmd {} logIndex " + "{} exception {}", gid, requestProto.getCmdType(), index, e);
            stateMachineHealthy.compareAndSet(true, false);
            metrics.incNumApplyTransactionsFails();
            applyTransactionFuture.completeExceptionally(e);
        };
        // Ensure the command gets executed in a separate thread than
        // stateMachineUpdater thread which is calling applyTransaction here.
        final CompletableFuture<ContainerCommandResponseProto> future = submitTask(requestProto, builder, exceptionHandler);
        future.thenApply(r -> {
            if (trx.getServerRole() == RaftPeerRole.LEADER && trx.getStateMachineContext() != null) {
                long startTime = (long) trx.getStateMachineContext();
                metrics.incPipelineLatency(cmdType, (Time.monotonicNowNanos() - startTime) / 1000000L);
            }
            // unhealthy
            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 {} : ApplyTransaction failed. cmd {} logIndex {} msg : " + "{} Container Result: {}", gid, r.getCmdType(), index, r.getMessage(), r.getResult());
                metrics.incNumApplyTransactionsFails();
                // Since the applyTransaction now is completed exceptionally,
                // before any further snapshot is taken , the exception will be
                // caught in stateMachineUpdater in Ratis and ratis server will
                // shutdown.
                applyTransactionFuture.completeExceptionally(sce);
                stateMachineHealthy.compareAndSet(true, false);
                ratisServer.handleApplyTransactionFailure(gid, trx.getServerRole());
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("gid {} : ApplyTransaction completed. cmd {} logIndex {} msg : " + "{} Container Result: {}", gid, r.getCmdType(), index, r.getMessage(), r.getResult());
                }
                if (cmdType == Type.WriteChunk || cmdType == Type.PutSmallFile) {
                    metrics.incNumBytesCommittedCount(requestProto.getWriteChunk().getChunkData().getLen());
                }
                applyTransactionFuture.complete(r::toByteString);
                // failures before.
                if (isStateMachineHealthy()) {
                    final Long previous = applyTransactionCompletionMap.put(index, trx.getLogEntry().getTerm());
                    Preconditions.checkState(previous == null);
                    updateLastApplied();
                }
            }
            return applyTransactionFuture;
        }).whenComplete((r, t) -> {
            if (t != null) {
                stateMachineHealthy.set(false);
                LOG.error("gid {} : ApplyTransaction failed. cmd {} logIndex " + "{} exception {}", gid, requestProto.getCmdType(), index, t);
            }
            applyTransactionSemaphore.release();
            metrics.recordApplyTransactionCompletion(Time.monotonicNowNanos() - applyTxnStartTime);
        });
        return applyTransactionFuture;
    } catch (InterruptedException e) {
        metrics.incNumApplyTransactionsFails();
        Thread.currentThread().interrupt();
        return completeExceptionally(e);
    } catch (IOException e) {
        metrics.incNumApplyTransactionsFails();
        return completeExceptionally(e);
    }
}
Also used : ScmConfigKeys(org.apache.hadoop.hdds.scm.ScmConfigKeys) Arrays(java.util.Arrays) DatanodeRatisServerConfig(org.apache.hadoop.hdds.conf.DatanodeRatisServerConfig) TermIndex(org.apache.ratis.server.protocol.TermIndex) ContainerCommandResponseProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandResponseProto) TransactionContext(org.apache.ratis.statemachine.TransactionContext) LoggerFactory(org.slf4j.LoggerFactory) InvalidProtocolBufferException(org.apache.ratis.thirdparty.com.google.protobuf.InvalidProtocolBufferException) DatanodeConfiguration(org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration) ConfigurationSource(org.apache.hadoop.hdds.conf.ConfigurationSource) ByteString(org.apache.ratis.thirdparty.com.google.protobuf.ByteString) Map(java.util.Map) RaftStorage(org.apache.ratis.server.storage.RaftStorage) SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) StateMachineException(org.apache.ratis.protocol.exceptions.StateMachineException) ResourceLimitCache(org.apache.hadoop.hdds.utils.ResourceLimitCache) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) BufferUtils(org.apache.hadoop.ozone.common.utils.BufferUtils) Container2BCSIDMapProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Container2BCSIDMapProto) SimpleStateMachineStorage(org.apache.ratis.statemachine.impl.SimpleStateMachineStorage) StateMachineLogEntryProto(org.apache.ratis.proto.RaftProtos.StateMachineLogEntryProto) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) List(java.util.List) StorageUnit(org.apache.hadoop.hdds.conf.StorageUnit) StorageContainerException(org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException) BaseStateMachine(org.apache.ratis.statemachine.impl.BaseStateMachine) OzoneConfigKeys(org.apache.hadoop.ozone.OzoneConfigKeys) ContainerCommandRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) ContainerController(org.apache.hadoop.ozone.container.ozoneimpl.ContainerController) RoleInfoProto(org.apache.ratis.proto.RaftProtos.RoleInfoProto) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) RaftGroupMemberId(org.apache.ratis.protocol.RaftGroupMemberId) RaftLog(org.apache.ratis.server.raftlog.RaftLog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ReadChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkRequestProto) CheckedSupplier(org.apache.ratis.util.function.CheckedSupplier) CompletableFuture(java.util.concurrent.CompletableFuture) ContainerProtos(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos) ConcurrentMap(java.util.concurrent.ConcurrentMap) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) Message(org.apache.ratis.protocol.Message) Type(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type) StateMachineStorage(org.apache.ratis.statemachine.StateMachineStorage) HddsUtils(org.apache.hadoop.hdds.HddsUtils) ContainerCommandRequestMessage(org.apache.hadoop.hdds.ratis.ContainerCommandRequestMessage) WriteChunkRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.WriteChunkRequestProto) ContainerDispatcher(org.apache.hadoop.ozone.container.common.interfaces.ContainerDispatcher) ExecutorService(java.util.concurrent.ExecutorService) ContainerNotOpenException(org.apache.hadoop.hdds.scm.container.common.helpers.ContainerNotOpenException) OutputStream(java.io.OutputStream) TaskQueue(org.apache.ratis.util.TaskQueue) Logger(org.slf4j.Logger) Semaphore(java.util.concurrent.Semaphore) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) RaftClientRequest(org.apache.ratis.protocol.RaftClientRequest) FileInputStream(java.io.FileInputStream) File(java.io.File) TextFormat(org.apache.ratis.thirdparty.com.google.protobuf.TextFormat) Consumer(java.util.function.Consumer) RaftPeerRole(org.apache.ratis.proto.RaftProtos.RaftPeerRole) Cache(org.apache.hadoop.hdds.utils.Cache) Time(org.apache.hadoop.util.Time) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) RaftServer(org.apache.ratis.server.RaftServer) ReadChunkResponseProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ReadChunkResponseProto) Message(org.apache.ratis.protocol.Message) ContainerCommandRequestMessage(org.apache.hadoop.hdds.ratis.ContainerCommandRequestMessage) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) 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) Type(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type) CompletableFuture(java.util.concurrent.CompletableFuture) ContainerCommandRequestProto(org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerCommandRequestProto) StorageContainerException(org.apache.hadoop.hdds.scm.container.common.helpers.StorageContainerException)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Preconditions (com.google.common.base.Preconditions)1 ThreadFactoryBuilder (com.google.common.util.concurrent.ThreadFactoryBuilder)1 File (java.io.File)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 List (java.util.List)1 Map (java.util.Map)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 ExecutorService (java.util.concurrent.ExecutorService)1 Executors (java.util.concurrent.Executors)1 Semaphore (java.util.concurrent.Semaphore)1 ThreadPoolExecutor (java.util.concurrent.ThreadPoolExecutor)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1