org.apache.ratis.statemachine.SnapshotInfo Java Examples

The following examples show how to use org.apache.ratis.statemachine.SnapshotInfo. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BaseStateMachine.java    From incubator-ratis with Apache License 2.0 6 votes vote down vote up
@Override
public StateMachineStorage getStateMachineStorage() {
  return new StateMachineStorage() {
    @Override
    public void init(RaftStorage raftStorage) throws IOException {
    }

    @Override
    public SnapshotInfo getLatestSnapshot() {
      return null;
    }

    @Override
    public void format() throws IOException {
    }

    @Override
    public void cleanupOldSnapshots(SnapshotRetentionPolicy snapshotRetentionPolicy) {
    }
  };
}
 
Example #2
Source File: ServerState.java    From incubator-ratis with Apache License 2.0 6 votes vote down vote up
private long initStatemachine(StateMachine sm, RaftGroupId gid)
    throws IOException {
  sm.initialize(server.getProxy(), gid, storage);
  SnapshotInfo snapshot = sm.getLatestSnapshot();

  if (snapshot == null || snapshot.getTermIndex().getIndex() < 0) {
    return RaftLog.INVALID_LOG_INDEX;
  }

  // get the raft configuration from raft metafile
  RaftConfiguration raftConf = storage.readRaftConfiguration();
  if (raftConf != null) {
    setRaftConf(raftConf.getLogEntryIndex(), raftConf);
  }
  return snapshot.getIndex();
}
 
Example #3
Source File: ServerState.java    From ratis with Apache License 2.0 6 votes vote down vote up
private long initStatemachine(StateMachine sm, RaftGroupId groupId)
    throws IOException {
  sm.initialize(server.getProxy(), groupId, storage);
  storage.setStateMachineStorage(sm.getStateMachineStorage());
  SnapshotInfo snapshot = sm.getLatestSnapshot();

  if (snapshot == null || snapshot.getTermIndex().getIndex() < 0) {
    return RaftServerConstants.INVALID_LOG_INDEX;
  }

  // get the raft configuration from raft metafile
  RaftConfiguration raftConf = storage.readRaftConfiguration();
  if (raftConf != null) {
    setRaftConf(raftConf.getLogEntryIndex(), raftConf);
  }
  return snapshot.getIndex();
}
 
Example #4
Source File: BaseStateMachine.java    From ratis with Apache License 2.0 6 votes vote down vote up
@Override
public StateMachineStorage getStateMachineStorage() {
  return new StateMachineStorage() {
    @Override
    public void init(RaftStorage raftStorage) throws IOException {
    }

    @Override
    public SnapshotInfo getLatestSnapshot() {
      return null;
    }

    @Override
    public void format() throws IOException {
    }
  };
}
 
Example #5
Source File: GrpcLogAppender.java    From ratis with Apache License 2.0 6 votes vote down vote up
@Override
protected void runAppenderImpl() throws IOException {
  for(; isAppenderRunning(); mayWait()) {
    if (shouldSendRequest()) {
      SnapshotInfo snapshot = shouldInstallSnapshot();
      if (snapshot != null) {
        installSnapshot(snapshot);
      } else if (!shouldWait()) {
        // keep appending log entries or sending heartbeats
        appendLog();
      }
    }
    checkSlowness();
  }

  Optional.ofNullable(appendLogRequestObserver).ifPresent(StreamObserver::onCompleted);
}
 
Example #6
Source File: LogAppender.java    From incubator-ratis with Apache License 2.0 6 votes vote down vote up
private TermIndex getPrevious(long nextIndex) {
  if (nextIndex == RaftLog.LEAST_VALID_LOG_INDEX) {
    return null;
  }

  final long previousIndex = nextIndex - 1;
  final TermIndex previous = raftLog.getTermIndex(previousIndex);
  if (previous != null) {
    return previous;
  }

  final SnapshotInfo snapshot = server.getState().getLatestSnapshot();
  if (snapshot != null) {
    final TermIndex snapshotTermIndex = snapshot.getTermIndex();
    if (snapshotTermIndex.getIndex() == previousIndex) {
      return snapshotTermIndex;
    }
  }

  return null;
}
 
Example #7
Source File: TestOzoneManagerRatisServer.java    From hadoop-ozone with Apache License 2.0 5 votes vote down vote up
@Test
public void testLoadSnapshotInfoOnStart() throws Exception {
  // Stop the Ratis server and manually update the snapshotInfo.
  omRatisServer.getOmStateMachine().loadSnapshotInfoFromDB();
  omRatisServer.stop();

  SnapshotInfo snapshotInfo =
      omRatisServer.getOmStateMachine().getLatestSnapshot();

  TermIndex newSnapshotIndex = TermIndex.newTermIndex(
      snapshotInfo.getTerm(), snapshotInfo.getIndex() + 100);

  omMetadataManager.getTransactionInfoTable().put(TRANSACTION_INFO_KEY,
      new OMTransactionInfo.Builder()
          .setCurrentTerm(snapshotInfo.getTerm())
          .setTransactionIndex(snapshotInfo.getIndex() + 100)
          .build());

  // Start new Ratis server. It should pick up and load the new SnapshotInfo
  omRatisServer = OzoneManagerRatisServer.newOMRatisServer(conf, ozoneManager,
      omNodeDetails, Collections.emptyList());
  omRatisServer.start();
  TermIndex lastAppliedTermIndex =
      omRatisServer.getLastAppliedTermIndex();

  Assert.assertEquals(newSnapshotIndex.getIndex(),
      lastAppliedTermIndex.getIndex());
  Assert.assertEquals(newSnapshotIndex.getTerm(),
      lastAppliedTermIndex.getTerm());
}
 
Example #8
Source File: RaftServerImpl.java    From ratis with Apache License 2.0 5 votes vote down vote up
synchronized InstallSnapshotRequestProto createInstallSnapshotRequest(
    RaftPeerId targetId, String requestId, int requestIndex,
    SnapshotInfo snapshot, List<FileChunkProto> chunks, boolean done) {
  OptionalLong totalSize = snapshot.getFiles().stream()
      .mapToLong(FileInfo::getFileSize).reduce(Long::sum);
  assert totalSize.isPresent();
  return ServerProtoUtils.toInstallSnapshotRequestProto(getId(), targetId, groupId,
      requestId, requestIndex, state.getCurrentTerm(), snapshot.getTermIndex(),
      chunks, totalSize.getAsLong(), done);
}
 
Example #9
Source File: LogAppender.java    From ratis with Apache License 2.0 5 votes vote down vote up
protected SnapshotInfo shouldInstallSnapshot() {
  final long logStartIndex = raftLog.getStartIndex();
  // we should install snapshot if the follower needs to catch up and:
  // 1. there is no local log entry but there is snapshot
  // 2. or the follower's next index is smaller than the log start index
  if (follower.getNextIndex() < raftLog.getNextIndex()) {
    SnapshotInfo snapshot = server.getState().getLatestSnapshot();
    if (follower.getNextIndex() < logStartIndex ||
        (logStartIndex == INVALID_LOG_INDEX && snapshot != null)) {
      return snapshot;
    }
  }
  return null;
}
 
Example #10
Source File: LogAppender.java    From ratis with Apache License 2.0 5 votes vote down vote up
private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException {
  String requestId = UUID.randomUUID().toString();
  InstallSnapshotReplyProto reply = null;
  try {
    for (InstallSnapshotRequestProto request :
        new SnapshotRequestIter(snapshot, requestId)) {
      follower.updateLastRpcSendTime();
      reply = server.getServerRpc().installSnapshot(request);
      follower.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) {
    follower.setSnapshotIndex(snapshot.getTermIndex().getIndex());
    LOG.info("{}: install snapshot-{} successfully on follower {}",
        server.getId(), snapshot.getTermIndex().getIndex(), follower.getPeer());
  }
  return reply;
}
 
Example #11
Source File: LogAppender.java    From ratis with Apache License 2.0 5 votes vote down vote up
public SnapshotRequestIter(SnapshotInfo snapshot, String requestId)
    throws IOException {
  this.snapshot = snapshot;
  this.requestId = requestId;
  this.files = snapshot.getFiles();
  if (files.size() > 0) {
    startReadFile();
  }
}
 
Example #12
Source File: LogAppender.java    From ratis with Apache License 2.0 5 votes vote down vote up
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(),
        "%s: follower's next index %s, local log start index %s",
        this, follower.getNextIndex(), raftLog.getStartIndex());
    SnapshotInfo snapshot = server.getState().getLatestSnapshot();
    previous = snapshot == null ? null : snapshot.getTermIndex();
  }
  return previous;
}
 
Example #13
Source File: ServerState.java    From ratis with Apache License 2.0 5 votes vote down vote up
boolean isLogUpToDate(TermIndex candidateLastEntry) {
  TermIndex local = log.getLastEntryTermIndex();
  // need to take into account snapshot
  SnapshotInfo snapshot = server.getStateMachine().getLatestSnapshot();
   if (local == null && snapshot == null) {
    return true;
  } else if (candidateLastEntry == null) {
    return false;
  }
  if (local == null || (snapshot != null && snapshot.getIndex() > local.getIndex())) {
    local = snapshot.getTermIndex();
  }
  return local.compareTo(candidateLastEntry) <= 0;
}
 
Example #14
Source File: RaftServerImpl.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
synchronized InstallSnapshotRequestProto createInstallSnapshotRequest(
    RaftPeerId targetId, String requestId, int requestIndex,
    SnapshotInfo snapshot, List<FileChunkProto> chunks, boolean done) {
  OptionalLong totalSize = snapshot.getFiles().stream()
      .mapToLong(FileInfo::getFileSize).reduce(Long::sum);
  assert totalSize.isPresent();
  return ServerProtoUtils.toInstallSnapshotRequestProto(getMemberId(), targetId,
      requestId, requestIndex, state.getCurrentTerm(), snapshot.getTermIndex(),
      chunks, totalSize.getAsLong(), done);
}
 
Example #15
Source File: LogAppender.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
protected SnapshotInfo shouldInstallSnapshot() {
  final long logStartIndex = raftLog.getStartIndex();
  // we should install snapshot if the follower needs to catch up and:
  // 1. there is no local log entry but there is snapshot
  // 2. or the follower's next index is smaller than the log start index
  if (follower.getNextIndex() < raftLog.getNextIndex()) {
    SnapshotInfo snapshot = server.getState().getLatestSnapshot();
    if (follower.getNextIndex() < logStartIndex ||
        (logStartIndex == RaftLog.INVALID_LOG_INDEX && snapshot != null)) {
      return snapshot;
    }
  }
  return null;
}
 
Example #16
Source File: LogAppender.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
public SnapshotRequestIter(SnapshotInfo snapshot, String requestId)
    throws IOException {
  this.snapshot = snapshot;
  this.requestId = requestId;
  this.files = snapshot.getFiles();
  if (files.size() > 0) {
    startReadFile();
  }
}
 
Example #17
Source File: GrpcLogAppender.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
@Override
protected void runAppenderImpl() throws IOException {
  boolean shouldAppendLog;
  for(; isAppenderRunning(); mayWait()) {
    shouldAppendLog = true;
    if (shouldSendRequest()) {
      if (installSnapshotEnabled) {
        SnapshotInfo snapshot = shouldInstallSnapshot();
        if (snapshot != null) {
          installSnapshot(snapshot);
          shouldAppendLog = false;
        }
      } else {
        TermIndex installSnapshotNotificationTermIndex = shouldNotifyToInstallSnapshot();
        if (installSnapshotNotificationTermIndex != null) {
          installSnapshot(installSnapshotNotificationTermIndex);
          shouldAppendLog = false;
        }
      }
      if (shouldHeartbeat() || (shouldAppendLog && !shouldWait())) {
        // keep appending log entries or sending heartbeats
        appendLog();
      }
    }
    checkSlowness();
  }

  Optional.ofNullable(appendLogRequestObserver).ifPresent(StreamObserver::onCompleted);
}
 
Example #18
Source File: StateMachineUpdater.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
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;
}
 
Example #19
Source File: ServerState.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
boolean isLogUpToDate(TermIndex candidateLastEntry) {
  TermIndex local = log.getLastEntryTermIndex();
  // need to take into account snapshot
  SnapshotInfo snapshot = server.getStateMachine().getLatestSnapshot();
   if (local == null && snapshot == null) {
    return true;
  } else if (candidateLastEntry == null) {
    return false;
  }
  if (local == null || (snapshot != null && snapshot.getIndex() > local.getIndex())) {
    local = snapshot.getTermIndex();
  }
  return local.compareTo(candidateLastEntry) <= 0;
}
 
Example #20
Source File: ServerState.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
boolean containsTermIndex(TermIndex ti) {
  Objects.requireNonNull(ti, "ti == null");

  if (Optional.ofNullable(latestInstalledSnapshot.get()).filter(ti::equals).isPresent()) {
    return true;
  }
  if (Optional.ofNullable(getLatestSnapshot()).map(SnapshotInfo::getTermIndex).filter(ti::equals).isPresent()) {
    return true;
  }
  return log.contains(ti);
}
 
Example #21
Source File: LogAppender.java    From incubator-ratis with Apache License 2.0 5 votes vote down vote up
private InstallSnapshotReplyProto installSnapshot(SnapshotInfo snapshot) throws InterruptedIOException {
  String requestId = UUID.randomUUID().toString();
  InstallSnapshotReplyProto reply = null;
  try {
    for (InstallSnapshotRequestProto request :
        new SnapshotRequestIter(snapshot, requestId)) {
      follower.updateLastRpcSendTime();
      reply = server.getServerRpc().installSnapshot(request);
      follower.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) {
    follower.setSnapshotIndex(snapshot.getTermIndex().getIndex());
    LOG.info("{}: installSnapshot {} successfully", this, snapshot);
    server.getRaftServerMetrics().getCounter(LOG_APPENDER_INSTALL_SNAPSHOT_METRIC).inc();
  }
  return reply;
}
 
Example #22
Source File: GrpcLogAppender.java    From ratis with Apache License 2.0 4 votes vote down vote up
private void installSnapshot(SnapshotInfo snapshot) {
  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 InstallSnapshotResponseHandler responseHandler = new InstallSnapshotResponseHandler();
  StreamObserver<InstallSnapshotRequestProto> snapshotRequestObserver = null;
  final String requestId = UUID.randomUUID().toString();
  try {
    snapshotRequestObserver = getClient().installSnapshot(responseHandler);
    for (InstallSnapshotRequestProto request :
        new SnapshotRequestIter(snapshot, requestId)) {
      if (isAppenderRunning()) {
        snapshotRequestObserver.onNext(request);
        follower.updateLastRpcSendTime();
        responseHandler.addPending(request);
      } else {
        break;
      }
    }
    snapshotRequestObserver.onCompleted();
  } catch (Exception e) {
    LOG.warn("{} failed to install snapshot {}. Exception: {}", this,
        snapshot.getFiles(), e);
    if (snapshotRequestObserver != null) {
      snapshotRequestObserver.onError(e);
    }
    return;
  }

  synchronized (this) {
    while (isAppenderRunning() && !responseHandler.isDone()) {
      try {
        wait();
      } catch (InterruptedException ignored) {
      }
    }
  }

  if (responseHandler.hasAllResponse()) {
    follower.setSnapshotIndex(snapshot.getTermIndex().getIndex());
    LOG.info("{}: install snapshot-{} successfully on follower {}",
        server.getId(), snapshot.getTermIndex().getIndex(), follower.getPeer());
  }
}
 
Example #23
Source File: BaseStateMachine.java    From ratis with Apache License 2.0 4 votes vote down vote up
@Override
public SnapshotInfo getLatestSnapshot() {
  return getStateMachineStorage().getLatestSnapshot();
}
 
Example #24
Source File: ServerState.java    From incubator-ratis with Apache License 2.0 4 votes vote down vote up
/**
 * The last index included in either the latestSnapshot or the latestInstalledSnapshot
 * @return the last snapshot index
 */
long getSnapshotIndex() {
  final SnapshotInfo s = getLatestSnapshot();
  final long latestSnapshotIndex = s != null ? s.getIndex() : 0;
  return Math.max(latestSnapshotIndex, getLatestInstalledSnapshotIndex());
}
 
Example #25
Source File: ServerState.java    From incubator-ratis with Apache License 2.0 4 votes vote down vote up
SnapshotInfo getLatestSnapshot() {
  return server.getStateMachine().getLatestSnapshot();
}
 
Example #26
Source File: ServerState.java    From ratis with Apache License 2.0 4 votes vote down vote up
SnapshotInfo getLatestSnapshot() {
  return server.getStateMachine().getStateMachineStorage().getLatestSnapshot();
}
 
Example #27
Source File: LeaderElection.java    From incubator-ratis with Apache License 2.0 4 votes vote down vote up
/**
 * After a peer changes its role to candidate, it invokes this method to
 * send out requestVote rpc to all other peers.
 */
private void askForVotes() throws InterruptedException, IOException {
  final ServerState state = server.getState();
  while (shouldRun()) {
    // one round of requestVotes
    final long electionTerm;
    final RaftConfiguration conf;
    synchronized (server) {
      if (!shouldRun()) {
        break;
      }
      electionTerm = state.initElection();
      conf = state.getRaftConf();
      state.persistMetadata();
    }
    LOG.info("{}: begin an election at term {} for {}", this, electionTerm, conf);

    TermIndex lastEntry = state.getLog().getLastEntryTermIndex();
    if (lastEntry == null) {
      // lastEntry may need to be derived from snapshot
      SnapshotInfo snapshot = state.getLatestSnapshot();
      if (snapshot != null) {
        lastEntry = snapshot.getTermIndex();
      }
    }

    final ResultAndTerm r;
    final Collection<RaftPeer> others = conf.getOtherPeers(server.getId());
    if (others.isEmpty()) {
      r = new ResultAndTerm(Result.PASSED, electionTerm);
    } else {
      final Executor voteExecutor = new Executor(this, others.size());
      try {
        final int submitted = submitRequests(electionTerm, lastEntry, others, voteExecutor);
        r = waitForResults(electionTerm, submitted, conf, voteExecutor);
      } finally {
        voteExecutor.shutdown();
      }
    }

    synchronized (server) {
      if (!shouldRun(electionTerm)) {
        return; // term already passed or this should not run anymore.
      }

      switch (r.result) {
        case PASSED:
          server.changeToLeader();
          return;
        case SHUTDOWN:
          LOG.info("{} received shutdown response when requesting votes.", this);
          server.getProxy().close();
          return;
        case REJECTED:
        case DISCOVERED_A_NEW_TERM:
          final long term = Math.max(r.term, state.getCurrentTerm());
          server.changeToFollowerAndPersistMetadata(term, Result.DISCOVERED_A_NEW_TERM);
          return;
        case TIMEOUT: // should start another election
          continue;
        default: throw new IllegalArgumentException("Unable to process result " + r.result);
      }
    }
  }
}
 
Example #28
Source File: BaseStateMachine.java    From incubator-ratis with Apache License 2.0 4 votes vote down vote up
@Override
public SnapshotInfo getLatestSnapshot() {
  return getStateMachineStorage().getLatestSnapshot();
}
 
Example #29
Source File: GrpcLogAppender.java    From incubator-ratis with Apache License 2.0 4 votes vote down vote up
/**
 * 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 :
        new SnapshotRequestIter(snapshot, requestId)) {
      if (isAppenderRunning()) {
        snapshotRequestObserver.onNext(request);
        getFollower().updateLastRpcSendTime();
        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;
  }

  synchronized (this) {
    while (isAppenderRunning() && !responseHandler.isDone()) {
      try {
        wait();
      } catch (InterruptedException ignored) {
      }
    }
  }

  if (responseHandler.hasAllResponse()) {
    getFollower().setSnapshotIndex(snapshot.getTermIndex().getIndex());
    LOG.info("{}: installed snapshot {} successfully", this, snapshot);
  }
}
 
Example #30
Source File: OzoneManagerStateMachine.java    From hadoop-ozone with Apache License 2.0 4 votes vote down vote up
@Override
public SnapshotInfo getLatestSnapshot() {
  LOG.info("Latest Snapshot Info {}", snapshotInfo);
  return snapshotInfo;
}