Search in sources :

Example 1 with InstallSnapshotRequestProto

use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.

the class GrpcLogAppender method installSnapshot.

/**
 * Send installSnapshot request to Follower with a snapshot.
 * @param snapshot the snapshot to be sent to Follower
 */
private void installSnapshot(SnapshotInfo snapshot) {
    LOG.info("{}: followerNextIndex = {} but logStartIndex = {}, send snapshot {} to follower", this, getFollower().getNextIndex(), getRaftLog().getStartIndex(), snapshot);
    final InstallSnapshotResponseHandler responseHandler = new InstallSnapshotResponseHandler();
    StreamObserver<InstallSnapshotRequestProto> snapshotRequestObserver = null;
    final String requestId = UUID.randomUUID().toString();
    try {
        snapshotRequestObserver = getClient().installSnapshot(responseHandler);
        for (InstallSnapshotRequestProto request : newInstallSnapshotRequests(requestId, snapshot)) {
            if (isRunning()) {
                snapshotRequestObserver.onNext(request);
                getFollower().updateLastRpcSendTime(false);
                responseHandler.addPending(request);
            } else {
                break;
            }
        }
        snapshotRequestObserver.onCompleted();
        grpcServerMetrics.onInstallSnapshot();
    } catch (Exception e) {
        LOG.warn("{}: failed to install snapshot {}: {}", this, snapshot.getFiles(), e);
        if (snapshotRequestObserver != null) {
            snapshotRequestObserver.onError(e);
        }
        return;
    }
    while (isRunning() && !responseHandler.isDone()) {
        try {
            getEventAwaitForSignal().await();
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
        }
    }
    if (responseHandler.hasAllResponse()) {
        getFollower().setSnapshotIndex(snapshot.getTermIndex().getIndex());
        LOG.info("{}: installed snapshot {} successfully", this, snapshot);
    }
}
Also used : InstallSnapshotRequestProto(org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto) IOException(java.io.IOException)

Example 2 with InstallSnapshotRequestProto

use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.

the class GrpcLogAppender method installSnapshot.

/**
 * Send installSnapshot request to Follower with only a notification that a snapshot needs to be installed.
 * @param firstAvailableLogTermIndex the first available log's index on the Leader
 */
private void installSnapshot(TermIndex firstAvailableLogTermIndex) {
    LOG.info("{}: followerNextIndex = {} but logStartIndex = {}, notify follower to install snapshot-{}", this, getFollower().getNextIndex(), getRaftLog().getStartIndex(), firstAvailableLogTermIndex);
    final InstallSnapshotResponseHandler responseHandler = new InstallSnapshotResponseHandler(true);
    StreamObserver<InstallSnapshotRequestProto> snapshotRequestObserver = null;
    // prepare and enqueue the notify install snapshot request.
    final InstallSnapshotRequestProto request = newInstallSnapshotNotificationRequest(firstAvailableLogTermIndex);
    if (LOG.isInfoEnabled()) {
        LOG.info("{}: send {}", this, ServerStringUtils.toInstallSnapshotRequestString(request));
    }
    try {
        snapshotRequestObserver = getClient().installSnapshot(responseHandler);
        snapshotRequestObserver.onNext(request);
        getFollower().updateLastRpcSendTime(false);
        responseHandler.addPending(request);
        snapshotRequestObserver.onCompleted();
    } catch (Exception e) {
        GrpcUtil.warn(LOG, () -> this + ": Failed to notify follower to install snapshot.", e);
        if (snapshotRequestObserver != null) {
            snapshotRequestObserver.onError(e);
        }
        return;
    }
    while (isRunning() && !responseHandler.isDone()) {
        try {
            getEventAwaitForSignal().await();
        } catch (InterruptedException ignored) {
            Thread.currentThread().interrupt();
        }
    }
}
Also used : InstallSnapshotRequestProto(org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto) IOException(java.io.IOException)

Example 3 with InstallSnapshotRequestProto

use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.

the class LogAppenderDefault method installSnapshot.

private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException {
    String requestId = UUID.randomUUID().toString();
    InstallSnapshotReplyProto reply = null;
    try {
        for (InstallSnapshotRequestProto request : newInstallSnapshotRequests(requestId, snapshot)) {
            getFollower().updateLastRpcSendTime(false);
            reply = getServerRpc().installSnapshot(request);
            getFollower().updateLastRpcResponseTime();
            if (!reply.getServerReply().getSuccess()) {
                return reply;
            }
        }
    } catch (InterruptedIOException iioe) {
        throw iioe;
    } catch (Exception ioe) {
        LOG.warn("{}: Failed to installSnapshot {}: {}", this, snapshot, ioe);
        handleException(ioe);
        return null;
    }
    if (reply != null) {
        getFollower().setSnapshotIndex(snapshot.getTermIndex().getIndex());
        LOG.info("{}: installSnapshot {} successfully", this, snapshot);
        getServer().getRaftServerMetrics().onSnapshotInstalled();
    }
    return reply;
}
Also used : InterruptedIOException(java.io.InterruptedIOException) InstallSnapshotRequestProto(org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto) InstallSnapshotReplyProto(org.apache.ratis.proto.RaftProtos.InstallSnapshotReplyProto) IOException(java.io.IOException) RaftLogIOException(org.apache.ratis.server.raftlog.RaftLogIOException) InterruptedIOException(java.io.InterruptedIOException)

Example 4 with InstallSnapshotRequestProto

use of org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto in project incubator-ratis by apache.

the class SnapshotManager method installSnapshot.

@SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
public void installSnapshot(StateMachine stateMachine, InstallSnapshotRequestProto request) throws IOException {
    final InstallSnapshotRequestProto.SnapshotChunkProto snapshotChunkRequest = request.getSnapshotChunk();
    final long lastIncludedIndex = snapshotChunkRequest.getTermIndex().getIndex();
    final RaftStorageDirectory dir = storage.getStorageDir();
    // create a unique temporary directory
    final File tmpDir = new File(dir.getTmpDir(), UUID.randomUUID().toString());
    FileUtils.createDirectories(tmpDir);
    tmpDir.deleteOnExit();
    LOG.info("Installing snapshot:{}, to tmp dir:{}", request, tmpDir);
    for (FileChunkProto chunk : snapshotChunkRequest.getFileChunksList()) {
        SnapshotInfo pi = stateMachine.getLatestSnapshot();
        if (pi != null && pi.getTermIndex().getIndex() >= lastIncludedIndex) {
            throw new IOException("There exists snapshot file " + pi.getFiles() + " in " + selfId + " with endIndex >= lastIncludedIndex " + lastIncludedIndex);
        }
        // this is relative to the root dir
        String fileName = chunk.getFilename();
        // TODO: assumes flat layout inside SM dir
        File tmpSnapshotFile = new File(tmpDir, new File(dir.getRoot(), fileName).getName());
        FileOutputStream out = null;
        try {
            // same last index.
            if (chunk.getOffset() == 0) {
                if (tmpSnapshotFile.exists()) {
                    FileUtils.deleteFully(tmpSnapshotFile);
                }
                // create the temp snapshot file and put padding inside
                out = new FileOutputStream(tmpSnapshotFile);
            } else {
                Preconditions.assertTrue(tmpSnapshotFile.exists());
                out = new FileOutputStream(tmpSnapshotFile, true);
                FileChannel fc = out.getChannel();
                fc.position(chunk.getOffset());
            }
            // write data to the file
            out.write(chunk.getData().toByteArray());
        } finally {
            IOUtils.cleanup(null, out);
        }
        // the md5 digest and create the md5 meta-file.
        if (chunk.getDone()) {
            final MD5Hash expectedDigest = new MD5Hash(chunk.getFileDigest().toByteArray());
            // calculate the checksum of the snapshot file and compare it with the
            // file digest in the request
            MD5Hash digest = MD5FileUtil.computeMd5ForFile(tmpSnapshotFile);
            if (!digest.equals(expectedDigest)) {
                LOG.warn("The snapshot md5 digest {} does not match expected {}", digest, expectedDigest);
                // rename the temp snapshot file to .corrupt
                FileUtils.renameFileToCorrupt(tmpSnapshotFile);
                throw new CorruptedFileException(tmpSnapshotFile, "MD5 mismatch for snapshot-" + lastIncludedIndex + " installation");
            } else {
                MD5FileUtil.saveMD5File(tmpSnapshotFile, digest);
            }
        }
    }
    if (snapshotChunkRequest.getDone()) {
        LOG.info("Install snapshot is done, renaming tnp dir:{} to:{}", tmpDir, dir.getStateMachineDir());
        dir.getStateMachineDir().delete();
        tmpDir.renameTo(dir.getStateMachineDir());
    }
}
Also used : FileChannel(java.nio.channels.FileChannel) FileChunkProto(org.apache.ratis.proto.RaftProtos.FileChunkProto) IOException(java.io.IOException) SnapshotInfo(org.apache.ratis.statemachine.SnapshotInfo) CorruptedFileException(org.apache.ratis.io.CorruptedFileException) FileOutputStream(java.io.FileOutputStream) MD5Hash(org.apache.ratis.io.MD5Hash) InstallSnapshotRequestProto(org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto) File(java.io.File) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings)

Aggregations

IOException (java.io.IOException)4 InstallSnapshotRequestProto (org.apache.ratis.proto.RaftProtos.InstallSnapshotRequestProto)4 SuppressFBWarnings (edu.umd.cs.findbugs.annotations.SuppressFBWarnings)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 InterruptedIOException (java.io.InterruptedIOException)1 FileChannel (java.nio.channels.FileChannel)1 CorruptedFileException (org.apache.ratis.io.CorruptedFileException)1 MD5Hash (org.apache.ratis.io.MD5Hash)1 FileChunkProto (org.apache.ratis.proto.RaftProtos.FileChunkProto)1 InstallSnapshotReplyProto (org.apache.ratis.proto.RaftProtos.InstallSnapshotReplyProto)1 RaftLogIOException (org.apache.ratis.server.raftlog.RaftLogIOException)1 SnapshotInfo (org.apache.ratis.statemachine.SnapshotInfo)1