use of org.apache.ignite.raft.jraft.conf.ConfigurationManager 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;
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationManager in project ignite-3 by apache.
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 = opts.getNodeOptions() == null ? new NodeOptions() : opts.getNodeOptions();
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();
initPools(opts.getNodeOptions());
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;
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationManager in project ignite-3 by apache.
the class BaseLogStorageTest method setup.
@BeforeEach
public void setup() throws Exception {
this.confManager = new ConfigurationManager();
this.logEntryCodecFactory = LogEntryV1CodecFactory.getInstance();
this.logStorage = newLogStorage();
final LogStorageOptions opts = newLogStorageOptions();
this.logStorage.init(opts);
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationManager in project ignite-3 by apache.
the class LogManagerTest method setup.
@BeforeEach
public void setup() throws Exception {
this.confManager = new ConfigurationManager();
this.raftOptions = new RaftOptions();
this.logStorage = newLogStorage(raftOptions);
this.logManager = new LogManagerImpl();
final LogManagerOptions opts = new LogManagerOptions();
NodeOptions nodeOptions = new NodeOptions();
executor = JRaftUtils.createExecutor("test-executor", Utils.cpus());
nodeOptions.setCommonExecutor(executor);
Mockito.when(node.getOptions()).thenReturn(nodeOptions);
opts.setConfigurationManager(this.confManager);
opts.setLogEntryCodecFactory(LogEntryV1CodecFactory.getInstance());
opts.setFsmCaller(this.fsmCaller);
opts.setNode(node);
opts.setNodeMetrics(new NodeMetrics(false));
opts.setLogStorage(this.logStorage);
opts.setRaftOptions(raftOptions);
opts.setGroupId("TestSrv");
opts.setLogManagerDisruptor(disruptor = new StripedDisruptor<>("TestLogManagerDisruptor", 1024, () -> new LogManagerImpl.StableClosureEvent(), 1));
assertTrue(this.logManager.init(opts));
}
use of org.apache.ignite.raft.jraft.conf.ConfigurationManager in project ignite-3 by apache.
the class LogStorageBenchmark method main.
public static void main(final String[] args) {
String testPath = Paths.get(SystemPropertyUtil.get("user.dir"), "log_storage").toString();
System.out.println("Test log storage path: " + testPath);
int batchSize = 100;
int logSize = 16 * 1024;
int totalLogs = 30 * 1024;
LogStorage logStorage = new RocksDBLogStorage(testPath, new RaftOptions());
// LogStorage logStorage = new LocalLogStorage(testPath, new RaftOptions());
LogStorageOptions opts = new LogStorageOptions();
opts.setConfigurationManager(new ConfigurationManager());
opts.setLogEntryCodecFactory(LogEntryV1CodecFactory.getInstance());
logStorage.init(opts);
new LogStorageBenchmark(logStorage, logSize, totalLogs, batchSize).doTest();
}
Aggregations