use of com.alipay.sofa.jraft.util.NamedThreadFactory in project sofa-jraft by sofastack.
the class AbstractChaosTest method chaosSplittingTest.
@Test
public void chaosSplittingTest() {
final List<PeerId> peerIds = TestUtil.generatePeers(INITIAL_PEER_COUNT);
final CliOptions opts = new CliOptions();
opts.setTimeoutMs(30000);
final RheaKVCliService cliService = RheaKVServiceFactory.createAndInitRheaKVCliService(opts);
final long regionId = Constants.DEFAULT_REGION_ID;
final long newRegionId = 2;
final String groupId = JRaftHelper.getJRaftGroupId(ChaosTestCluster.CLUSTER_NAME, regionId);
final Configuration conf = new Configuration(peerIds);
ChaosTestCluster cluster = null;
for (int l = 0; l < RETRIES; l++) {
final ExecutorService executor = Executors.newCachedThreadPool(new NamedThreadFactory("chaos-splitting-test", true));
final List<Future<?>> allFutures = new CopyOnWriteArrayList<>();
try {
cluster = new ChaosTestCluster(peerIds, getStorageType(), isAllowBatching(), isOnlyLeaderRead());
cluster.start();
final RheaKVStore store = cluster.getLeaderStore();
// for least keys on split
for (int j = 0; j < LOOP_2; j++) {
store.bPut(j + "_split_", VALUE);
}
for (int i = 0; i < LOOP_1; i++) {
final int index = i;
final Future<?> f = executor.submit(() -> {
for (int j = 0; j < LOOP_2; j++) {
store.bPut(index + "_split_test_" + j, VALUE);
}
});
allFutures.add(f);
}
final Status st = cliService.rangeSplit(regionId, newRegionId, groupId, conf);
if (!st.isOk()) {
System.err.println("Status:" + st);
throw new RuntimeException(st.toString());
}
// wait for all writes finished
for (final Future<?> f : allFutures) {
f.get(30, TimeUnit.SECONDS);
}
break;
} catch (final Exception e) {
System.err.println("Fail to put data, try again...");
e.printStackTrace();
for (final Future<?> f : allFutures) {
f.cancel(true);
}
if (cluster != null) {
cluster.stopAll();
}
cluster = null;
} finally {
ExecutorServiceHelper.shutdownAndAwaitTermination(executor);
}
}
if (cluster == null) {
throw new RuntimeException("fail to put data, can not check data");
}
try {
chaosSplittingCheckData(cluster);
} finally {
cluster.stopAll();
}
}
use of com.alipay.sofa.jraft.util.NamedThreadFactory in project sofa-jraft by sofastack.
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;
}
use of com.alipay.sofa.jraft.util.NamedThreadFactory in project sofa-jraft by sofastack.
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;
}
use of com.alipay.sofa.jraft.util.NamedThreadFactory in project sofa-jraft by sofastack.
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());
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 TimeoutBlockingWaitStrategy(this.raftOptions.getDisruptorPublishEventWaitTimeoutSecs(), //
TimeUnit.SECONDS)).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;
}
use of com.alipay.sofa.jraft.util.NamedThreadFactory in project sofa-jraft by sofastack.
the class AbstractClientService method initRpcClient.
protected boolean initRpcClient(final int rpcProcessorThreadPoolSize) {
final RaftRpcFactory factory = RpcFactoryHelper.rpcFactory();
this.rpcClient = factory.createRpcClient(factory.defaultJRaftClientConfigHelper(this.rpcOptions));
configRpcClient(this.rpcClient);
this.rpcClient.init(null);
this.rpcExecutor = //
ThreadPoolUtil.newBuilder().poolName(//
"JRaft-RPC-Processor").enableMetric(//
true).coreThreads(//
rpcProcessorThreadPoolSize / 3).maximumThreads(//
rpcProcessorThreadPoolSize).keepAliveSeconds(//
60L).workQueue(//
new ArrayBlockingQueue<>(10000)).threadFactory(//
new NamedThreadFactory("JRaft-RPC-Processor-", true)).build();
if (this.rpcOptions.getMetricRegistry() != null) {
this.rpcOptions.getMetricRegistry().register("raft-rpc-client-thread-pool", new ThreadPoolMetricSet(this.rpcExecutor));
Utils.registerClosureExecutorMetrics(this.rpcOptions.getMetricRegistry());
}
return true;
}
Aggregations