Search in sources :

Example 1 with DisruptorMetricSet

use of io.dingodb.raft.util.DisruptorMetricSet in project dingo by dingodb.

the class ReadOnlyServiceImpl method init.

@Override
public boolean init(final ReadOnlyServiceOptions opts) {
    this.node = opts.getNode();
    this.nodeMetrics = this.node.getNodeMetrics();
    this.fsmCaller = opts.getFsmCaller();
    this.raftOptions = opts.getRaftOptions();
    this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("ReadOnlyService-PendingNotify-Scanner", true));
    this.readIndexDisruptor = // 
    DisruptorBuilder.<ReadIndexEvent>newInstance().setEventFactory(// 
    new ReadIndexEventFactory()).setRingBufferSize(// 
    this.raftOptions.getDisruptorBufferSize()).setThreadFactory(// 
    new NamedThreadFactory("JRaft-ReadOnlyService-Disruptor-", true)).setWaitStrategy(// 
    new BlockingWaitStrategy()).setProducerType(// 
    ProducerType.MULTI).build();
    this.readIndexDisruptor.handleEventsWith(new ReadIndexEventHandler());
    this.readIndexDisruptor.setDefaultExceptionHandler(new LogExceptionHandler<Object>(getClass().getSimpleName()));
    this.readIndexQueue = this.readIndexDisruptor.start();
    if (this.nodeMetrics.getMetricRegistry() != null) {
        // 
        this.nodeMetrics.getMetricRegistry().register("jraft-read-only-service-disruptor", new DisruptorMetricSet(this.readIndexQueue));
    }
    // listen on lastAppliedLogIndex change events.
    this.fsmCaller.addLastAppliedLogIndexListener(this);
    // start scanner
    this.scheduledExecutorService.scheduleAtFixedRate(() -> onApplied(this.fsmCaller.getLastAppliedIndex()), this.raftOptions.getMaxElectionDelayMs(), this.raftOptions.getMaxElectionDelayMs(), TimeUnit.MILLISECONDS);
    return true;
}
Also used : BlockingWaitStrategy(com.lmax.disruptor.BlockingWaitStrategy) NamedThreadFactory(io.dingodb.raft.util.NamedThreadFactory) DisruptorMetricSet(io.dingodb.raft.util.DisruptorMetricSet)

Example 2 with DisruptorMetricSet

use of io.dingodb.raft.util.DisruptorMetricSet in project dingo by dingodb.

the class LogManagerImpl method init.

@Override
public boolean init(final LogManagerOptions opts) {
    this.writeLock.lock();
    try {
        if (opts.getLogStorage() == null) {
            LOG.error("Fail to init log manager, log storage is null");
            return false;
        }
        this.raftOptions = opts.getRaftOptions();
        this.nodeMetrics = opts.getNodeMetrics();
        this.logStorage = opts.getLogStorage();
        this.configManager = opts.getConfigurationManager();
        LogStorageOptions lsOpts = new LogStorageOptions();
        lsOpts.setConfigurationManager(this.configManager);
        lsOpts.setLogEntryCodecFactory(opts.getLogEntryCodecFactory());
        lsOpts.setRaftLogStorageOptions(opts.getRaftLogStorageOptions());
        if (!this.logStorage.init(lsOpts)) {
            LOG.error("Fail to init logStorage");
            return false;
        }
        this.firstLogIndex = this.logStorage.getFirstLogIndex();
        this.lastLogIndex = this.logStorage.getLastLogIndex();
        this.diskId = new LogId(this.lastLogIndex, getTermFromLogStorage(this.lastLogIndex));
        this.fsmCaller = opts.getFsmCaller();
        this.disruptor = // 
        DisruptorBuilder.<StableClosureEvent>newInstance().setEventFactory(// 
        new StableClosureEventFactory()).setRingBufferSize(// 
        opts.getDisruptorBufferSize()).setThreadFactory(// 
        new NamedThreadFactory("JRaft-LogManager-Disruptor-", true)).setProducerType(// 
        ProducerType.MULTI).setWaitStrategy(new BlockingWaitStrategy()).build();
        this.disruptor.handleEventsWith(new StableClosureEventHandler());
        this.disruptor.setDefaultExceptionHandler(new LogExceptionHandler<Object>(this.getClass().getSimpleName(), (event, ex) -> reportError(-1, "LogManager handle event error")));
        this.diskQueue = this.disruptor.start();
        if (this.nodeMetrics.getMetricRegistry() != null) {
            this.nodeMetrics.getMetricRegistry().register("jraft-log-manager-disruptor", new DisruptorMetricSet(this.diskQueue));
        }
    } finally {
        this.writeLock.unlock();
    }
    return true;
}
Also used : RaftException(io.dingodb.raft.error.RaftException) Requires(io.dingodb.raft.util.Requires) RaftError(io.dingodb.raft.error.RaftError) LogId(io.dingodb.raft.entity.LogId) LoggerFactory(org.slf4j.LoggerFactory) LogEntryCorruptedException(io.dingodb.raft.error.LogEntryCorruptedException) HashMap(java.util.HashMap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) NodeMetrics(io.dingodb.raft.core.NodeMetrics) LogEntry(io.dingodb.raft.entity.LogEntry) LogExceptionHandler(io.dingodb.raft.util.LogExceptionHandler) ArrayList(java.util.ArrayList) com.lmax.disruptor(com.lmax.disruptor) SnapshotMeta(io.dingodb.raft.entity.RaftOutter.SnapshotMeta) LogStorage(io.dingodb.raft.storage.LogStorage) Map(java.util.Map) ConfigurationEntry(io.dingodb.raft.conf.ConfigurationEntry) EntryType(io.dingodb.raft.entity.EnumOutter.EntryType) ThreadHelper(io.dingodb.raft.util.ThreadHelper) LogManager(io.dingodb.raft.storage.LogManager) RaftOptions(io.dingodb.raft.option.RaftOptions) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) DisruptorMetricSet(io.dingodb.raft.util.DisruptorMetricSet) Logger(org.slf4j.Logger) NamedThreadFactory(io.dingodb.raft.util.NamedThreadFactory) ArrayDeque(io.dingodb.raft.util.ArrayDeque) LogManagerOptions(io.dingodb.raft.option.LogManagerOptions) ProducerType(com.lmax.disruptor.dsl.ProducerType) ErrorType(io.dingodb.raft.entity.EnumOutter.ErrorType) Status(io.dingodb.raft.Status) Configuration(io.dingodb.raft.conf.Configuration) Utils(io.dingodb.raft.util.Utils) FSMCaller(io.dingodb.raft.FSMCaller) DisruptorBuilder(io.dingodb.raft.util.DisruptorBuilder) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Lock(java.util.concurrent.locks.Lock) PeerId(io.dingodb.raft.entity.PeerId) ConfigurationManager(io.dingodb.raft.conf.ConfigurationManager) LogStorageOptions(io.dingodb.raft.option.LogStorageOptions) SegmentList(io.dingodb.raft.util.SegmentList) Disruptor(com.lmax.disruptor.dsl.Disruptor) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) NamedThreadFactory(io.dingodb.raft.util.NamedThreadFactory) DisruptorMetricSet(io.dingodb.raft.util.DisruptorMetricSet) LogStorageOptions(io.dingodb.raft.option.LogStorageOptions) LogId(io.dingodb.raft.entity.LogId)

Example 3 with DisruptorMetricSet

use of io.dingodb.raft.util.DisruptorMetricSet in project dingo by dingodb.

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 (this.serverId.getIp().equals(Utils.IP_ANY)) {
        LOG.error("Node can't started from IP_ANY.");
        return false;
    }
    if (!NodeManager.getInstance().serverExists(this.serverId.getEndpoint())) {
        LOG.error("No RPC server attached to, did you forget to call addService?");
        return false;
    }
    this.timerManager = TIMER_FACTORY.getRaftScheduler(this.options.isSharedTimerPool(), this.options.getTimerPoolSize(), "JRaft-Node-ScheduleThreadPool");
    // Init timers
    final String suffix = getNodeId().toString();
    String name = "JRaft-VoteTimer-" + suffix;
    this.voteTimer = new RepeatedTimer(name, this.options.getElectionTimeoutMs(), TIMER_FACTORY.getVoteTimer(this.options.isSharedVoteTimer(), name)) {

        @Override
        protected void onTrigger() {
            handleVoteTimeout();
        }

        @Override
        protected int adjustTimeout(final int timeoutMs) {
            return randomTimeout(timeoutMs);
        }
    };
    name = "JRaft-ElectionTimer-" + suffix;
    this.electionTimer = new RepeatedTimer(name, this.options.getElectionTimeoutMs(), TIMER_FACTORY.getElectionTimer(this.options.isSharedElectionTimer(), name)) {

        @Override
        protected void onTrigger() {
            handleElectionTimeout();
        }

        @Override
        protected int adjustTimeout(final int timeoutMs) {
            return randomTimeout(timeoutMs);
        }
    };
    name = "JRaft-StepDownTimer-" + suffix;
    this.stepDownTimer = new RepeatedTimer(name, this.options.getElectionTimeoutMs() >> 1, TIMER_FACTORY.getStepDownTimer(this.options.isSharedStepDownTimer(), name)) {

        @Override
        protected void onTrigger() {
            handleStepDownTimeout();
        }
    };
    name = "JRaft-SnapshotTimer-" + suffix;
    this.snapshotTimer = new RepeatedTimer(name, this.options.getSnapshotIntervalSecs() * 1000, TIMER_FACTORY.getSnapshotTimer(this.options.isSharedSnapshotTimer(), name)) {

        private volatile boolean firstSchedule = true;

        @Override
        protected void onTrigger() {
            handleSnapshotTimeout();
        }

        @Override
        protected int adjustTimeout(final int timeoutMs) {
            if (!this.firstSchedule) {
                return timeoutMs;
            }
            // Randomize the first snapshot trigger timeout
            this.firstSchedule = false;
            if (timeoutMs > 0) {
                int half = timeoutMs / 2;
                return half + ThreadLocalRandom.current().nextInt(half);
            } else {
                return timeoutMs;
            }
        }
    };
    this.configManager = new ConfigurationManager();
    this.applyDisruptor = // 
    DisruptorBuilder.<LogEntryAndClosure>newInstance().setRingBufferSize(// 
    this.raftOptions.getDisruptorBufferSize()).setEventFactory(// 
    new LogEntryAndClosureFactory()).setThreadFactory(// 
    new NamedThreadFactory("JRaft-NodeImpl-Disruptor-", true)).setProducerType(// 
    ProducerType.MULTI).setWaitStrategy(// 
    new BlockingWaitStrategy()).build();
    this.applyDisruptor.handleEventsWith(new LogEntryAndClosureHandler());
    this.applyDisruptor.setDefaultExceptionHandler(new LogExceptionHandler<Object>(getClass().getSimpleName()));
    this.applyQueue = this.applyDisruptor.start();
    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);
    }
    // TODO RPC service and ReplicatorGroup is in cycle dependent, refactor it
    this.replicatorGroup = new ReplicatorGroupImpl();
    this.rpcService = new DefaultRaftClientService(this.replicatorGroup);
    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.rpcService);
    rgOpts.setSnapshotStorage(this.snapshotExecutor != null ? this.snapshotExecutor.getSnapshotStorage() : null);
    rgOpts.setRaftOptions(this.raftOptions);
    rgOpts.setTimerManager(this.timerManager);
    // Adds metric registry to RPC service.
    this.options.setMetricRegistry(this.metrics.getMetricRegistry());
    if (!this.rpcService.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.setFsmCaller(this.fsmCaller);
    rosOpts.setNode(this);
    rosOpts.setRaftOptions(this.raftOptions);
    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());
    }
    if (!NodeManager.getInstance().add(this)) {
        LOG.error("NodeManager add {} failed.", getNodeId());
        return false;
    }
    // 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 : BallotBoxOptions(io.dingodb.raft.option.BallotBoxOptions) ReadOnlyServiceOptions(io.dingodb.raft.option.ReadOnlyServiceOptions) RepeatedTimer(io.dingodb.raft.util.RepeatedTimer) ConfigurationManager(io.dingodb.raft.conf.ConfigurationManager) ConfigurationEntry(io.dingodb.raft.conf.ConfigurationEntry) Status(io.dingodb.raft.Status) BlockingWaitStrategy(com.lmax.disruptor.BlockingWaitStrategy) NamedThreadFactory(io.dingodb.raft.util.NamedThreadFactory) DisruptorMetricSet(io.dingodb.raft.util.DisruptorMetricSet) ReplicatorGroupOptions(io.dingodb.raft.option.ReplicatorGroupOptions) NodeId(io.dingodb.raft.entity.NodeId) DefaultRaftClientService(io.dingodb.raft.rpc.impl.core.DefaultRaftClientService) LogId(io.dingodb.raft.entity.LogId)

Example 4 with DisruptorMetricSet

use of io.dingodb.raft.util.DisruptorMetricSet in project dingo by dingodb.

the class FSMCallerImpl method init.

@Override
public boolean init(final FSMCallerOptions opts) {
    this.logManager = opts.getLogManager();
    this.fsm = opts.getFsm();
    this.closureQueue = opts.getClosureQueue();
    this.afterShutdown = opts.getAfterShutdown();
    this.node = opts.getNode();
    this.nodeMetrics = this.node.getNodeMetrics();
    this.lastAppliedIndex.set(opts.getBootstrapId().getIndex());
    notifyLastAppliedIndexUpdated(this.lastAppliedIndex.get());
    this.lastAppliedTerm = opts.getBootstrapId().getTerm();
    this.disruptor = // 
    DisruptorBuilder.<ApplyTask>newInstance().setEventFactory(// 
    new ApplyTaskFactory()).setRingBufferSize(// 
    opts.getDisruptorBufferSize()).setThreadFactory(// 
    new NamedThreadFactory("JRaft-FSMCaller-Disruptor-", true)).setProducerType(// 
    ProducerType.MULTI).setWaitStrategy(// 
    new BlockingWaitStrategy()).build();
    this.disruptor.handleEventsWith(new ApplyTaskHandler());
    this.disruptor.setDefaultExceptionHandler(new LogExceptionHandler<Object>(getClass().getSimpleName()));
    this.taskQueue = this.disruptor.start();
    if (this.nodeMetrics.getMetricRegistry() != null) {
        this.nodeMetrics.getMetricRegistry().register("jraft-fsm-caller-disruptor", new DisruptorMetricSet(this.taskQueue));
    }
    this.error = new RaftException(EnumOutter.ErrorType.ERROR_TYPE_NONE);
    LOG.info("Starts FSMCaller successfully.");
    return true;
}
Also used : RaftException(io.dingodb.raft.error.RaftException) BlockingWaitStrategy(com.lmax.disruptor.BlockingWaitStrategy) NamedThreadFactory(io.dingodb.raft.util.NamedThreadFactory) DisruptorMetricSet(io.dingodb.raft.util.DisruptorMetricSet)

Aggregations

DisruptorMetricSet (io.dingodb.raft.util.DisruptorMetricSet)4 NamedThreadFactory (io.dingodb.raft.util.NamedThreadFactory)4 BlockingWaitStrategy (com.lmax.disruptor.BlockingWaitStrategy)3 Status (io.dingodb.raft.Status)2 ConfigurationEntry (io.dingodb.raft.conf.ConfigurationEntry)2 ConfigurationManager (io.dingodb.raft.conf.ConfigurationManager)2 LogId (io.dingodb.raft.entity.LogId)2 RaftException (io.dingodb.raft.error.RaftException)2 com.lmax.disruptor (com.lmax.disruptor)1 Disruptor (com.lmax.disruptor.dsl.Disruptor)1 ProducerType (com.lmax.disruptor.dsl.ProducerType)1 FSMCaller (io.dingodb.raft.FSMCaller)1 Configuration (io.dingodb.raft.conf.Configuration)1 NodeMetrics (io.dingodb.raft.core.NodeMetrics)1 EntryType (io.dingodb.raft.entity.EnumOutter.EntryType)1 ErrorType (io.dingodb.raft.entity.EnumOutter.ErrorType)1 LogEntry (io.dingodb.raft.entity.LogEntry)1 NodeId (io.dingodb.raft.entity.NodeId)1 PeerId (io.dingodb.raft.entity.PeerId)1 SnapshotMeta (io.dingodb.raft.entity.RaftOutter.SnapshotMeta)1