New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: support raft cluster #5226
Conversation
serializer/seata-serializer-kryo/src/main/java/io/seata/serializer/kryo/KryoSerializer.java
Outdated
Show resolved
Hide resolved
server/src/main/java/io/seata/server/session/GlobalSession.java
Outdated
Show resolved
Hide resolved
server/src/main/java/io/seata/server/session/GlobalSession.java
Outdated
Show resolved
Hide resolved
server/src/main/java/io/seata/server/session/GlobalSession.java
Outdated
Show resolved
Hide resolved
/** | ||
* The instance of DefaultCoordinator | ||
*/ | ||
private static final DefaultCoordinator COORDINATOR = DefaultCoordinator.getInstance(); | ||
|
||
private static final boolean DELAY_HANDLE_SESSION = StoreConfig.getSessionMode() != SessionMode.FILE; | ||
private static final String STORE_MODE = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -99,84 +96,133 @@ public static void init(SessionMode sessionMode) { | |||
if (null == sessionMode) { | |||
sessionMode = StoreConfig.getSessionMode(); | |||
} | |||
String group = CONFIG.getConfig(ConfigurationKeys.SERVER_RAFT_GROUP, DEFAULT_SEATA_GROUP); | |||
RaftServerFactory.getInstance().init(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo
if (ROOT_SESSION_MANAGER instanceof Reloadable) { | ||
((Reloadable) ROOT_SESSION_MANAGER).reload(); | ||
if (sessionMode == SessionMode.FILE) { | ||
((Reloadable)ROOT_SESSION_MANAGER).reload(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo
server/src/main/java/io/seata/server/session/SessionHolder.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Ⅰ. Describe what this PR did
完整源码解析: https://blog.funkye.icu/2023/01/05/seata-raft-2023/
raft学习资料:
https://raft.github.io/
http://thesecretlivesofdata.com/raft/
支持http(不再扩充私有协议涉及范围)下长轮询获取metadata,最大延迟为1s,当集群发生变动时实时响应被挂起的请求,client再进行拉取集群信息(参考zk的listener通知变动,值需要自己再去获取的方式), 并优化multi-raft逻辑
该参数为节点raft选举和通信端口设置,本机调试使用,按照netty端口+1000自动算出raft选举端口
完整的raft地址
-Dseata.server.raft.server-addr=192.168.31.181:9091::100,192.168.31.181:9092::10,192.168.31.181:9093::10
这个节点,其中9093为raft端口,10为选举时的权重,当然你也可以不写权重::中间的为预留值
或者通过配置文件指定集群
比如:
192.168.31.182:9091,192.168.31.181:9092,192.168.31.183:9093
1.x升级2.x采用raft集群模式(非存储模式)步骤
先将事务分组对应集群的group设置为defalut
先滚动升级2.x 如上配置几台seata集群的地址(继续保留第三方注册中心的配置registry.type=xxx),由于没有使用raft存储模式,该节点虽然会报选举相关的异常日志,但是还是可以对外服务,等都滚动完毕后,集群选举成功后异常日志自然会消失
再滚动升级client,将client上的注册中心改为seata,并将对应事务分组的grouplist配置上对应集群的4层lb,vip,或者直接是对应seata集群地址即可
spring-boot如下:
配置中心如下:
后续工作:
debug server侧时建议把 election-timeout-ms 配置长一些,否者debug会造成进程阻塞,其它节点会重选举,默认是1s,调试可以设置成60s之类的,超过1s没有发心跳,其余节点会开始选举,所以调试时需要改大,生产时最好默认,调太小网络抖动会造成重选举对业务请求会有影响,太大当真正出现宕机网络分区时,触发重选举的时间太久,业务也会有影响,上生产时需要注意这个参数调优,或者直接采用默认
单机测试以99.9%的事务成功率压测,随机扣200件商品的库存 五分钟或50000个请求
Failed requests的值为压测时回滚的事务数
db模式(非实时刷盘)+raft集群模式
调优参数参考某些云数据库方式,相当于1s一刷盘,减少事务信息和client的增删改对数据库的压力
具体修改如下
纯raft模式
redis+raft集群模式
纯空begin压测,3台tc 2c2g,tc之间延迟0.5ms左右,tm与tc之间延迟1ms左右,人工介入强行让测试时的leader都为同一台,确保压测结果准确性,进行20W次请求,50并发压测
jdk19 虚拟线程
ThreadPoolExecutor workingThreads = new ThreadPoolExecutor(NettyServerConfig.getMinServerPoolSize(), NettyServerConfig.getMaxServerPoolSize(), NettyServerConfig.getKeepAliveTime(), TimeUnit.SECONDS, new LinkedBlockingQueue<>(NettyServerConfig.getMaxTaskQueueSize()), Thread.ofVirtual().name("ServerHandlerThread").factory(), new ThreadPoolExecutor.CallerRunsPolicy());
jdk17
jdk8
Ⅱ. Does this pull request fix one issue?
Ⅲ. Why don't you add test cases (unit test/integration test)?
Ⅳ. Describe how to verify it
Ⅴ. Special notes for reviews