Search in sources :

Example 6 with RaftLog

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

the class ServerRestartTests method assertLastLogEntry.

static void assertLastLogEntry(RaftServer.Division server) throws RaftLogIOException {
    final RaftLog raftLog = server.getRaftLog();
    final long lastIndex = raftLog.getLastEntryTermIndex().getIndex();
    final LogEntryProto lastEntry = raftLog.get(lastIndex);
    Assert.assertTrue(lastEntry.hasMetadataEntry());
    final long loggedCommitIndex = lastEntry.getMetadataEntry().getCommitIndex();
    final LogEntryProto lastCommittedEntry = raftLog.get(loggedCommitIndex);
    Assert.assertTrue(lastCommittedEntry.hasStateMachineLogEntry());
    final SimpleStateMachine4Testing leaderStateMachine = SimpleStateMachine4Testing.get(server);
    final TermIndex lastAppliedTermIndex = leaderStateMachine.getLastAppliedTermIndex();
    Assert.assertEquals(lastCommittedEntry.getTerm(), lastAppliedTermIndex.getTerm());
    Assert.assertTrue(lastCommittedEntry.getIndex() <= lastAppliedTermIndex.getIndex());
}
Also used : SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftLog(org.apache.ratis.server.raftlog.RaftLog) TestSegmentedRaftLog(org.apache.ratis.server.raftlog.segmented.TestSegmentedRaftLog) TermIndex(org.apache.ratis.server.protocol.TermIndex)

Example 7 with RaftLog

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

the class TestSegmentedRaftLog method testLoadLogSegments.

@Test
public void testLoadLogSegments() throws Exception {
    // first generate log files
    List<SegmentRange> ranges = prepareRanges(0, 5, 100, 0);
    LogEntryProto[] entries = prepareLog(ranges);
    // create RaftLog object and load log file
    try (SegmentedRaftLog raftLog = newSegmentedRaftLog()) {
        raftLog.open(RaftLog.INVALID_LOG_INDEX, null);
        // check if log entries are loaded correctly
        for (LogEntryProto e : entries) {
            LogEntryProto entry = raftLog.get(e.getIndex());
            Assert.assertEquals(e, entry);
        }
        final LogEntryHeader[] termIndices = raftLog.getEntries(0, 500);
        LogEntryProto[] entriesFromLog = Arrays.stream(termIndices).map(ti -> {
            try {
                return raftLog.get(ti.getIndex());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }).toArray(LogEntryProto[]::new);
        Assert.assertArrayEquals(entries, entriesFromLog);
        Assert.assertEquals(entries[entries.length - 1], getLastEntry(raftLog));
        final RatisMetricRegistry metricRegistryForLogWorker = RaftLogMetricsBase.getLogWorkerMetricRegistry(memberId);
        Timer raftLogSegmentLoadLatencyTimer = metricRegistryForLogWorker.timer("segmentLoadLatency");
        assertTrue(raftLogSegmentLoadLatencyTimer.getMeanRate() > 0);
        Timer raftLogReadLatencyTimer = metricRegistryForLogWorker.timer("readEntryLatency");
        assertTrue(raftLogReadLatencyTimer.getMeanRate() > 0);
    }
}
Also used : LogProtoUtils(org.apache.ratis.server.raftlog.LogProtoUtils) Arrays(java.util.Arrays) RetryCache(org.apache.ratis.server.RetryCache) TermIndex(org.apache.ratis.server.protocol.TermIndex) LogEntryHeader(org.apache.ratis.server.raftlog.LogEntryHeader) LongSupplier(java.util.function.LongSupplier) RaftGroupMemberId(org.apache.ratis.protocol.RaftGroupMemberId) RaftLog(org.apache.ratis.server.raftlog.RaftLog) RetryCacheTestUtil(org.apache.ratis.server.impl.RetryCacheTestUtil) CompletableFuture(java.util.concurrent.CompletableFuture) Supplier(java.util.function.Supplier) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) RaftGroupId(org.apache.ratis.protocol.RaftGroupId) TimeoutIOException(org.apache.ratis.protocol.exceptions.TimeoutIOException) RaftLogMetricsBase(org.apache.ratis.server.metrics.RaftLogMetricsBase) Log4jUtils(org.apache.ratis.util.Log4jUtils) Level(org.apache.log4j.Level) After(org.junit.After) SimpleStateMachine4Testing(org.apache.ratis.statemachine.SimpleStateMachine4Testing) RaftStorage(org.apache.ratis.server.storage.RaftStorage) JavaUtils(org.apache.ratis.util.JavaUtils) SizeInBytes(org.apache.ratis.util.SizeInBytes) Before(org.junit.Before) StateMachine(org.apache.ratis.statemachine.StateMachine) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftServerConfigKeys(org.apache.ratis.server.RaftServerConfigKeys) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) IOException(java.io.IOException) BaseTest(org.apache.ratis.BaseTest) RatisMetricRegistry(org.apache.ratis.metrics.RatisMetricRegistry) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) FileUtils(org.apache.ratis.util.FileUtils) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) BaseStateMachine(org.apache.ratis.statemachine.impl.BaseStateMachine) RaftStorageTestUtils(org.apache.ratis.server.storage.RaftStorageTestUtils) RaftProperties(org.apache.ratis.conf.RaftProperties) LifeCycle(org.apache.ratis.util.LifeCycle) Timer(com.codahale.metrics.Timer) SimpleOperation(org.apache.ratis.RaftTestUtil.SimpleOperation) Assert(org.junit.Assert) Collections(java.util.Collections) TimeDuration(org.apache.ratis.util.TimeDuration) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) LogEntryHeader(org.apache.ratis.server.raftlog.LogEntryHeader) Timer(com.codahale.metrics.Timer) TimeoutIOException(org.apache.ratis.protocol.exceptions.TimeoutIOException) IOException(java.io.IOException) RatisMetricRegistry(org.apache.ratis.metrics.RatisMetricRegistry) Test(org.junit.Test) BaseTest(org.apache.ratis.BaseTest)

Example 8 with RaftLog

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

the class RaftReconfigurationBaseTest method runTestKillLeaderDuringReconf.

void runTestKillLeaderDuringReconf(CLUSTER cluster) throws Exception {
    final AtomicBoolean clientRunning = new AtomicBoolean(true);
    Thread clientThread = null;
    try {
        final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
        PeerChanges c1 = cluster.addNewPeers(1, false);
        PeerChanges c2 = cluster.removePeers(1, false, asList(c1.newPeers));
        LOG.info("Start setConf: {}", asList(c2.allPeersInNewConf));
        LOG.info(cluster.printServers());
        final CompletableFuture<Void> setConf = new CompletableFuture<>();
        clientThread = new Thread(() -> {
            try (final RaftClient client = cluster.createClient(leaderId)) {
                for (int i = 0; clientRunning.get() && !setConf.isDone(); i++) {
                    final RaftClientReply reply = client.admin().setConfiguration(c2.allPeersInNewConf);
                    if (reply.isSuccess()) {
                        setConf.complete(null);
                    }
                    LOG.info("setConf attempt #{} failed, {}", i, cluster.printServers());
                }
            } catch (Exception e) {
                LOG.error("Failed to setConf", e);
                setConf.completeExceptionally(e);
            }
        });
        clientThread.start();
        TimeUnit.SECONDS.sleep(1);
        // the leader cannot generate the (old, new) conf, and it will keep
        // bootstrapping the 2 new peers since they have not started yet
        Assert.assertFalse(((RaftConfigurationImpl) cluster.getLeader().getRaftConf()).isTransitional());
        // only (0) the first conf entry, (1) the 1st setConf entry and (2) a metadata entry
        {
            final RaftLog leaderLog = cluster.getLeader().getRaftLog();
            for (LogEntryProto e : RaftTestUtil.getLogEntryProtos(leaderLog)) {
                LOG.info("{}", LogProtoUtils.toLogEntryString(e));
            }
            final long commitIndex = leaderLog.getLastCommittedIndex();
            Assert.assertTrue("commitIndex = " + commitIndex + " > 2", commitIndex <= 2);
        }
        final RaftPeerId killed = RaftTestUtil.waitAndKillLeader(cluster);
        Assert.assertEquals(leaderId, killed);
        final RaftPeerId newLeaderId = RaftTestUtil.waitForLeader(cluster).getId();
        LOG.info("newLeaderId: {}", newLeaderId);
        LOG.info("start new peers: {}", Arrays.asList(c1.newPeers));
        for (RaftPeer np : c1.newPeers) {
            cluster.restartServer(np.getId(), false);
        }
        try {
            setConf.get(10, TimeUnit.SECONDS);
        } catch (TimeoutException ignored) {
        }
        // the client fails with the first leader, and then retry the same setConfiguration request
        waitAndCheckNewConf(cluster, c2.allPeersInNewConf, 2, Collections.singletonList(leaderId));
        setConf.get(1, TimeUnit.SECONDS);
    } finally {
        if (clientThread != null) {
            clientRunning.set(false);
            clientThread.interrupt();
        }
    }
}
Also used : RaftPeer(org.apache.ratis.protocol.RaftPeer) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationInProgressException(org.apache.ratis.protocol.exceptions.ReconfigurationInProgressException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) PeerChanges(org.apache.ratis.server.impl.MiniRaftCluster.PeerChanges) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException)

Example 9 with RaftLog

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

the class RaftReconfigurationBaseTest method runTestRevertConfigurationChange.

void runTestRevertConfigurationChange(CLUSTER cluster) throws Exception {
    RaftLogBase log2 = null;
    try {
        RaftTestUtil.waitForLeader(cluster);
        final RaftServer.Division leader = cluster.getLeader();
        final RaftPeerId leaderId = leader.getId();
        final RaftLog log = leader.getRaftLog();
        log2 = (RaftLogBase) log;
        Thread.sleep(1000);
        // we block the incoming msg for the leader and block its requests to
        // followers, so that we force the leader change and the old leader will
        // not know
        LOG.info("start blocking the leader");
        BlockRequestHandlingInjection.getInstance().blockReplier(leaderId.toString());
        cluster.setBlockRequestsFrom(leaderId.toString(), true);
        PeerChanges change = cluster.removePeers(1, false, new ArrayList<>());
        AtomicBoolean gotNotLeader = new AtomicBoolean(false);
        final Thread clientThread = new Thread(() -> {
            try (final RaftClient client = cluster.createClient(leaderId)) {
                LOG.info("client starts to change conf");
                final RaftClientRpc sender = client.getClientRpc();
                RaftClientReply reply = sender.sendRequest(cluster.newSetConfigurationRequest(client.getId(), leaderId, change.allPeersInNewConf));
                if (reply.getNotLeaderException() != null) {
                    gotNotLeader.set(true);
                }
            } catch (IOException e) {
                LOG.warn("Got unexpected exception when client1 changes conf", e);
            }
        });
        clientThread.start();
        // find ConfigurationEntry
        final TimeDuration sleepTime = TimeDuration.valueOf(500, TimeUnit.MILLISECONDS);
        final long confIndex = JavaUtils.attemptRepeatedly(() -> {
            final long last = log.getLastEntryTermIndex().getIndex();
            for (long i = last; i >= 1; i--) {
                if (log.get(i).hasConfigurationEntry()) {
                    return i;
                }
            }
            throw new Exception("ConfigurationEntry not found: last=" + last);
        }, 10, sleepTime, "confIndex", LOG);
        // wait till the old leader persist the new conf
        JavaUtils.attemptRepeatedly(() -> {
            Assert.assertTrue(log.getFlushIndex() >= confIndex);
            return null;
        }, 10, sleepTime, "FLUSH", LOG);
        final long committed = log.getLastCommittedIndex();
        Assert.assertTrue(committed < confIndex);
        // unblock the old leader
        BlockRequestHandlingInjection.getInstance().unblockReplier(leaderId.toString());
        cluster.setBlockRequestsFrom(leaderId.toString(), false);
        // the client should get NotLeaderException
        clientThread.join(5000);
        Assert.assertTrue(gotNotLeader.get());
        // the old leader should have truncated the setConf from the log
        JavaUtils.attemptRepeatedly(() -> {
            Assert.assertTrue(log.getLastCommittedIndex() >= confIndex);
            return null;
        }, 10, ONE_SECOND, "COMMIT", LOG);
        Assert.assertTrue(log.get(confIndex).hasConfigurationEntry());
        log2 = null;
    } finally {
        RaftStorageTestUtils.printLog(log2, s -> LOG.info(s));
    }
}
Also used : RaftServer(org.apache.ratis.server.RaftServer) RaftLogBase(org.apache.ratis.server.raftlog.RaftLogBase) IOException(java.io.IOException) LeaderNotReadyException(org.apache.ratis.protocol.exceptions.LeaderNotReadyException) TimeoutException(java.util.concurrent.TimeoutException) ReconfigurationInProgressException(org.apache.ratis.protocol.exceptions.ReconfigurationInProgressException) ReconfigurationTimeoutException(org.apache.ratis.protocol.exceptions.ReconfigurationTimeoutException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) RaftClientReply(org.apache.ratis.protocol.RaftClientReply) PeerChanges(org.apache.ratis.server.impl.MiniRaftCluster.PeerChanges) TimeDuration(org.apache.ratis.util.TimeDuration) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) RaftLog(org.apache.ratis.server.raftlog.RaftLog) RaftClientRpc(org.apache.ratis.client.RaftClientRpc)

Example 10 with RaftLog

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

the class LogAppenderTests method runTest.

void runTest(CLUSTER cluster) throws Exception {
    final int numMsgs = 10;
    final int numClients = 5;
    final RaftPeerId leaderId = RaftTestUtil.waitForLeader(cluster).getId();
    List<RaftClient> clients = new ArrayList<>();
    try {
        List<Sender> senders = new ArrayList<>();
        // start several clients and write concurrently
        final CountDownLatch latch = new CountDownLatch(1);
        for (int i = 0; i < numClients; i++) {
            RaftClient client = cluster.createClient(leaderId);
            clients.add(client);
            senders.add(new Sender(client, numMsgs, latch));
        }
        senders.forEach(Thread::start);
        latch.countDown();
        for (Sender s : senders) {
            s.join();
            final Exception e = s.exception.get();
            if (e != null) {
                throw e;
            }
            Assert.assertTrue(s.succeed.get());
        }
    } finally {
        for (int i = 0; i < clients.size(); i++) {
            try {
                clients.get(i).close();
            } catch (Exception ignored) {
                LOG.warn("{} is ignored", JavaUtils.getClassSimpleName(ignored.getClass()), ignored);
            }
        }
    }
    final RaftServer.Division leader = cluster.getLeader();
    final RaftLog leaderLog = cluster.getLeader().getRaftLog();
    final EnumMap<LogEntryBodyCase, AtomicLong> counts = RaftTestUtil.countEntries(leaderLog);
    LOG.info("counts = " + counts);
    Assert.assertEquals(6 * numMsgs * numClients, counts.get(LogEntryBodyCase.STATEMACHINELOGENTRY).get());
    final LogEntryProto last = RaftTestUtil.getLastEntry(LogEntryBodyCase.STATEMACHINELOGENTRY, leaderLog);
    LOG.info("last = {}", LogProtoUtils.toLogEntryString(last));
    Assert.assertNotNull(last);
    Assert.assertTrue(last.getIndex() <= leader.getInfo().getLastAppliedIndex());
}
Also used : RaftServer(org.apache.ratis.server.RaftServer) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) IOException(java.io.IOException) LogEntryBodyCase(org.apache.ratis.proto.RaftProtos.LogEntryProto.LogEntryBodyCase) AtomicLong(java.util.concurrent.atomic.AtomicLong) LogEntryProto(org.apache.ratis.proto.RaftProtos.LogEntryProto) RaftPeerId(org.apache.ratis.protocol.RaftPeerId) RaftClient(org.apache.ratis.client.RaftClient) 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