Apache Ratis 配置参数详解
详解 Apache Ratis 3.3.1 的 RaftProperties 配置体系与 RaftServerConfigKeys、GrpcConfigKeys 核心参数:以启动日志实测的 50 余项默认值为准,覆盖选举、日志存储、网络线程池、读取快照与重试缓存,并给出演示与生产两套可落地的配置模板。
Apache RatisApache Ratis2026/10/12
Apache Ratis 配置参数详解
目标:讲清 Apache Ratis 3.3.1 的配置载体与核心参数。所有默认值均取自实测启动日志打印(Ratis 启动时会逐项输出),所有 setter 均经 javap 核对,配置示例可直接编译运行。
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| JDK | OpenJDK 17.0.20.1 |
| Maven | 3.6.3 |
| Ratis 版本 | 3.3.1(revision 379c90a00291252beffa81c6d10d47ac0d015dce) |
| 配置依据 | 实测启动日志 + javap 反编译核对 |
二、前置条件
- 已完成 Ratis 安装与示例运行(见安装指南与示例指南两篇)。
- 本地 ~/.m2 存在 ratis-server-api-3.3.1.jar 与 ratis-server-3.3.1.jar,可用 javap 核对参数键类。
- 参数键类的物理分布:RaftServerConfigKeys 在 ratis-server-api,GrpcConfigKeys 在 ratis-grpc,均为 com.typesafe 风格的 Properties 域。
三、参数查看与修改方式
3.1 配置载体与生命周期
Ratis 没有全局配置文件,一切配置通过 RaftProperties 对象在构建 RaftServer 与 RaftClient 前注入,生命周期与所配置的实例一致:
final RaftProperties props = new RaftProperties();
RaftServerConfigKeys.setStorageDir(props, Collections.singletonList(new File("/tmp/ratis/n0")));
GrpcConfigKeys.Server.setPort(props, 6000);
RaftServer server = RaftServer.newBuilder()
.setServerId(RaftPeerId.valueOf("n0"))
.setGroup(group)
.setProperties(props)
.setStateMachine(new SimpleStateMachine())
.build();
要点:
- RaftProperties 内部是强类型键值,setter 即唯一合法入口,非法值在 set 时即校验失败,而非启动中期。
- 每个节点实例独享一份 RaftProperties;多实例同进程部署(伪集群)时务必各建一份,storage dir 与端口必须互不相同。
- RaftClient 侧传空的 new RaftProperties() 即可,客户端重试等参数可单独定制。
3.2 通过启动日志核对默认值
Ratis 启动时把每个已读取参数的当前值打印到日志,格式为 键 = 值 (default) 或 (fallback)。这是核对环境真实生效值最可靠的手段:
raft.server.log.segment.size.max = 32MB (=33554432) (default)
raft.server.leaderelection.pre-vote = true (default)
打印级别 INFO,因此生产环境排查配置漂移时,直接 grep 启动日志即可,无需改动代码。
四、参数总览
下表为 3.3.1 实测启动日志中的核心默认值(全部为日志原样照抄):
| 参数键 | 默认值 | 归属分类 |
|---|---|---|
| raft.rpc.type | GRPC | 网络 |
| raft.datastream.type | DISABLED | 网络 |
| raft.grpc.flow.control.window | 1MB (=1048576) | 网络 |
| raft.grpc.message.size.max | 64MB (=67108864) | 网络 |
| raft.grpc.server.async.request.thread.pool.size | 32 | 线程池 |
| raft.grpc.server.async.request.thread.pool.cached | true | 线程池 |
| raft.grpc.server.heartbeat.channel | true | 网络 |
| raft.grpc.server.leader.outstanding.appends.max | 8 | 网络 |
| raft.grpc.server.stub.pool.size | 1 | 线程池 |
| raft.server.close.threshold | 60s | 生命周期 |
| raft.server.leaderelection.leader.step-down.wait-time | 10s | 选举 |
| raft.server.leaderelection.pre-vote | true | 选举 |
| raft.server.leaderelection.member.majority-add | false | 选举 |
| raft.server.rpc.timeout.min | 150ms | 选举 |
| raft.server.rpc.timeout.max | 300ms | 选举 |
| raft.server.rpc.first-election.timeout.min | 150ms(fallback 到 rpc.timeout.min) | 选举 |
| raft.server.rpc.first-election.timeout.max | 300ms(fallback 到 rpc.timeout.max) | 选举 |
| raft.server.rpc.request.timeout | 3000ms | RPC |
| raft.server.rpc.sleep.time | 25ms | RPC |
| raft.server.rpc.slowness.timeout | 60s | RPC |
| raft.server.log.segment.size.max | 32MB (=33554432) | 日志 |
| raft.server.log.write.buffer.size | 8MB (=8388608) | 日志 |
| raft.server.log.preallocated.size | 4MB (=4194304) | 日志 |
| raft.server.log.force.sync.num | 128 | 日志 |
| raft.server.log.purge.gap | 1024 | 日志 |
| raft.server.log.purge.upto.snapshot.index | false | 日志 |
| raft.server.log.purge.preservation.log.num | 0 | 日志 |
| raft.server.log.segment.cache.num.max | 6 | 日志 |
| raft.server.log.segment.cache.size.max | 200MB (=209715200) | 日志 |
| raft.server.log.appender.install.snapshot.enabled | true | 快照 |
| raft.server.log.appender.snapshot.chunk.size.max | 16MB (=16777216) | 快照 |
| raft.server.log.corruption.policy | EXCEPTION | 日志 |
| raft.server.log.read.lock.enabled | true | 日志 |
| raft.server.log.use.memory | false | 日志 |
| raft.server.log.statemachine.data.caching.enabled | false | 日志 |
| raft.server.log.statemachine.data.sync | true | 日志 |
| raft.server.log.statemachine.data.sync.timeout | 10s | 日志 |
| raft.server.read.option | DEFAULT | 读取 |
| raft.server.read.timeout | 10s | 读取 |
| raft.server.read.leader.lease.enabled | false | 读取 |
| raft.server.read.leader.lease.timeout.ratio | 0.9 | 读取 |
| raft.server.retrycache.expirytime | 60s | 客户端 |
| raft.server.retrycache.statistics.expirytime | 100ms | 客户端 |
| raft.server.snapshot.auto.trigger.enabled | false | 快照 |
| raft.server.snapshot.retention.file.num | -1 | 快照 |
| raft.server.staging.catchup.gap | 1000 | 集群变更 |
| raft.server.staging.timeout | 900ms(fallback) | 集群变更 |
| raft.server.sleep.deviation.threshold | 300ms | 调度 |
| raft.server.threadpool.client.size | 0 | 线程池 |
| raft.server.threadpool.client.cached | true | 线程池 |
| raft.server.threadpool.server.size | 0 | 线程池 |
| raft.server.threadpool.server.cached | true | 线程池 |
| raft.server.threadpool.proxy.size | 0 | 线程池 |
| raft.server.threadpool.proxy.cached | true | 线程池 |
| raft.server.watch.timeout | 10s | 客户端 |
五、核心参数详解
5.1 服务标识与网络
节点身份不在参数键里,而在 RaftPeer 对象中,服务端口由 gRPC 键决定:
| 项 | 配置方式 | 说明 |
|---|---|---|
| 节点 ID | RaftPeer.newBuilder().setId(RaftPeerId.valueOf("n0")) | 对应键 raft.server.id 语义 |
| 服务地址 | RaftPeer.newBuilder().setAddress("127.0.0.1:6000") | 对应键 raft.server.address 语义 |
| RPC 类型 | raft.rpc.type | 构建时 RpcType.GRPC,实测默认 GRPC |
| gRPC 端口 | GrpcConfigKeys.Server.setPort(props, 6000) | admin/client/data 端口未显式设置时与主端口复用 |
| flow control | raft.grpc.flow.control.window | 默认 1MB,跨机房高延迟链路可调大 |
| 单消息上限 | raft.grpc.message.size.max | 默认 64MB,大对象写入时按需放宽 |
示例(实测可编译运行):
final RaftPeer[] peers = new RaftPeer[]{
RaftPeer.newBuilder().setId(RaftPeerId.valueOf("n0")).setAddress("127.0.0.1:6000").build(),
RaftPeer.newBuilder().setId(RaftPeerId.valueOf("n1")).setAddress("127.0.0.1:6001").build(),
RaftPeer.newBuilder().setId(RaftPeerId.valueOf("n2")).setAddress("127.0.0.1:6002").build()
};
GrpcConfigKeys.Server.setPort(props, 6000);
5.2 选举
| 参数键 | 默认值 | 说明 |
|---|---|---|
| raft.server.rpc.timeout.min/max | 150ms / 300ms | 3.x 中选举超时直接取这对值(min 加随机抖动到 max),并非常见旧文档写的 3s/6s |
| raft.server.rpc.first-election.timeout.min/max | fallback 到上两项 | 集群首次启动的选举窗口,可单独收窄加快首轮选举 |
| raft.server.leaderelection.pre-vote | true | pre-vote 阶段先行探测,避免网络抖动直接抬升 term |
| raft.server.leaderelection.leader.step-down.wait-time | 10s | leader 失联多数派后主动让位前等待时长 |
| raft.server.leaderelection.member.majority-add | false | 成员变更时新节点是否要求多数派确认 |
调整示例:
RaftServerConfigKeys.Rpc.setTimeoutMin(props, TimeDuration.valueOf("1s"));
RaftServerConfigKeys.Rpc.setTimeoutMax(props, TimeDuration.valueOf("2s"));
RaftServerConfigKeys.LeaderElection.setPreVote(props, true);
5.3 日志与存储
| 参数键 | 默认值 | 说明 |
|---|---|---|
| raft.server.storage.dir | 无默认,必配 | RaftServerConfigKeys.setStorageDir 传入 List,多盘可给多个目录 |
| raft.server.log.segment.size.max | 32MB | 段文件上限;实测 segment 文件名形如 log_0-0、log_inprogress_1 |
| raft.server.log.write.buffer.size | 8MB | 写日志的内存缓冲 |
| raft.server.log.preallocated.size | 4MB | 预分配段文件大小,减少运行中扩容 |
| raft.server.log.force.sync.num | 128 | 每 N 条强刷一次盘,越大吞吐越高、崩溃窗口越大 |
| raft.server.log.purge.gap | 1024 | leader 与 follower 的日志差距超过该值时走 install snapshot |
| raft.server.log.segment.cache.num.max / size.max | 6 / 200MB | 已关闭段的读缓存上限 |
| raft.server.log.use.memory | false | true 时日志放内存,仅限测试 |
| raft.server.log.corruption.policy | EXCEPTION | 段损坏即拒绝启动,生产保持默认 |
示例:
RaftServerConfigKeys.setStorageDir(props, Collections.singletonList(new File("/data/ratis/n0")));
RaftServerConfigKeys.Log.setSegmentSizeMax(props, SizeInBytes.valueOf("32MB"));
RaftServerConfigKeys.Log.setPreallocatedSize(props, SizeInBytes.valueOf("4MB"));
RaftServerConfigKeys.Log.setPurgeGap(props, 1024);
5.4 RPC 与线程池
| 参数键 | 默认值 | 说明 |
|---|---|---|
| raft.server.rpc.request.timeout | 3000ms | 单次 RPC 超时,弱网环境适当调大 |
| raft.server.rpc.slowness.timeout | 60s | 判定对端慢节点的时间阈值 |
| raft.server.threadpool.client.size / cached | 0 / true | 0 表示按需创建的 cached 池 |
| raft.server.threadpool.server.size / cached | 0 / true | 同上,处理对端请求 |
| raft.grpc.server.async.request.thread.pool.size / cached | 32 / true | gRPC 异步请求池 |
| raft.grpc.server.leader.outstanding.appends.max | 8 | leader 未确认的最大并发 append 数,流控关键项 |
5.5 读取与快照
| 参数键 | 默认值 | 说明 |
|---|---|---|
| raft.server.read.option | DEFAULT | DEFAULT 线性一致读;LINEARIZABLE 为显式线性读模式 |
| raft.server.read.timeout | 10s | 读请求等待多数派心跳的超时 |
| raft.server.read.leader.lease.enabled | false | leader 租约读,开启后读路径省一次确认 |
| raft.server.snapshot.auto.trigger.enabled | false | 快照自动触发默认关闭,大流量写入集群建议开启 |
| raft.server.snapshot.auto.trigger.threshold | 按需设置 | 与 setCreationGap(long) 配合,日志条数超阈值自动快照 |
| raft.server.snapshot.retention.file.num | -1 | 保留的历史快照数,-1 表示不清理 |
| raft.server.log.appender.snapshot.chunk.size.max | 16MB | install snapshot 的分片大小 |
示例:
RaftServerConfigKeys.Snapshot.setAutoTriggerEnabled(props, true);
RaftServerConfigKeys.Snapshot.setCreationGap(props, 100000);
RaftServerConfigKeys.Snapshot.setRetentionFileNum(props, 3);
5.6 客户端与重试缓存
| 参数键 | 默认值 | 说明 |
|---|---|---|
| raft.server.retrycache.expirytime | 60s | 去重缓存时长;重试请求在该窗口内命中缓存返回原结果 |
| raft.server.retrycache.statistics.expirytime | 100ms | 缓存命中统计窗口 |
| raft.server.watch.timeout | 10s | watch 复制进度 API 的等待上限 |
| raft.server.close.threshold | 60s | 关闭服务时等待收尾的上限 |
六、配置模板
6.1 演示环境模板(实测所用最小配置)
final RaftProperties props = new RaftProperties();
// 存储目录与端口按实例区分
RaftServerConfigKeys.setStorageDir(props, Collections.singletonList(new File("/tmp/ratis/n0")));
GrpcConfigKeys.Server.setPort(props, 6000);
// 其余全部使用默认值
配套启动参数 MAVEN_OPTS="-Xms256m -Xmx512m"(独立进程用 java -Xms256m -Xmx512m),实测 3 副本 + 写读演练全程稳定。
6.2 生产环境建议值
| 场景 | 建议调整 | 理由 |
|---|---|---|
| 跨机房部署 | rpc.timeout.min/max 调至 1s/2s | 150ms 选举窗口在 20ms 级 RTT 下过于激进,易误切主 |
| 高吞吐写入 | segment.size.max 调至 64MB-256MB、force.sync.num 适度增大 | 减少段切换与刷盘次数 |
| 长期运行 | snapshot.auto.trigger.enabled 开启并设 creation.gap | 防止日志无限增长 |
| 大快照 | appender.snapshot.chunk.size.max 调至 32MB-64MB | 加快落后节点追赶 |
| 弱网读 | read.option 保持 DEFAULT,read.timeout 调至 15s-30s | 在一致性与可用性间取平衡 |
七、常见问题
- 改了参数但未生效:确认改的是传入 RaftServer.newBuilder 的那份对象;多实例伪集群最易改错实例。
- 想确认线上默认值:grep 启动日志的 (default) 行,比查文档更可信,版本差异一目了然。
- storage.dir 未配置即启动失败:该键无默认值,属必配项。
- 首轮选举慢:默认 first-election 窗口 150-300ms 本已很小,若被其他任务抢占 CPU,优先排查负载而非加大窗口。
- 快照后日志未清理:retention.file.num 默认 -1 不清理,需显式设置保留个数。
八、参考链接
- 源码配置键定义:https://github.com/apache/ratis/blob/ratis-3.3.1/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
- gRPC 键定义:https://github.com/apache/ratis/blob/ratis-3.3.1/ratis-grpc/src/main/java/org/apache/ratis/grpc/GrpcConfigKeys.java
- 官网配置文档:https://ratis.apache.org/documentation/
- 关联文档:《Apache Ratis 安装指南》《Apache Ratis 常用工具与 API 详解》
章节目录