Search in sources :

Example 11 with AutoCloseableLock

use of org.apache.ratis.util.AutoCloseableLock in project incubator-ratis by apache.

the class SegmentedRaftLog method loadLogSegments.

private void loadLogSegments(long lastIndexInSnapshot, Consumer<LogEntryProto> logConsumer) throws IOException {
    try (AutoCloseableLock writeLock = writeLock()) {
        final List<LogSegmentPath> paths = LogSegmentPath.getLogSegmentPaths(storage);
        int i = 0;
        for (LogSegmentPath pi : paths) {
            // During the initial loading, we can only confirm the committed
            // index based on the snapshot. This means if a log segment is not kept
            // in cache after the initial loading, later we have to load its content
            // again for updating the state machine.
            // TODO we should let raft peer persist its committed index periodically
            // so that during the initial loading we can apply part of the log
            // entries to the state machine
            boolean keepEntryInCache = (paths.size() - i++) <= cache.getMaxCachedSegments();
            final Timer.Context loadSegmentContext = getRaftLogMetrics().getRaftLogLoadSegmentTimer().time();
            cache.loadSegment(pi, keepEntryInCache, logConsumer);
            loadSegmentContext.stop();
        }
        // committing the log and taking snapshot)
        if (!cache.isEmpty() && cache.getEndIndex() < lastIndexInSnapshot) {
            LOG.warn("End log index {} is smaller than last index in snapshot {}", cache.getEndIndex(), lastIndexInSnapshot);
            purgeImpl(lastIndexInSnapshot);
        }
    }
}
Also used : Timer(com.codahale.metrics.Timer) AutoCloseableLock(org.apache.ratis.util.AutoCloseableLock)

Example 12 with AutoCloseableLock

use of org.apache.ratis.util.AutoCloseableLock in project incubator-ratis by apache.

the class SegmentedRaftLog method appendImpl.

@Override
public List<CompletableFuture<Long>> appendImpl(LogEntryProto... entries) {
    checkLogState();
    if (entries == null || entries.length == 0) {
        return Collections.emptyList();
    }
    try (AutoCloseableLock writeLock = writeLock()) {
        final TruncateIndices ti = cache.computeTruncateIndices(server::notifyTruncatedLogEntry, entries);
        final long truncateIndex = ti.getTruncateIndex();
        final int index = ti.getArrayIndex();
        LOG.debug("truncateIndex={}, arrayIndex={}", truncateIndex, index);
        final List<CompletableFuture<Long>> futures;
        if (truncateIndex != -1) {
            futures = new ArrayList<>(entries.length - index + 1);
            futures.add(truncate(truncateIndex));
        } else {
            futures = new ArrayList<>(entries.length - index);
        }
        for (int i = index; i < entries.length; i++) {
            futures.add(appendEntry(entries[i]));
        }
        return futures;
    }
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) AutoCloseableLock(org.apache.ratis.util.AutoCloseableLock) TruncateIndices(org.apache.ratis.server.raftlog.segmented.SegmentedRaftLogCache.TruncateIndices)

Example 13 with AutoCloseableLock

use of org.apache.ratis.util.AutoCloseableLock in project incubator-ratis by apache.

the class SegmentedRaftLog method appendEntryImpl.

@Override
protected CompletableFuture<Long> appendEntryImpl(LogEntryProto entry) {
    final Timer.Context context = getRaftLogMetrics().getRaftLogAppendEntryTimer().time();
    checkLogState();
    if (LOG.isTraceEnabled()) {
        LOG.trace("{}: appendEntry {}", getName(), LogProtoUtils.toLogEntryString(entry));
    }
    try (AutoCloseableLock writeLock = writeLock()) {
        validateLogEntry(entry);
        final LogSegment currentOpenSegment = cache.getOpenSegment();
        if (currentOpenSegment == null) {
            cache.addOpenSegment(entry.getIndex());
            fileLogWorker.startLogSegment(entry.getIndex());
        } else if (isSegmentFull(currentOpenSegment, entry)) {
            cache.rollOpenSegment(true);
            fileLogWorker.rollLogSegment(currentOpenSegment);
        } else if (currentOpenSegment.numOfEntries() > 0 && currentOpenSegment.getLastTermIndex().getTerm() != entry.getTerm()) {
            // the term changes
            final long currentTerm = currentOpenSegment.getLastTermIndex().getTerm();
            Preconditions.assertTrue(currentTerm < entry.getTerm(), "open segment's term %s is larger than the new entry's term %s", currentTerm, entry.getTerm());
            cache.rollOpenSegment(true);
            fileLogWorker.rollLogSegment(currentOpenSegment);
        }
        // TODO(runzhiwang): If there is performance problem, start a daemon thread to checkAndEvictCache
        checkAndEvictCache();
        // If the entry has state machine data, then the entry should be inserted
        // to statemachine first and then to the cache. Not following the order
        // will leave a spurious entry in the cache.
        CompletableFuture<Long> writeFuture = fileLogWorker.writeLogEntry(entry).getFuture();
        if (stateMachineCachingEnabled) {
            // The stateMachineData will be cached inside the StateMachine itself.
            cache.appendEntry(LogProtoUtils.removeStateMachineData(entry), LogSegment.Op.WRITE_CACHE_WITH_STATE_MACHINE_CACHE);
        } else {
            cache.appendEntry(entry, LogSegment.Op.WRITE_CACHE_WITHOUT_STATE_MACHINE_CACHE);
        }
        return writeFuture;
    } catch (Exception e) {
        LOG.error("{}: Failed to append {}", getName(), LogProtoUtils.toLogEntryString(entry), e);
        throw e;
    } finally {
        context.stop();
    }
}
Also used : Timer(com.codahale.metrics.Timer) AutoCloseableLock(org.apache.ratis.util.AutoCloseableLock) RaftLogIOException(org.apache.ratis.server.raftlog.RaftLogIOException) IOException(java.io.IOException)

Example 14 with AutoCloseableLock

use of org.apache.ratis.util.AutoCloseableLock in project incubator-ratis by apache.

the class SegmentedRaftLog method purgeImpl.

@Override
protected CompletableFuture<Long> purgeImpl(long index) {
    try (AutoCloseableLock writeLock = writeLock()) {
        SegmentedRaftLogCache.TruncationSegments ts = cache.purge(index);
        updateSnapshotIndexFromStateMachine();
        LOG.debug("purging segments:{}", ts);
        if (ts != null) {
            Task task = fileLogWorker.purge(ts);
            return task.getFuture();
        }
    }
    return CompletableFuture.completedFuture(index);
}
Also used : AutoCloseableLock(org.apache.ratis.util.AutoCloseableLock)

Example 15 with AutoCloseableLock

use of org.apache.ratis.util.AutoCloseableLock in project incubator-ratis by apache.

the class MemoryRaftLog method appendImpl.

@Override
public List<CompletableFuture<Long>> appendImpl(LogEntryProto... logEntryProtos) {
    checkLogState();
    if (logEntryProtos == null || logEntryProtos.length == 0) {
        return Collections.emptyList();
    }
    try (AutoCloseableLock writeLock = writeLock()) {
        // Before truncating the entries, we first need to check if some
        // entries are duplicated. If the leader sends entry 6, entry 7, then
        // entry 6 again, without this check the follower may truncate entry 7
        // when receiving entry 6 again. Then before the leader detects this
        // truncation in the next appendEntries RPC, leader may think entry 7 has
        // been committed but in the system the entry has not been committed to
        // the quorum of peers' disks.
        boolean toTruncate = false;
        int truncateIndex = (int) logEntryProtos[0].getIndex();
        int index = 0;
        for (; truncateIndex < getNextIndex() && index < logEntryProtos.length; index++, truncateIndex++) {
            if (this.entries.get(truncateIndex).getTerm() != logEntryProtos[index].getTerm()) {
                toTruncate = true;
                break;
            }
        }
        final List<CompletableFuture<Long>> futures;
        if (toTruncate) {
            futures = new ArrayList<>(logEntryProtos.length - index + 1);
            futures.add(truncate(truncateIndex));
        } else {
            futures = new ArrayList<>(logEntryProtos.length - index);
        }
        for (int i = index; i < logEntryProtos.length; i++) {
            this.entries.add(logEntryProtos[i]);
            futures.add(CompletableFuture.completedFuture(logEntryProtos[i].getIndex()));
        }
        return futures;
    }
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) AutoCloseableLock(org.apache.ratis.util.AutoCloseableLock)

Aggregations

AutoCloseableLock (org.apache.ratis.util.AutoCloseableLock)35 TermIndex (org.apache.ratis.server.protocol.TermIndex)9 IOException (java.io.IOException)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 LogEntryProto (org.apache.ratis.proto.RaftProtos.LogEntryProto)4 LogEntryProto (org.apache.ratis.shaded.proto.RaftProtos.LogEntryProto)4 Timer (com.codahale.metrics.Timer)2 File (java.io.File)2 Expression (org.apache.ratis.examples.arithmetic.expression.Expression)2 RaftLogIOException (org.apache.ratis.server.raftlog.RaftLogIOException)2 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 ObjectInputStream (java.io.ObjectInputStream)1 ObjectOutputStream (java.io.ObjectOutputStream)1 RaftPeerRole (org.apache.ratis.proto.RaftProtos.RaftPeerRole)1 Message (org.apache.ratis.protocol.Message)1 StateMachineException (org.apache.ratis.protocol.StateMachineException)1 StateMachineException (org.apache.ratis.protocol.exceptions.StateMachineException)1