Search in sources :

Example 11 with RaftLog

use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.

the class RaftBasicTests method runTestOldLeaderCommit.

void runTestOldLeaderCommit(CLUSTER cluster) throws Exception {
    final RaftServer.Division leader = waitForLeader(cluster);
    final RaftPeerId leaderId = leader.getId();
    final long term = leader.getInfo().getCurrentTerm();
    final List<RaftServer.Division> followers = cluster.getFollowers();
    final List<RaftServer.Division> followersToSendLog = followers.subList(0, followers.size() / 2);
    for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
        cluster.killServer(followers.get(i).getId());
    }
    SimpleMessage[] messages = SimpleMessage.create(1);
    RaftTestUtil.sendMessageInNewThread(cluster, leaderId, messages);
    Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) + 100);
    for (RaftServer.Division followerToSendLog : followersToSendLog) {
        RaftLog followerLog = followerToSendLog.getRaftLog();
        Assert.assertTrue(RaftTestUtil.logEntriesContains(followerLog, messages));
    }
    LOG.info(String.format("killing old leader: %s", leaderId.toString()));
    cluster.killServer(leaderId);
    for (int i = followers.size() / 2; i < NUM_SERVERS - 1; i++) {
        final RaftPeerId followerId = followers.get(i).getId();
        LOG.info(String.format("restarting follower: %s", followerId));
        cluster.restartServer(followerId, false);
    }
    Thread.sleep(cluster.getTimeoutMax().toLong(TimeUnit.MILLISECONDS) * 5);
    // confirm the server with log is elected as new leader.
    final RaftPeerId newLeaderId = waitForLeader(cluster).getId();
    Set<RaftPeerId> followersToSendLogIds = followersToSendLog.stream().map(f -> f.getId()).collect(Collectors.toSet());
    Assert.assertTrue(followersToSendLogIds.contains(newLeaderId));
    cluster.getServerAliveStream().map(RaftServer.Division::getRaftLog).forEach(log -> RaftTestUtil.assertLogEntries(log, term, messages));
}
Also used : RetryCacheTestUtil(org.apache.ratis.server.impl.RetryCacheTestUtil) Timer(java.util.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Level(org.apache.log4j.Level) JavaUtils(org.apache.ratis.util.JavaUtils) TimerTask(java.util.TimerTask) BlockRequestHandlingInjection(org.apache.ratis.server.impl.BlockRequestHandlingInjection) RaftTestUtil.waitForLeader(org.apache.ratis.RaftTestUtil.waitForLeader) STATEMACHINE_APPLIED_INDEX_GAUGE(org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLIED_INDEX_GAUGE) Timestamp(org.apache.ratis.util.Timestamp) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) Predicate(java.util.function.Predicate) Set(java.util.Set) RATIS_STATEMACHINE_METRICS(org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS) Collectors(java.util.stream.Collectors) RATIS_STATEMACHINE_METRICS_DESC(org.apache.ratis.server.impl.StateMachineMetrics.RATIS_STATEMACHINE_METRICS_DESC) MetricRegistries(org.apache.ratis.metrics.MetricRegistries) MetricRegistryInfo(org.apache.ratis.metrics.MetricRegistryInfo) List(java.util.List) Stream(java.util.stream.Stream) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) Optional(java.util.Optional) ClientInvocationId(org.apache.ratis.protocol.ClientInvocationId) Gauge(com.codahale.metrics.Gauge) SortedMap(java.util.SortedMap) MiniRaftCluster(org.apache.ratis.server.impl.MiniRaftCluster) TimeDuration(org.apache.ratis.util.TimeDuration) RaftGroupMemberId(org.apache.ratis.protocol.RaftGroupMemberId) RaftLog(org.apache.ratis.server.raftlog.RaftLog) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) RATIS_APPLICATION_NAME_METRICS(org.apache.ratis.metrics.RatisMetrics.RATIS_APPLICATION_NAME_METRICS) Log4jUtils(org.apache.ratis.util.Log4jUtils) RaftServerTestUtil(org.apache.ratis.server.impl.RaftServerTestUtil) RaftServerMetricsImpl(org.apache.ratis.server.metrics.RaftServerMetricsImpl) Logger(org.slf4j.Logger) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) RaftClientTestUtil(org.apache.ratis.client.impl.RaftClientTestUtil) STATEMACHINE_APPLY_COMPLETED_GAUGE(org.apache.ratis.server.impl.StateMachineMetrics.STATEMACHINE_APPLY_COMPLETED_GAUGE) Test(org.junit.Test) IOException(java.io.IOException) RatisMetricRegistry(org.apache.ratis.metrics.RatisMetricRegistry) TimeUnit(java.util.concurrent.TimeUnit) ExitUtils(org.apache.ratis.util.ExitUtils) RaftServer(org.apache.ratis.server.RaftServer) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) Assert(org.junit.Assert) RaftServer(org.apache.ratis.server.RaftServer) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Example 12 with RaftLog

use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.

the class RaftTestUtil method assertLogEntries.

static void assertLogEntries(RaftServer.Division server, long expectedTerm, SimpleMessage... expectedMessages) {
    LOG.info("checking raft log for {}", server.getMemberId());
    final RaftLog log = server.getRaftLog();
    try {
        RaftTestUtil.assertLogEntries(log, expectedTerm, expectedMessages);
    } catch (AssertionError e) {
        LOG.error("Unexpected raft log in {}", server.getMemberId(), e);
        throw e;
    }
}
Also used : RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Example 13 with RaftLog

use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.

the class ServerRestartTests method runTestRestartFollower.

void runTestRestartFollower(MiniRaftCluster cluster) throws Exception {
    RaftTestUtil.waitForLeader(cluster);
    final RaftPeerId leaderId = cluster.getLeader().getId();
    // write some messages
    final AtomicInteger messageCount = new AtomicInteger();
    final Supplier<Message> newMessage = () -> new SimpleMessage("m" + messageCount.getAndIncrement());
    writeSomething(newMessage, cluster);
    // restart a follower
    RaftPeerId followerId = cluster.getFollowers().get(0).getId();
    LOG.info("Restart follower {}", followerId);
    cluster.restartServer(followerId, false);
    // write some more messages
    writeSomething(newMessage, cluster);
    final int truncatedMessageIndex = messageCount.get() - 1;
    final long leaderLastIndex = cluster.getLeader().getRaftLog().getLastEntryTermIndex().getIndex();
    // make sure the restarted follower can catchup
    final RaftServer.Division followerState = cluster.getDivision(followerId);
    JavaUtils.attemptRepeatedly(() -> {
        Assert.assertTrue(followerState.getInfo().getLastAppliedIndex() >= leaderLastIndex);
        return null;
    }, 10, ONE_SECOND, "follower catchup", LOG);
    // make sure the restarted peer's log segments is correct
    final RaftServer.Division follower = cluster.restartServer(followerId, false);
    final RaftLog followerLog = follower.getRaftLog();
    final long followerLastIndex = followerLog.getLastEntryTermIndex().getIndex();
    Assert.assertTrue(followerLastIndex >= leaderLastIndex);
    final File followerOpenLogFile = getOpenLogFile(follower);
    final File leaderOpenLogFile = getOpenLogFile(cluster.getDivision(leaderId));
    // shutdown all servers
    for (RaftServer s : cluster.getServers()) {
        s.close();
    }
    // truncate log and
    assertTruncatedLog(followerId, followerOpenLogFile, followerLastIndex, cluster);
    assertTruncatedLog(leaderId, leaderOpenLogFile, leaderLastIndex, cluster);
    // restart and write something.
    cluster.restart(false);
    writeSomething(newMessage, cluster);
    // restart again and check messages.
    cluster.restart(false);
    try (final RaftClient client = cluster.createClient()) {
        for (int i = 0; i < messageCount.get(); i++) {
            if (i != truncatedMessageIndex) {
                final Message m = new SimpleMessage("m" + i);
                final RaftClientReply reply = client.io().sendReadOnly(m);
                Assert.assertTrue(reply.isSuccess());
                LOG.info("query {}: {} {}", m, reply, LogEntryProto.parseFrom(reply.getMessage().getContent()));
            }
        }
    }
}
Also used : Message(org.apache.ratis.protocol.Message) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog) TestSegmentedRaftLog(org.apache.ratis.server.raftlog.segmented.TestSegmentedRaftLog)

Example 14 with RaftLog

use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.

the class TestRaftWithGrpc method runTestUpdateViaHeartbeat.

void runTestUpdateViaHeartbeat(MiniRaftClusterWithGrpc cluster) throws Exception {
    waitForLeader(cluster);
    try (final RaftClient client = cluster.createClient()) {
        // block append requests
        cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::blockWriteStateMachineData);
        CompletableFuture<RaftClientReply> replyFuture = client.async().send(new RaftTestUtil.SimpleMessage("abc"));
        TimeDuration.valueOf(5, TimeUnit.SECONDS).sleep();
        // replyFuture should not be completed until append request is unblocked.
        Assert.assertFalse(replyFuture.isDone());
        // unblock append request.
        cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).map(SimpleStateMachine4Testing::get).forEach(SimpleStateMachine4Testing::unblockWriteStateMachineData);
        final RaftLog leaderLog = cluster.getLeader().getRaftLog();
        // The entries have been appended in the followers
        // although the append entry timed out at the leader
        cluster.getServerAliveStream().filter(impl -> !impl.getInfo().isLeader()).forEach(raftServer -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
            final long leaderNextIndex = leaderLog.getNextIndex();
            final LogEntryHeader[] leaderEntries = leaderLog.getEntries(0, Long.MAX_VALUE);
            final RaftLog followerLog = raftServer.getRaftLog();
            Assert.assertEquals(leaderNextIndex, followerLog.getNextIndex());
            final LogEntryHeader[] serverEntries = followerLog.getEntries(0, Long.MAX_VALUE);
            Assert.assertArrayEquals(serverEntries, leaderEntries);
        }, 10, HUNDRED_MILLIS, "assertRaftLog-" + raftServer.getId(), LOG)));
        // Wait for heartbeats from leader to be received by followers
        Thread.sleep(500);
        RaftServerTestUtil.getLogAppenders(cluster.getLeader()).forEach(logAppender -> JavaUtils.runAsUnchecked(() -> JavaUtils.attempt(() -> {
            final long leaderNextIndex = leaderLog.getNextIndex();
            // FollowerInfo in the leader state should have updated next and match index.
            final long followerMatchIndex = logAppender.getFollower().getMatchIndex();
            Assert.assertTrue(followerMatchIndex >= leaderNextIndex - 1);
            Assert.assertEquals(followerMatchIndex + 1, logAppender.getFollower().getNextIndex());
        }, 10, HUNDRED_MILLIS, "assertRaftLog-" + logAppender.getFollower(), LOG)));
    }
}
Also used : RaftBasicTests(org.apache.ratis.RaftBasicTests) RaftTestUtil.waitForLeader(org.apache.ratis.RaftTestUtil.waitForLeader) LogEntryHeader(org.apache.ratis.server.raftlog.LogEntryHeader) StateMachine(org.apache.ratis.statemachine.StateMachine) RaftLog(org.apache.ratis.server.raftlog.RaftLog) Test(org.junit.Test) CompletableFuture(java.util.concurrent.CompletableFuture) RaftTestUtil(org.apache.ratis.RaftTestUtil) TimeUnit(java.util.concurrent.TimeUnit) RaftServerTestUtil(org.apache.ratis.server.impl.RaftServerTestUtil) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) RaftClient(org.apache.ratis.client.RaftClient) JavaUtils(org.apache.ratis.util.JavaUtils) Assert(org.junit.Assert) BlockRequestHandlingInjection(org.apache.ratis.server.impl.BlockRequestHandlingInjection) MiniRaftCluster(org.apache.ratis.server.impl.MiniRaftCluster) TimeDuration(org.apache.ratis.util.TimeDuration) SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) LogEntryHeader(org.apache.ratis.server.raftlog.LogEntryHeader) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) RaftTestUtil(org.apache.ratis.RaftTestUtil) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Example 15 with RaftLog

use of org.apache.ratis.server.raftlog.RaftLog in project incubator-ratis by apache.

the class RaftStateMachineExceptionTests method runTestRetryOnStateMachineException.

private void runTestRetryOnStateMachineException(CLUSTER cluster) throws Exception {
    RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
    cluster.getLeaderAndSendFirstMessage(true);
    final long oldLastApplied = cluster.getLeader().getInfo().getLastAppliedIndex();
    try (final RaftClient client = cluster.createClient(leaderId)) {
        final RaftClientRpc rpc = client.getClientRpc();
        final long callId = 999;
        final SimpleMessage message = new SimpleMessage("message");
        final RaftClientRequest r = cluster.newRaftClientRequest(client.getId(), leaderId, callId, message);
        RaftClientReply reply = rpc.sendRequest(r);
        Assert.assertFalse(reply.isSuccess());
        Assert.assertNotNull(reply.getStateMachineException());
        // retry with the same callId
        for (int i = 0; i < 5; i++) {
            reply = rpc.sendRequest(r);
            Assert.assertEquals(client.getId(), reply.getClientId());
            Assert.assertEquals(callId, reply.getCallId());
            Assert.assertFalse(reply.isSuccess());
            Assert.assertNotNull(reply.getStateMachineException());
        }
        for (RaftServer.Division server : cluster.iterateDivisions()) {
            LOG.info("check server " + server.getId());
            JavaUtils.attemptRepeatedly(() -> {
                Assert.assertNotNull(RetryCacheTestUtil.get(server, client.getId(), callId));
                return null;
            }, 5, BaseTest.ONE_SECOND, "GetRetryEntry", LOG);
            final RaftLog log = server.getRaftLog();
            RaftTestUtil.logEntriesContains(log, oldLastApplied + 1, log.getNextIndex(), message);
        }
        cluster.shutdown();
    }
}
Also used : RaftServer(org.apache.ratis.server.RaftServer) SimpleMessage(org.apache.ratis.RaftTestUtil.SimpleMessage) RaftClient(org.apache.ratis.client.RaftClient) RaftClientRpc(org.apache.ratis.client.RaftClientRpc) RaftLog(org.apache.ratis.server.raftlog.RaftLog)

Aggregations

RaftLog (org.apache.ratis.server.raftlog.RaftLog)23 RaftClient (org.apache.ratis.client.RaftClient)12 LogEntryProto (org.apache.ratis.proto.RaftProtos.LogEntryProto)12 RaftPeerId (org.apache.ratis.protocol.RaftPeerId)12 RaftServer (org.apache.ratis.server.RaftServer)11 IOException (java.io.IOException)9 SimpleMessage (org.apache.ratis.RaftTestUtil.SimpleMessage)9 RaftClientReply (org.apache.ratis.protocol.RaftClientReply)8 CompletableFuture (java.util.concurrent.CompletableFuture)7 TimeDuration (org.apache.ratis.util.TimeDuration)6 ArrayList (java.util.ArrayList)5 TimeUnit (java.util.concurrent.TimeUnit)5 JavaUtils (org.apache.ratis.util.JavaUtils)5 Assert (org.junit.Assert)5 File (java.io.File)4 List (java.util.List)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 TermIndex (org.apache.ratis.server.protocol.TermIndex)4 SimpleStateMachine4Testing (org.apache.ratis.statemachine.SimpleStateMachine4Testing)4 Arrays (java.util.Arrays)3