Search in sources :

Example 1 with SingleFileSnapshotInfo

use of org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo in project alluxio by Alluxio.

the class SnapshotDownloader method onNextInternal.

private void onNextInternal(R response) throws IOException {
    TermIndex termIndex = TermIndex.valueOf(mDataGetter.apply(response).getSnapshotTerm(), mDataGetter.apply(response).getSnapshotIndex());
    if (mTermIndex == null) {
        LOG.info("Downloading new snapshot {} from {}", termIndex, mSource);
        mTermIndex = termIndex;
        // start a new file
        mTempFile = RaftJournalUtils.createTempSnapshotFile(mStorage);
        mTempFile.deleteOnExit();
        mStream.onNext(mMessageBuilder.apply(0L));
    } else {
        if (!termIndex.equals(mTermIndex)) {
            throw new IOException(String.format("Mismatched term index when downloading the snapshot. expected: %s actual: %s", mTermIndex, termIndex));
        }
        if (!mDataGetter.apply(response).hasChunk()) {
            throw new IOException(String.format("A chunk for file %s is missing from the response %s.", mTempFile, response));
        }
        // write the chunk
        if (mOutputStream == null) {
            LOG.info("Start writing to temporary file {}", mTempFile.getPath());
            mOutputStream = new FileOutputStream(mTempFile);
        }
        long position = mOutputStream.getChannel().position();
        if (position != mDataGetter.apply(response).getOffset()) {
            throw new IOException(String.format("Mismatched offset in file %d, expect %d, bytes written %d", position, mDataGetter.apply(response).getOffset(), mBytesWritten));
        }
        mOutputStream.write(mDataGetter.apply(response).getChunk().toByteArray());
        mBytesWritten += mDataGetter.apply(response).getChunk().size();
        LOG.debug("Written {} bytes to snapshot file {}", mBytesWritten, mTempFile.getPath());
        if (mDataGetter.apply(response).getEof()) {
            LOG.debug("Completed writing to temporary file {} with size {}", mTempFile.getPath(), mOutputStream.getChannel().position());
            mOutputStream.close();
            mOutputStream = null;
            final MD5Hash digest = MD5FileUtil.computeMd5ForFile(mTempFile);
            mSnapshotToInstall = new SingleFileSnapshotInfo(new FileInfo(mTempFile.toPath(), digest), mTermIndex.getTerm(), mTermIndex.getIndex());
            mFuture.complete(mTermIndex);
            LOG.info("Finished copying snapshot to local file {}.", mTempFile);
            mStream.onCompleted();
        } else {
            mStream.onNext(mMessageBuilder.apply(mBytesWritten));
        }
    }
}
Also used : SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) FileInfo(org.apache.ratis.server.storage.FileInfo) FileOutputStream(java.io.FileOutputStream) MD5Hash(org.apache.ratis.io.MD5Hash) IOException(java.io.IOException) TermIndex(org.apache.ratis.server.protocol.TermIndex)

Example 2 with SingleFileSnapshotInfo

use of org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo in project alluxio by Alluxio.

the class SnapshotReplicationManager method requestInfo.

private void requestInfo() {
    Preconditions.checkState(mDownloadState.get() == DownloadState.REQUEST_INFO);
    try {
        SingleFileSnapshotInfo latestSnapshot = mStorage.getLatestSnapshot();
        SnapshotMetadata snapshotMetadata = latestSnapshot == null ? null : SnapshotMetadata.newBuilder().setSnapshotTerm(latestSnapshot.getTerm()).setSnapshotIndex(latestSnapshot.getIndex()).build();
        // build SnapshotInfoRequests
        Map<RaftPeerId, CompletableFuture<RaftClientReply>> jobs = mJournalSystem.getQuorumServerInfoList().stream().filter(server -> server.getServerState() == QuorumServerState.AVAILABLE).map(server -> RaftJournalUtils.getPeerId(server.getServerAddress().getHost(), server.getServerAddress().getRpcPort())).filter(peerId -> !peerId.equals(mJournalSystem.getLocalPeerId())).collect(Collectors.toMap(Function.identity(), peerId -> mJournalSystem.sendMessageAsync(peerId, toMessage(JournalQueryRequest.newBuilder().setSnapshotInfoRequest(GetSnapshotInfoRequest.getDefaultInstance()).build()))));
        // query all secondary masters for information about their latest snapshot
        for (Map.Entry<RaftPeerId, CompletableFuture<RaftClientReply>> job : jobs.entrySet()) {
            RaftPeerId peerId = job.getKey();
            try {
                RaftClientReply reply = job.getValue().get();
                if (reply.getException() != null) {
                    throw reply.getException();
                }
                JournalQueryResponse response = JournalQueryResponse.parseFrom(reply.getMessage().getContent().asReadOnlyByteBuffer());
                if (!response.hasSnapshotInfoResponse()) {
                    throw new IOException("Invalid response for GetSnapshotInfoRequest " + response);
                }
                LOG.debug("Received snapshot info from follower {} - {}", peerId, response);
                SnapshotMetadata latest = response.getSnapshotInfoResponse().getLatest();
                if (snapshotMetadata == null || (latest.getSnapshotTerm() >= snapshotMetadata.getSnapshotTerm()) && latest.getSnapshotIndex() > snapshotMetadata.getSnapshotIndex()) {
                    mSnapshotCandidates.add(new Pair<>(latest, peerId));
                }
            } catch (Exception e) {
                LOG.warn("Error while requesting snapshot info from {}: {}", peerId, e.toString());
            }
        }
    } catch (Exception e) {
        LogUtils.warnWithException(LOG, "Failed to request snapshot info from followers", e);
    }
}
Also used : TermIndex(org.apache.ratis.server.protocol.TermIndex) PriorityQueue(java.util.PriorityQueue) LoggerFactory(org.slf4j.LoggerFactory) LogUtils(alluxio.util.LogUtils) GetSnapshotInfoResponse(alluxio.grpc.GetSnapshotInfoResponse) StreamObserver(io.grpc.stub.StreamObserver) JournalQueryRequest(alluxio.grpc.JournalQueryRequest) MetricKey(alluxio.metrics.MetricKey) Map(java.util.Map) Status(io.grpc.Status) ClientContext(alluxio.ClientContext) SnapshotInfo(org.apache.ratis.statemachine.SnapshotInfo) SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) UnsafeByteOperations(org.apache.ratis.thirdparty.com.google.protobuf.UnsafeByteOperations) ServerConfiguration(alluxio.conf.ServerConfiguration) JournalQueryResponse(alluxio.grpc.JournalQueryResponse) CompletionException(java.util.concurrent.CompletionException) SimpleStateMachineStorage(org.apache.ratis.statemachine.impl.SimpleStateMachineStorage) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) Timer(com.codahale.metrics.Timer) FileInfo(org.apache.ratis.server.storage.FileInfo) SnapshotData(alluxio.grpc.SnapshotData) MD5FileUtil(org.apache.ratis.util.MD5FileUtil) GetSnapshotInfoRequest(alluxio.grpc.GetSnapshotInfoRequest) UploadSnapshotPResponse(alluxio.grpc.UploadSnapshotPResponse) RaftLog(org.apache.ratis.server.raftlog.RaftLog) DownloadSnapshotPRequest(alluxio.grpc.DownloadSnapshotPRequest) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) Message(org.apache.ratis.protocol.Message) GetSnapshotRequest(alluxio.grpc.GetSnapshotRequest) QuorumServerState(alluxio.grpc.QuorumServerState) SnapshotMetadata(alluxio.grpc.SnapshotMetadata) ClientIpAddressInjector(alluxio.security.authentication.ClientIpAddressInjector) AbortedException(alluxio.exception.status.AbortedException) MetricsSystem(alluxio.metrics.MetricsSystem) AlluxioStatusException(alluxio.exception.status.AlluxioStatusException) DownloadSnapshotPResponse(alluxio.grpc.DownloadSnapshotPResponse) Logger(org.slf4j.Logger) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) IOException(java.io.IOException) Pair(alluxio.collections.Pair) NotFoundException(alluxio.exception.status.NotFoundException) File(java.io.File) MessageLite(com.google.protobuf.MessageLite) UploadSnapshotPRequest(alluxio.grpc.UploadSnapshotPRequest) MasterClientContext(alluxio.master.MasterClientContext) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) JournalQueryResponse(alluxio.grpc.JournalQueryResponse) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) FileNotFoundException(java.io.FileNotFoundException) AbortedException(alluxio.exception.status.AbortedException) AlluxioStatusException(alluxio.exception.status.AlluxioStatusException) IOException(java.io.IOException) NotFoundException(alluxio.exception.status.NotFoundException) SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) CompletableFuture(java.util.concurrent.CompletableFuture) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) SnapshotMetadata(alluxio.grpc.SnapshotMetadata) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) Map(java.util.Map)

Example 3 with SingleFileSnapshotInfo

use of org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo in project alluxio by Alluxio.

the class SnapshotReplicationManagerTest method validateSnapshotFile.

private void validateSnapshotFile(SimpleStateMachineStorage storage, long term, long index) throws IOException {
    SingleFileSnapshotInfo snapshot = storage.getLatestSnapshot();
    Assert.assertNotNull(snapshot);
    Assert.assertEquals(TermIndex.valueOf(term, index), snapshot.getTermIndex());
    byte[] received = FileUtils.readFileToByteArray(snapshot.getFiles().get(0).getPath().toFile());
    Assert.assertTrue(BufferUtils.equalIncreasingByteArray(SNAPSHOT_SIZE, received));
}
Also used : SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo)

Example 4 with SingleFileSnapshotInfo

use of org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo in project alluxio by Alluxio.

the class SnapshotReplicationManagerTest method downloadFailure.

/**
 * Simulates a {@link SnapshotDownloader} error.
 */
@Test
public void downloadFailure() throws Exception {
    before(2);
    List<Follower> followers = new ArrayList<>(mFollowers.values());
    Follower firstFollower = followers.get(0);
    Follower secondFollower = followers.get(1);
    // create default 0, 1 snapshot
    createSnapshotFile(firstFollower.mStore);
    // preferable to the default 0, 1 snapshot
    createSnapshotFile(secondFollower.mStore, 0, 2);
    // make sure to error out when requesting the better snapshot from secondFollower
    Mockito.doAnswer(mock -> {
        SingleFileSnapshotInfo snapshot = secondFollower.mStore.getLatestSnapshot();
        StreamObserver<UploadSnapshotPResponse> responseObserver = SnapshotUploader.forFollower(secondFollower.mStore, snapshot);
        StreamObserver<UploadSnapshotPRequest> requestObserver = mClient.uploadSnapshot(responseObserver);
        requestObserver.onError(new IOException("failed snapshot upload"));
        return null;
    }).when(secondFollower.mSnapshotManager).sendSnapshotToLeader();
    mLeaderSnapshotManager.maybeCopySnapshotFromFollower();
    CommonUtils.waitFor("leader snapshot to complete", () -> mLeaderSnapshotManager.maybeCopySnapshotFromFollower() != -1, mWaitOptions);
    // verify that the leader still requests and gets second best snapshot
    validateSnapshotFile(mLeaderStore);
}
Also used : SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) ArrayList(java.util.ArrayList) UploadSnapshotPRequest(alluxio.grpc.UploadSnapshotPRequest) IOException(java.io.IOException) UploadSnapshotPResponse(alluxio.grpc.UploadSnapshotPResponse) Test(org.junit.Test)

Example 5 with SingleFileSnapshotInfo

use of org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo in project alluxio by Alluxio.

the class SnapshotReplicationManagerTest method uploadFailure.

/**
 * Simulates a {@link SnapshotUploader} error.
 */
@Test
public void uploadFailure() throws Exception {
    before(2);
    List<Follower> followers = new ArrayList<>(mFollowers.values());
    Follower firstFollower = followers.get(0);
    Follower secondFollower = followers.get(1);
    // create default 0, 1 snapshot
    createSnapshotFile(firstFollower.mStore);
    // preferable to the default 0, 1 snapshot
    createSnapshotFile(secondFollower.mStore, 0, 2);
    // make sure to error out when requesting the better snapshot from secondFollower
    Mockito.doAnswer(mock -> {
        SingleFileSnapshotInfo snapshot = secondFollower.mStore.getLatestSnapshot();
        StreamObserver<UploadSnapshotPResponse> responseObserver = SnapshotUploader.forFollower(secondFollower.mStore, snapshot);
        StreamObserver<UploadSnapshotPRequest> requestObserver = mClient.uploadSnapshot(responseObserver);
        responseObserver.onError(new StatusRuntimeException(Status.UNAVAILABLE));
        requestObserver.onNext(UploadSnapshotPRequest.newBuilder().setData(SnapshotData.newBuilder().setSnapshotTerm(snapshot.getTerm()).setSnapshotIndex(snapshot.getIndex()).setOffset(0)).build());
        return null;
    }).when(secondFollower.mSnapshotManager).sendSnapshotToLeader();
    mLeaderSnapshotManager.maybeCopySnapshotFromFollower();
    CommonUtils.waitFor("leader snapshot to complete", () -> mLeaderSnapshotManager.maybeCopySnapshotFromFollower() != -1, mWaitOptions);
    // verify that the leader still requests and gets second best snapshot
    validateSnapshotFile(mLeaderStore);
}
Also used : SingleFileSnapshotInfo(org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo) ArrayList(java.util.ArrayList) StatusRuntimeException(io.grpc.StatusRuntimeException) UploadSnapshotPRequest(alluxio.grpc.UploadSnapshotPRequest) UploadSnapshotPResponse(alluxio.grpc.UploadSnapshotPResponse) Test(org.junit.Test)

Aggregations

SingleFileSnapshotInfo (org.apache.ratis.statemachine.impl.SingleFileSnapshotInfo)9 File (java.io.File)5 IOException (java.io.IOException)5 SimpleStateMachineStorage (org.apache.ratis.statemachine.impl.SimpleStateMachineStorage)5 Test (org.junit.Test)4 UploadSnapshotPRequest (alluxio.grpc.UploadSnapshotPRequest)3 UploadSnapshotPResponse (alluxio.grpc.UploadSnapshotPResponse)3 RaftStorageImpl (org.apache.ratis.server.storage.RaftStorageImpl)3 AlluxioURI (alluxio.AlluxioURI)2 FileSystem (alluxio.client.file.FileSystem)2 FileNotFoundException (java.io.FileNotFoundException)2 ArrayList (java.util.ArrayList)2 TermIndex (org.apache.ratis.server.protocol.TermIndex)2 FileInfo (org.apache.ratis.server.storage.FileInfo)2 ClientContext (alluxio.ClientContext)1 Pair (alluxio.collections.Pair)1 ServerConfiguration (alluxio.conf.ServerConfiguration)1 AbortedException (alluxio.exception.status.AbortedException)1 AlluxioStatusException (alluxio.exception.status.AlluxioStatusException)1 NotFoundException (alluxio.exception.status.NotFoundException)1