Search in sources :

Example 1 with ConfigurationManager

use of io.dingodb.raft.conf.ConfigurationManager in project dingo by dingodb.

the class RocksDBLogStorage method initAndLoad.

private boolean initAndLoad(final LogStorageOptions lopts) throws RocksDBException {
    this.hasLoadFirstLogIndex = false;
    this.firstLogIndex = 1;
    final List<ColumnFamilyDescriptor> columnFamilyDescriptors = new ArrayList<>();
    final ColumnFamilyOptions cfOption = createColumnFamilyOptions();
    ConfigurationManager confManager = lopts.getConfigurationManager();
    BlockBasedTableConfig tableConfig = new BlockBasedTableConfig();
    tableConfig.setBlockSize(128 * 1024);
    RaftLogStorageOptions raftLogStorageOptions = lopts.getRaftLogStorageOptions();
    if (raftLogStorageOptions.getCfBlockSize() != 0) {
        tableConfig.setBlockSize(raftLogStorageOptions.getCfBlockSize());
    }
    tableConfig.setBlockCacheSize(200 / 4 * 1024 * 1024 * 1024L);
    if (raftLogStorageOptions.getCfBlockCacheSize() != 0) {
        tableConfig.setBlockSize(raftLogStorageOptions.getCfBlockCacheSize());
    }
    cfOption.setTableFormatConfig(tableConfig);
    cfOption.setArenaBlockSize(128 * 1024 * 1024);
    if (raftLogStorageOptions.getCfArenaBlockSize() != 0) {
        cfOption.setArenaBlockSize(raftLogStorageOptions.getCfArenaBlockSize());
    }
    cfOption.setMinWriteBufferNumberToMerge(4);
    if (raftLogStorageOptions.getCfMinWriteBufferNumberToMerge() != 0) {
        cfOption.setMinWriteBufferNumberToMerge(raftLogStorageOptions.getCfMinWriteBufferNumberToMerge());
    }
    cfOption.setMaxWriteBufferNumber(5);
    if (raftLogStorageOptions.getCfMaxWriteBufferNumber() != 0) {
        cfOption.setMaxWriteBufferNumber(raftLogStorageOptions.getCfMaxWriteBufferNumber());
    }
    cfOption.setMaxCompactionBytes(512 * 1024 * 1024);
    if (raftLogStorageOptions.getCfMaxCompactionBytes() != 0) {
        cfOption.setMaxCompactionBytes(raftLogStorageOptions.getCfMaxCompactionBytes());
    }
    cfOption.setWriteBufferSize(1 * 1024 * 1024 * 1024);
    if (raftLogStorageOptions.getCfWriteBufferSize() != 0) {
        cfOption.setWriteBufferSize(raftLogStorageOptions.getCfWriteBufferSize());
    }
    this.cfOptions.add(cfOption);
    // Column family to store configuration log entry.
    columnFamilyDescriptors.add(new ColumnFamilyDescriptor("Configuration".getBytes(), cfOption));
    // Default column family to store user data log entry.
    columnFamilyDescriptors.add(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOption));
    openDB(columnFamilyDescriptors);
    load(confManager);
    return onInitLoaded();
}
Also used : ColumnFamilyOptions(org.rocksdb.ColumnFamilyOptions) RaftLogStorageOptions(io.dingodb.raft.option.RaftLogStorageOptions) ArrayList(java.util.ArrayList) BlockBasedTableConfig(org.rocksdb.BlockBasedTableConfig) ColumnFamilyDescriptor(org.rocksdb.ColumnFamilyDescriptor) ConfigurationManager(io.dingodb.raft.conf.ConfigurationManager)

Example 2 with ConfigurationManager

use of io.dingodb.raft.conf.ConfigurationManager in project dingo by dingodb.

the class NodeImpl method bootstrap.

public boolean bootstrap(final BootstrapOptions opts) throws InterruptedException {
    if (opts.getLastLogIndex() > 0 && (opts.getGroupConf().isEmpty() || opts.getFsm() == null)) {
        LOG.error("Invalid arguments for bootstrap, groupConf={}, fsm={}, lastLogIndex={}.", opts.getGroupConf(), opts.getFsm(), opts.getLastLogIndex());
        return false;
    }
    if (opts.getGroupConf().isEmpty()) {
        LOG.error("Bootstrapping an empty node makes no sense.");
        return false;
    }
    Requires.requireNonNull(opts.getServiceFactory(), "Null jraft service factory");
    this.serviceFactory = opts.getServiceFactory();
    // Term is not an option since changing it is very dangerous
    final long bootstrapLogTerm = opts.getLastLogIndex() > 0 ? 1 : 0;
    final LogId bootstrapId = new LogId(opts.getLastLogIndex(), bootstrapLogTerm);
    this.options = new NodeOptions();
    this.raftOptions = this.options.getRaftOptions();
    this.metrics = new NodeMetrics(opts.isEnableMetrics());
    this.options.setFsm(opts.getFsm());
    this.options.setLogUri(opts.getLogUri());
    this.options.setRaftMetaUri(opts.getRaftMetaUri());
    this.options.setSnapshotUri(opts.getSnapshotUri());
    this.configManager = new ConfigurationManager();
    // Create fsmCaller at first as logManager needs it to report error
    this.fsmCaller = new FSMCallerImpl();
    if (!initLogStorage()) {
        LOG.error("Fail to init log storage.");
        return false;
    }
    if (!initMetaStorage()) {
        LOG.error("Fail to init meta storage.");
        return false;
    }
    if (this.currTerm == 0) {
        this.currTerm = 1;
        if (!this.metaStorage.setTermAndVotedFor(1, new PeerId())) {
            LOG.error("Fail to set term.");
            return false;
        }
    }
    if (opts.getFsm() != null && !initFSMCaller(bootstrapId)) {
        LOG.error("Fail to init fsm caller.");
        return false;
    }
    final LogEntry entry = new LogEntry(EnumOutter.EntryType.ENTRY_TYPE_CONFIGURATION);
    entry.getId().setTerm(this.currTerm);
    entry.setPeers(opts.getGroupConf().listPeers());
    entry.setLearners(opts.getGroupConf().listLearners());
    final List<LogEntry> entries = new ArrayList<>();
    entries.add(entry);
    final BootstrapStableClosure bootstrapDone = new BootstrapStableClosure();
    this.logManager.appendEntries(entries, bootstrapDone);
    if (!bootstrapDone.await().isOk()) {
        LOG.error("Fail to append configuration.");
        return false;
    }
    if (opts.getLastLogIndex() > 0) {
        if (!initSnapshotStorage()) {
            LOG.error("Fail to init snapshot storage.");
            return false;
        }
        final SynchronizedClosure snapshotDone = new SynchronizedClosure();
        this.snapshotExecutor.doSnapshot(snapshotDone);
        if (!snapshotDone.await().isOk()) {
            LOG.error("Fail to save snapshot, status={}.", snapshotDone.getStatus());
            return false;
        }
    }
    if (this.logManager.getFirstLogIndex() != opts.getLastLogIndex() + 1) {
        throw new IllegalStateException("First and last log index mismatch");
    }
    if (opts.getLastLogIndex() > 0) {
        if (this.logManager.getLastLogIndex() != opts.getLastLogIndex()) {
            throw new IllegalStateException("Last log index mismatch");
        }
    } else {
        if (this.logManager.getLastLogIndex() != opts.getLastLogIndex() + 1) {
            throw new IllegalStateException("Last log index mismatch");
        }
    }
    return true;
}
Also used : SynchronizedClosure(io.dingodb.raft.closure.SynchronizedClosure) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) NodeOptions(io.dingodb.raft.option.NodeOptions) LogId(io.dingodb.raft.entity.LogId) ConfigurationManager(io.dingodb.raft.conf.ConfigurationManager) LogEntry(io.dingodb.raft.entity.LogEntry) PeerId(io.dingodb.raft.entity.PeerId)

Example 3 with ConfigurationManager

use of io.dingodb.raft.conf.ConfigurationManager 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)

Aggregations

ConfigurationManager (io.dingodb.raft.conf.ConfigurationManager)3 LogId (io.dingodb.raft.entity.LogId)2 ArrayList (java.util.ArrayList)2 BlockingWaitStrategy (com.lmax.disruptor.BlockingWaitStrategy)1 Status (io.dingodb.raft.Status)1 SynchronizedClosure (io.dingodb.raft.closure.SynchronizedClosure)1 ConfigurationEntry (io.dingodb.raft.conf.ConfigurationEntry)1 LogEntry (io.dingodb.raft.entity.LogEntry)1 NodeId (io.dingodb.raft.entity.NodeId)1 PeerId (io.dingodb.raft.entity.PeerId)1 BallotBoxOptions (io.dingodb.raft.option.BallotBoxOptions)1 NodeOptions (io.dingodb.raft.option.NodeOptions)1 RaftLogStorageOptions (io.dingodb.raft.option.RaftLogStorageOptions)1 ReadOnlyServiceOptions (io.dingodb.raft.option.ReadOnlyServiceOptions)1 ReplicatorGroupOptions (io.dingodb.raft.option.ReplicatorGroupOptions)1 DefaultRaftClientService (io.dingodb.raft.rpc.impl.core.DefaultRaftClientService)1 DisruptorMetricSet (io.dingodb.raft.util.DisruptorMetricSet)1 NamedThreadFactory (io.dingodb.raft.util.NamedThreadFactory)1 RepeatedTimer (io.dingodb.raft.util.RepeatedTimer)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1