use of org.apache.ratis.statemachine.SnapshotInfo in project alluxio by Alluxio.
the class SnapshotReplicationManager method installDownloadedSnapshot.
/**
* Installs a downloaded snapshot in the journal snapshot directory.
*
* @return the index of the installed snapshot
*/
private long installDownloadedSnapshot() {
if (!transitionState(DownloadState.DOWNLOADED, DownloadState.INSTALLING)) {
return RaftLog.INVALID_LOG_INDEX;
}
File tempFile = null;
try (Timer.Context ctx = MetricsSystem.timer(MetricKey.MASTER_EMBEDDED_JOURNAL_SNAPSHOT_INSTALL_TIMER.getName()).time()) {
SnapshotInfo snapshot = mDownloadedSnapshot;
if (snapshot == null) {
throw new IllegalStateException("Snapshot is not completed");
}
FileInfo fileInfo = snapshot.getFiles().get(0);
tempFile = fileInfo.getPath().toFile();
if (!tempFile.exists()) {
throw new FileNotFoundException(String.format("Snapshot file %s is not found", tempFile));
}
SnapshotInfo latestSnapshot = mStorage.getLatestSnapshot();
TermIndex lastInstalled = latestSnapshot == null ? null : latestSnapshot.getTermIndex();
TermIndex downloaded = snapshot.getTermIndex();
if (lastInstalled != null && downloaded.compareTo(lastInstalled) < 0) {
throw new AbortedException(String.format("Snapshot to be installed %s is older than current snapshot %s", downloaded, lastInstalled));
}
final File snapshotFile = mStorage.getSnapshotFile(downloaded.getTerm(), downloaded.getIndex());
LOG.debug("Moving temp snapshot {} to file {}", tempFile, snapshotFile);
MD5FileUtil.saveMD5File(snapshotFile, fileInfo.getFileDigest());
if (!tempFile.renameTo(snapshotFile)) {
throw new IOException(String.format("Failed to rename %s to %s", tempFile, snapshotFile));
}
mStorage.loadLatestSnapshot();
LOG.info("Completed storing snapshot at {} to file {}", downloaded, snapshotFile);
return downloaded.getIndex();
} catch (Exception e) {
LOG.error("Failed to install snapshot", e);
if (tempFile != null) {
tempFile.delete();
}
return RaftLog.INVALID_LOG_INDEX;
} finally {
transitionState(DownloadState.INSTALLING, DownloadState.IDLE);
}
}
use of org.apache.ratis.statemachine.SnapshotInfo in project alluxio by Alluxio.
the class SnapshotReplicationManager method sendSnapshotToLeader.
/**
* Sends a snapshot to the leader.
*
* @throws IOException if error occurs while initializing the data stream
*/
public void sendSnapshotToLeader() throws IOException {
if (mJournalSystem.isLeader()) {
throw new IllegalStateException("Server is no longer a follower");
}
LOG.debug("Checking latest snapshot to send");
SnapshotInfo snapshot = mStorage.getLatestSnapshot();
if (snapshot == null) {
throw new NotFoundException("No snapshot available");
}
StreamObserver<UploadSnapshotPResponse> responseObserver = SnapshotUploader.forFollower(mStorage, snapshot);
try (RaftJournalServiceClient client = getJournalServiceClient()) {
LOG.info("Sending stream request to {} for snapshot {}", client.getAddress(), snapshot.getTermIndex());
StreamObserver<UploadSnapshotPRequest> requestObserver = client.uploadSnapshot(responseObserver);
requestObserver.onNext(UploadSnapshotPRequest.newBuilder().setData(SnapshotData.newBuilder().setSnapshotTerm(snapshot.getTerm()).setSnapshotIndex(snapshot.getIndex()).setOffset(0)).build());
}
}
use of org.apache.ratis.statemachine.SnapshotInfo in project incubator-ratis by apache.
the class LogAppender method getPrevious.
private TermIndex getPrevious() {
TermIndex previous = raftLog.getTermIndex(follower.getNextIndex() - 1);
if (previous == null) {
// if previous is null, nextIndex must be equal to the log start
// index (otherwise we will install snapshot).
Preconditions.assertTrue(follower.getNextIndex() == raftLog.getStartIndex(), "follower's next index %s, local log start index %s", follower.getNextIndex(), raftLog.getStartIndex());
SnapshotInfo snapshot = server.getState().getLatestSnapshot();
previous = snapshot == null ? null : snapshot.getTermIndex();
}
return previous;
}
use of org.apache.ratis.statemachine.SnapshotInfo in project incubator-ratis by apache.
the class LogAppender method checkAndSendAppendEntries.
/**
* Check and send appendEntries RPC
*/
private void checkAndSendAppendEntries() throws InterruptedException, InterruptedIOException, RaftLogIOException {
while (isAppenderRunning()) {
if (shouldSendRequest()) {
SnapshotInfo snapshot = shouldInstallSnapshot();
if (snapshot != null) {
LOG.info("{}: follower {}'s next index is {}," + " log's start index is {}, need to install snapshot", server.getId(), follower.getPeer(), follower.getNextIndex(), raftLog.getStartIndex());
final InstallSnapshotReplyProto r = installSnapshot(snapshot);
if (r != null && r.getResult() == InstallSnapshotResult.NOT_LEADER) {
checkResponseTerm(r.getTerm());
}
// otherwise if r is null, retry the snapshot installation
} else {
final AppendEntriesReplyProto r = sendAppendEntriesWithRetries();
if (r != null) {
handleReply(r);
}
}
}
if (isAppenderRunning() && !shouldAppendEntries(follower.getNextIndex() + buffer.getPendingEntryNum())) {
final long waitTime = getHeartbeatRemainingTime(follower.getLastRpcTime());
if (waitTime > 0) {
synchronized (this) {
wait(waitTime);
}
}
}
}
}
use of org.apache.ratis.statemachine.SnapshotInfo in project incubator-ratis by apache.
the class StateMachineUpdater method reload.
private void reload() throws IOException {
Preconditions.assertTrue(stateMachine.getLifeCycleState() == LifeCycle.State.PAUSED);
stateMachine.reinitialize();
final SnapshotInfo snapshot = stateMachine.getLatestSnapshot();
Objects.requireNonNull(snapshot, "snapshot == null");
final long i = snapshot.getIndex();
snapshotIndex.setUnconditionally(i, infoIndexChange);
appliedIndex.setUnconditionally(i, infoIndexChange);
state = State.RUNNING;
}
Aggregations