Search in sources :

Example 1 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class ItCliServiceTest method testChangePeers.

@Test
public void testChangePeers() throws Exception {
    List<PeerId> newPeers = TestUtils.generatePeers(6);
    newPeers.removeAll(conf.getPeerSet());
    assertEquals(3, newPeers.size());
    for (PeerId peer : newPeers) {
        assertTrue(cluster.start(peer.getEndpoint()));
    }
    cluster.waitLeader();
    Node oldLeaderNode = cluster.getLeader();
    assertNotNull(oldLeaderNode);
    PeerId oldLeader = oldLeaderNode.getNodeId().getPeerId();
    assertNotNull(oldLeader);
    Status status = cliService.changePeers(groupId, conf, new Configuration(newPeers));
    assertTrue(status.isOk(), status.getErrorMsg());
    cluster.waitLeader();
    PeerId newLeader = cluster.getLeader().getNodeId().getPeerId();
    assertNotEquals(oldLeader, newLeader);
    assertTrue(newPeers.contains(newLeader));
}
Also used : Status(org.apache.ignite.raft.jraft.Status) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) Node(org.apache.ignite.raft.jraft.Node) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) Test(org.junit.jupiter.api.Test)

Example 2 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class ItNodeTest method testNodeTaskOverload.

@Test
public void testNodeTaskOverload() throws Exception {
    Endpoint addr = new Endpoint(TestUtils.getLocalAddress(), TestUtils.INIT_PORT);
    PeerId peer = new PeerId(addr, 0);
    NodeOptions nodeOptions = createNodeOptions();
    RaftOptions raftOptions = new RaftOptions();
    raftOptions.setDisruptorBufferSize(2);
    nodeOptions.setRaftOptions(raftOptions);
    MockStateMachine fsm = new MockStateMachine(addr);
    nodeOptions.setFsm(fsm);
    nodeOptions.setLogUri(dataPath + File.separator + "log");
    nodeOptions.setRaftMetaUri(dataPath + File.separator + "meta");
    nodeOptions.setSnapshotUri(dataPath + File.separator + "snapshot");
    nodeOptions.setInitialConf(new Configuration(Collections.singletonList(peer)));
    RaftGroupService service = createService("unittest", new PeerId(addr, 0), nodeOptions);
    Node node = service.start();
    assertEquals(1, node.listPeers().size());
    assertTrue(node.listPeers().contains(peer));
    while (!node.isLeader()) ;
    List<Task> tasks = new ArrayList<>();
    AtomicInteger c = new AtomicInteger(0);
    for (int i = 0; i < 10; i++) {
        ByteBuffer data = ByteBuffer.wrap(("hello" + i).getBytes(UTF_8));
        int finalI = i;
        Task task = new Task(data, new JoinableClosure(status -> {
            LOG.info("{} i={}", status, finalI);
            if (!status.isOk()) {
                assertTrue(status.getRaftError() == RaftError.EBUSY || status.getRaftError() == RaftError.EPERM);
            }
            c.incrementAndGet();
        }));
        node.apply(task);
        tasks.add(task);
    }
    Task.joinAll(tasks, TimeUnit.SECONDS.toMillis(30));
    assertEquals(10, c.get());
}
Also used : SynchronizedClosure(org.apache.ignite.raft.jraft.closure.SynchronizedClosure) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) ExponentialBackoffTimeoutStrategy(org.apache.ignite.raft.jraft.util.ExponentialBackoffTimeoutStrategy) TaskClosure(org.apache.ignite.raft.jraft.closure.TaskClosure) SnapshotThrottle(org.apache.ignite.raft.jraft.storage.SnapshotThrottle) Disabled(org.junit.jupiter.api.Disabled) BooleanSupplier(java.util.function.BooleanSupplier) AfterAll(org.junit.jupiter.api.AfterAll) Future(java.util.concurrent.Future) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) BeforeAll(org.junit.jupiter.api.BeforeAll) Path(java.nio.file.Path) Collections.synchronizedList(java.util.Collections.synchronizedList) Set(java.util.Set) Assertions.assertNotSame(org.junit.jupiter.api.Assertions.assertNotSame) ELECTION_TIMEOUT_MILLIS(org.apache.ignite.raft.jraft.core.TestCluster.ELECTION_TIMEOUT_MILLIS) TestUtils(org.apache.ignite.raft.jraft.test.TestUtils) ExecutorServiceHelper(org.apache.ignite.raft.jraft.util.ExecutorServiceHelper) Executors(java.util.concurrent.Executors) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Endpoint(org.apache.ignite.raft.jraft.util.Endpoint) RaftError(org.apache.ignite.raft.jraft.error.RaftError) RpcServer(org.apache.ignite.raft.jraft.rpc.RpcServer) Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) StateMachine(org.apache.ignite.raft.jraft.StateMachine) RaftException(org.apache.ignite.raft.jraft.error.RaftException) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) ArrayList(java.util.ArrayList) Task(org.apache.ignite.raft.jraft.entity.Task) IgniteRpcServer(org.apache.ignite.raft.jraft.rpc.impl.IgniteRpcServer) TestScaleCubeClusterServiceFactory(org.apache.ignite.network.scalecube.TestScaleCubeClusterServiceFactory) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) LinkedHashSet(java.util.LinkedHashSet) NodeManager(org.apache.ignite.raft.jraft.NodeManager) LogIndexOutOfBoundsException(org.apache.ignite.raft.jraft.error.LogIndexOutOfBoundsException) RaftGroupService(org.apache.ignite.raft.jraft.RaftGroupService) LogNotFoundException(org.apache.ignite.raft.jraft.error.LogNotFoundException) DefaultRaftClientService(org.apache.ignite.raft.jraft.rpc.impl.core.DefaultRaftClientService) File(java.io.File) Assertions.assertSame(org.junit.jupiter.api.Assertions.assertSame) WorkDirectory(org.apache.ignite.internal.testframework.WorkDirectory) NetworkAddress(org.apache.ignite.network.NetworkAddress) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) AfterEach(org.junit.jupiter.api.AfterEach) ConsoleReporter(com.codahale.metrics.ConsoleReporter) RaftOptions(org.apache.ignite.raft.jraft.option.RaftOptions) EnumOutter(org.apache.ignite.raft.jraft.entity.EnumOutter) Assertions.assertNotEquals(org.junit.jupiter.api.Assertions.assertNotEquals) TestUtils.sender(org.apache.ignite.raft.jraft.test.TestUtils.sender) IgniteLogger(org.apache.ignite.lang.IgniteLogger) ByteBuffer(java.nio.ByteBuffer) ReadOnlyOption(org.apache.ignite.raft.jraft.option.ReadOnlyOption) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NodeFinder(org.apache.ignite.network.NodeFinder) Node(org.apache.ignite.raft.jraft.Node) JoinableClosure(org.apache.ignite.raft.jraft.closure.JoinableClosure) TestIgniteRpcServer(org.apache.ignite.raft.jraft.rpc.TestIgniteRpcServer) SnapshotReader(org.apache.ignite.raft.jraft.storage.snapshot.SnapshotReader) Status(org.apache.ignite.raft.jraft.Status) BootstrapOptions(org.apache.ignite.raft.jraft.option.BootstrapOptions) TestInfo(org.junit.jupiter.api.TestInfo) Utils(org.apache.ignite.raft.jraft.util.Utils) Test(org.junit.jupiter.api.Test) List(java.util.List) StaticNodeFinder(org.apache.ignite.network.StaticNodeFinder) RpcClientEx(org.apache.ignite.raft.jraft.rpc.RpcClientEx) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) ReadIndexClosure(org.apache.ignite.raft.jraft.closure.ReadIndexClosure) Bits(org.apache.ignite.raft.jraft.util.Bits) ClusterServiceTestUtils(org.apache.ignite.utils.ClusterServiceTestUtils) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) FixedThreadsExecutorGroup(org.apache.ignite.raft.jraft.util.concurrent.FixedThreadsExecutorGroup) AtomicReference(java.util.concurrent.atomic.AtomicReference) NodeOptions(org.apache.ignite.raft.jraft.option.NodeOptions) HashSet(java.util.HashSet) BiPredicate(java.util.function.BiPredicate) Iterator(org.apache.ignite.raft.jraft.Iterator) ExecutorService(java.util.concurrent.ExecutorService) JRaftUtils(org.apache.ignite.raft.jraft.JRaftUtils) UTF_8(java.nio.charset.StandardCharsets.UTF_8) RpcRequests(org.apache.ignite.raft.jraft.rpc.RpcRequests) IgniteRpcClient(org.apache.ignite.raft.jraft.rpc.impl.IgniteRpcClient) TimeUnit(java.util.concurrent.TimeUnit) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) Collectors.toList(java.util.stream.Collectors.toList) ThroughputSnapshotThrottle(org.apache.ignite.raft.jraft.storage.snapshot.ThroughputSnapshotThrottle) ClusterService(org.apache.ignite.network.ClusterService) WorkDirectoryExtension(org.apache.ignite.internal.testframework.WorkDirectoryExtension) UserLog(org.apache.ignite.raft.jraft.entity.UserLog) Collections(java.util.Collections) RaftOptions(org.apache.ignite.raft.jraft.option.RaftOptions) Task(org.apache.ignite.raft.jraft.entity.Task) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) RaftGroupService(org.apache.ignite.raft.jraft.RaftGroupService) Node(org.apache.ignite.raft.jraft.Node) ArrayList(java.util.ArrayList) NodeOptions(org.apache.ignite.raft.jraft.option.NodeOptions) ByteBuffer(java.nio.ByteBuffer) Endpoint(org.apache.ignite.raft.jraft.util.Endpoint) Endpoint(org.apache.ignite.raft.jraft.util.Endpoint) JoinableClosure(org.apache.ignite.raft.jraft.closure.JoinableClosure) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PeerId(org.apache.ignite.raft.jraft.entity.PeerId) Test(org.junit.jupiter.api.Test)

Example 3 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method checkDeadNodes.

/**
 * @param conf The configuration.
 * @param monotonicNowMs The timestamp.
 * @param stepDownOnCheckFail {@code True} to step down on check fail.
 * @return {@code True} if a majority of peers are alive.
 */
private boolean checkDeadNodes(final Configuration conf, final long monotonicNowMs, final boolean stepDownOnCheckFail) {
    // Check learner replicators at first.
    for (final PeerId peer : conf.getLearners()) {
        checkReplicator(peer);
    }
    // Ensure quorum nodes alive.
    final List<PeerId> peers = conf.listPeers();
    final Configuration deadNodes = new Configuration();
    if (checkDeadNodes0(peers, monotonicNowMs, true, deadNodes)) {
        return true;
    }
    if (stepDownOnCheckFail) {
        LOG.warn("Node {} steps down when alive nodes don't satisfy quorum, term={}, deadNodes={}, conf={}.", getNodeId(), this.currTerm, deadNodes, conf);
        final Status status = new Status();
        status.setError(RaftError.ERAFTTIMEDOUT, "Majority of the group dies: %d/%d", deadNodes.size(), peers.size());
        stepDown(this.currTerm, false, status);
    }
    return false;
}
Also used : Status(org.apache.ignite.raft.jraft.Status) Configuration(org.apache.ignite.raft.jraft.conf.Configuration) PeerId(org.apache.ignite.raft.jraft.entity.PeerId)

Example 4 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method readLeader.

private void readLeader(ReadIndexRequest request, RpcResponseClosure<ReadIndexResponse> closure) {
    ReadIndexResponseBuilder respBuilder = raftOptions.getRaftMessagesFactory().readIndexResponse();
    final int quorum = getQuorum();
    if (quorum <= 1) {
        // Only one peer, fast path.
        respBuilder.success(true).index(this.ballotBox.getLastCommittedIndex());
        closure.setResponse(respBuilder.build());
        closure.run(Status.OK());
        return;
    }
    final long lastCommittedIndex = this.ballotBox.getLastCommittedIndex();
    if (this.logManager.getTerm(lastCommittedIndex) != this.currTerm) {
        // Reject read only request when this leader has not committed any log entry at its term
        closure.run(new Status(RaftError.EAGAIN, "ReadIndex request rejected because leader has not committed any log entry at its term, logIndex=%d, currTerm=%d.", lastCommittedIndex, this.currTerm));
        return;
    }
    respBuilder.index(lastCommittedIndex);
    if (request.peerId() != null) {
        // request from follower or learner, check if the follower/learner is in current conf.
        final PeerId peer = new PeerId();
        peer.parse(request.serverId());
        if (!this.conf.contains(peer) && !this.conf.containsLearner(peer)) {
            closure.run(new Status(RaftError.EPERM, "Peer %s is not in current configuration: %s.", peer, this.conf));
            return;
        }
    }
    ReadOnlyOption readOnlyOpt = this.raftOptions.getReadOnlyOptions();
    if (readOnlyOpt == ReadOnlyOption.ReadOnlyLeaseBased && !isLeaderLeaseValid()) {
        // If leader lease timeout, we must change option to ReadOnlySafe
        readOnlyOpt = ReadOnlyOption.ReadOnlySafe;
    }
    switch(readOnlyOpt) {
        case ReadOnlySafe:
            final List<PeerId> peers = this.conf.getConf().getPeers();
            Requires.requireTrue(peers != null && !peers.isEmpty(), "Empty peers");
            final ReadIndexHeartbeatResponseClosure heartbeatDone = new ReadIndexHeartbeatResponseClosure(closure, respBuilder, quorum, peers.size());
            // Send heartbeat requests to followers
            for (final PeerId peer : peers) {
                if (peer.equals(this.serverId)) {
                    continue;
                }
                this.replicatorGroup.sendHeartbeat(peer, heartbeatDone);
            }
            break;
        case ReadOnlyLeaseBased:
            // Responses to followers and local node.
            respBuilder.success(true);
            closure.setResponse(respBuilder.build());
            closure.run(Status.OK());
            break;
    }
}
Also used : Status(org.apache.ignite.raft.jraft.Status) ReadIndexResponseBuilder(org.apache.ignite.raft.jraft.rpc.ReadIndexResponseBuilder) ReadOnlyOption(org.apache.ignite.raft.jraft.option.ReadOnlyOption) PeerId(org.apache.ignite.raft.jraft.entity.PeerId)

Example 5 with Status

use of org.apache.ignite.raft.jraft.Status in project ignite-3 by apache.

the class NodeImpl method init.

@Override
public boolean init(final NodeOptions opts) {
    Requires.requireNonNull(opts, "Null node options");
    Requires.requireNonNull(opts.getRaftOptions(), "Null raft options");
    Requires.requireNonNull(opts.getServiceFactory(), "Null jraft service factory");
    this.serviceFactory = opts.getServiceFactory();
    this.options = opts;
    this.raftOptions = opts.getRaftOptions();
    this.metrics = new NodeMetrics(opts.isEnableMetrics());
    this.serverId.setPriority(opts.getElectionPriority());
    this.electionTimeoutCounter = 0;
    if (opts.getReplicationStateListeners() != null)
        this.replicatorStateListeners.addAll(opts.getReplicationStateListeners());
    if (this.serverId.getIp().equals(Utils.IP_ANY)) {
        LOG.error("Node can't start from IP_ANY.");
        return false;
    }
    // Init timers.
    initTimers(opts);
    // Init pools.
    initPools(opts);
    this.configManager = new ConfigurationManager();
    applyDisruptor = opts.getNodeApplyDisruptor();
    applyQueue = applyDisruptor.subscribe(groupId, new LogEntryAndClosureHandler());
    if (this.metrics.getMetricRegistry() != null) {
        this.metrics.getMetricRegistry().register("jraft-node-impl-disruptor", new DisruptorMetricSet(this.applyQueue));
    }
    this.fsmCaller = new FSMCallerImpl();
    if (!initLogStorage()) {
        LOG.error("Node {} initLogStorage failed.", getNodeId());
        return false;
    }
    if (!initMetaStorage()) {
        LOG.error("Node {} initMetaStorage failed.", getNodeId());
        return false;
    }
    if (!initFSMCaller(new LogId(0, 0))) {
        LOG.error("Node {} initFSMCaller failed.", getNodeId());
        return false;
    }
    this.ballotBox = new BallotBox();
    final BallotBoxOptions ballotBoxOpts = new BallotBoxOptions();
    ballotBoxOpts.setWaiter(this.fsmCaller);
    ballotBoxOpts.setClosureQueue(this.closureQueue);
    if (!this.ballotBox.init(ballotBoxOpts)) {
        LOG.error("Node {} init ballotBox failed.", getNodeId());
        return false;
    }
    if (!initSnapshotStorage()) {
        LOG.error("Node {} initSnapshotStorage failed.", getNodeId());
        return false;
    }
    final Status st = this.logManager.checkConsistency();
    if (!st.isOk()) {
        LOG.error("Node {} is initialized with inconsistent log, status={}.", getNodeId(), st);
        return false;
    }
    this.conf = new ConfigurationEntry();
    this.conf.setId(new LogId());
    // if have log using conf in log, else using conf in options
    if (this.logManager.getLastLogIndex() > 0) {
        checkAndSetConfiguration(false);
    } else {
        this.conf.setConf(this.options.getInitialConf());
        // initially set to max(priority of all nodes)
        this.targetPriority = getMaxPriorityOfNodes(this.conf.getConf().getPeers());
    }
    if (!this.conf.isEmpty()) {
        Requires.requireTrue(this.conf.isValid(), "Invalid conf: %s", this.conf);
    } else {
        LOG.info("Init node {} with empty conf.", this.serverId);
    }
    this.replicatorGroup = new ReplicatorGroupImpl();
    this.rpcClientService = new DefaultRaftClientService();
    final ReplicatorGroupOptions rgOpts = new ReplicatorGroupOptions();
    rgOpts.setHeartbeatTimeoutMs(heartbeatTimeout(this.options.getElectionTimeoutMs()));
    rgOpts.setElectionTimeoutMs(this.options.getElectionTimeoutMs());
    rgOpts.setLogManager(this.logManager);
    rgOpts.setBallotBox(this.ballotBox);
    rgOpts.setNode(this);
    rgOpts.setRaftRpcClientService(this.rpcClientService);
    rgOpts.setSnapshotStorage(this.snapshotExecutor != null ? this.snapshotExecutor.getSnapshotStorage() : null);
    rgOpts.setRaftOptions(this.raftOptions);
    rgOpts.setTimerManager(this.options.getScheduler());
    // Adds metric registry to RPC service.
    this.options.setMetricRegistry(this.metrics.getMetricRegistry());
    if (!this.rpcClientService.init(this.options)) {
        LOG.error("Fail to init rpc service.");
        return false;
    }
    this.replicatorGroup.init(new NodeId(this.groupId, this.serverId), rgOpts);
    this.readOnlyService = new ReadOnlyServiceImpl();
    final ReadOnlyServiceOptions rosOpts = new ReadOnlyServiceOptions();
    rosOpts.setGroupId(groupId);
    rosOpts.setFsmCaller(this.fsmCaller);
    rosOpts.setNode(this);
    rosOpts.setRaftOptions(this.raftOptions);
    rosOpts.setReadOnlyServiceDisruptor(opts.getReadOnlyServiceDisruptor());
    if (!this.readOnlyService.init(rosOpts)) {
        LOG.error("Fail to init readOnlyService.");
        return false;
    }
    // set state to follower
    this.state = State.STATE_FOLLOWER;
    if (LOG.isInfoEnabled()) {
        LOG.info("Node {} init, term={}, lastLogId={}, conf={}, oldConf={}.", getNodeId(), this.currTerm, this.logManager.getLastLogId(false), this.conf.getConf(), this.conf.getOldConf());
    }
    if (this.snapshotExecutor != null && this.options.getSnapshotIntervalSecs() > 0) {
        LOG.debug("Node {} start snapshot timer, term={}.", getNodeId(), this.currTerm);
        this.snapshotTimer.start();
    }
    if (!this.conf.isEmpty()) {
        stepDown(this.currTerm, false, new Status());
    }
    // Now the raft node is started , have to acquire the writeLock to avoid race
    // conditions
    this.writeLock.lock();
    if (this.conf.isStable() && this.conf.getConf().size() == 1 && this.conf.getConf().contains(this.serverId)) {
        // The group contains only this server which must be the LEADER, trigger
        // the timer immediately.
        electSelf();
    } else {
        this.writeLock.unlock();
    }
    return true;
}
Also used : Status(org.apache.ignite.raft.jraft.Status) DisruptorMetricSet(org.apache.ignite.raft.jraft.util.DisruptorMetricSet) ReplicatorGroupOptions(org.apache.ignite.raft.jraft.option.ReplicatorGroupOptions) BallotBoxOptions(org.apache.ignite.raft.jraft.option.BallotBoxOptions) ReadOnlyServiceOptions(org.apache.ignite.raft.jraft.option.ReadOnlyServiceOptions) NodeId(org.apache.ignite.raft.jraft.entity.NodeId) DefaultRaftClientService(org.apache.ignite.raft.jraft.rpc.impl.core.DefaultRaftClientService) ConfigurationManager(org.apache.ignite.raft.jraft.conf.ConfigurationManager) LogId(org.apache.ignite.raft.jraft.entity.LogId) ConfigurationEntry(org.apache.ignite.raft.jraft.conf.ConfigurationEntry)

Aggregations

Status (org.apache.ignite.raft.jraft.Status)121 Test (org.junit.jupiter.api.Test)49 PeerId (org.apache.ignite.raft.jraft.entity.PeerId)43 CountDownLatch (java.util.concurrent.CountDownLatch)31 Message (org.apache.ignite.raft.jraft.rpc.Message)21 ArrayList (java.util.ArrayList)20 Node (org.apache.ignite.raft.jraft.Node)20 Configuration (org.apache.ignite.raft.jraft.conf.Configuration)20 ReadIndexClosure (org.apache.ignite.raft.jraft.closure.ReadIndexClosure)16 LogId (org.apache.ignite.raft.jraft.entity.LogId)14 RaftException (org.apache.ignite.raft.jraft.error.RaftException)14 LogEntry (org.apache.ignite.raft.jraft.entity.LogEntry)11 JRaftException (org.apache.ignite.raft.jraft.error.JRaftException)11 SynchronizedClosure (org.apache.ignite.raft.jraft.closure.SynchronizedClosure)10 Endpoint (org.apache.ignite.raft.jraft.util.Endpoint)10 ByteBuffer (java.nio.ByteBuffer)9 List (java.util.List)9 ConfigurationEntry (org.apache.ignite.raft.jraft.conf.ConfigurationEntry)9 Task (org.apache.ignite.raft.jraft.entity.Task)8 RaftOptions (org.apache.ignite.raft.jraft.option.RaftOptions)8