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
JDKOpenJDK 17.0.20.1
Maven3.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.typeGRPC网络
raft.datastream.typeDISABLED网络
raft.grpc.flow.control.window1MB (=1048576)网络
raft.grpc.message.size.max64MB (=67108864)网络
raft.grpc.server.async.request.thread.pool.size32线程池
raft.grpc.server.async.request.thread.pool.cachedtrue线程池
raft.grpc.server.heartbeat.channeltrue网络
raft.grpc.server.leader.outstanding.appends.max8网络
raft.grpc.server.stub.pool.size1线程池
raft.server.close.threshold60s生命周期
raft.server.leaderelection.leader.step-down.wait-time10s选举
raft.server.leaderelection.pre-votetrue选举
raft.server.leaderelection.member.majority-addfalse选举
raft.server.rpc.timeout.min150ms选举
raft.server.rpc.timeout.max300ms选举
raft.server.rpc.first-election.timeout.min150ms(fallback 到 rpc.timeout.min)选举
raft.server.rpc.first-election.timeout.max300ms(fallback 到 rpc.timeout.max)选举
raft.server.rpc.request.timeout3000msRPC
raft.server.rpc.sleep.time25msRPC
raft.server.rpc.slowness.timeout60sRPC
raft.server.log.segment.size.max32MB (=33554432)日志
raft.server.log.write.buffer.size8MB (=8388608)日志
raft.server.log.preallocated.size4MB (=4194304)日志
raft.server.log.force.sync.num128日志
raft.server.log.purge.gap1024日志
raft.server.log.purge.upto.snapshot.indexfalse日志
raft.server.log.purge.preservation.log.num0日志
raft.server.log.segment.cache.num.max6日志
raft.server.log.segment.cache.size.max200MB (=209715200)日志
raft.server.log.appender.install.snapshot.enabledtrue快照
raft.server.log.appender.snapshot.chunk.size.max16MB (=16777216)快照
raft.server.log.corruption.policyEXCEPTION日志
raft.server.log.read.lock.enabledtrue日志
raft.server.log.use.memoryfalse日志
raft.server.log.statemachine.data.caching.enabledfalse日志
raft.server.log.statemachine.data.synctrue日志
raft.server.log.statemachine.data.sync.timeout10s日志
raft.server.read.optionDEFAULT读取
raft.server.read.timeout10s读取
raft.server.read.leader.lease.enabledfalse读取
raft.server.read.leader.lease.timeout.ratio0.9读取
raft.server.retrycache.expirytime60s客户端
raft.server.retrycache.statistics.expirytime100ms客户端
raft.server.snapshot.auto.trigger.enabledfalse快照
raft.server.snapshot.retention.file.num-1快照
raft.server.staging.catchup.gap1000集群变更
raft.server.staging.timeout900ms(fallback)集群变更
raft.server.sleep.deviation.threshold300ms调度
raft.server.threadpool.client.size0线程池
raft.server.threadpool.client.cachedtrue线程池
raft.server.threadpool.server.size0线程池
raft.server.threadpool.server.cachedtrue线程池
raft.server.threadpool.proxy.size0线程池
raft.server.threadpool.proxy.cachedtrue线程池
raft.server.watch.timeout10s客户端

五、核心参数详解

5.1 服务标识与网络

节点身份不在参数键里,而在 RaftPeer 对象中,服务端口由 gRPC 键决定:

项配置方式说明
节点 IDRaftPeer.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 controlraft.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/max150ms / 300ms3.x 中选举超时直接取这对值(min 加随机抖动到 max),并非常见旧文档写的 3s/6s
raft.server.rpc.first-election.timeout.min/maxfallback 到上两项集群首次启动的选举窗口,可单独收窄加快首轮选举
raft.server.leaderelection.pre-votetruepre-vote 阶段先行探测,避免网络抖动直接抬升 term
raft.server.leaderelection.leader.step-down.wait-time10sleader 失联多数派后主动让位前等待时长
raft.server.leaderelection.member.majority-addfalse成员变更时新节点是否要求多数派确认

调整示例:

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.max32MB段文件上限;实测 segment 文件名形如 log_0-0、log_inprogress_1
raft.server.log.write.buffer.size8MB写日志的内存缓冲
raft.server.log.preallocated.size4MB预分配段文件大小,减少运行中扩容
raft.server.log.force.sync.num128每 N 条强刷一次盘,越大吞吐越高、崩溃窗口越大
raft.server.log.purge.gap1024leader 与 follower 的日志差距超过该值时走 install snapshot
raft.server.log.segment.cache.num.max / size.max6 / 200MB已关闭段的读缓存上限
raft.server.log.use.memoryfalsetrue 时日志放内存,仅限测试
raft.server.log.corruption.policyEXCEPTION段损坏即拒绝启动,生产保持默认

示例:

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.timeout3000ms单次 RPC 超时,弱网环境适当调大
raft.server.rpc.slowness.timeout60s判定对端慢节点的时间阈值
raft.server.threadpool.client.size / cached0 / true0 表示按需创建的 cached 池
raft.server.threadpool.server.size / cached0 / true同上,处理对端请求
raft.grpc.server.async.request.thread.pool.size / cached32 / truegRPC 异步请求池
raft.grpc.server.leader.outstanding.appends.max8leader 未确认的最大并发 append 数,流控关键项

5.5 读取与快照

参数键默认值说明
raft.server.read.optionDEFAULTDEFAULT 线性一致读;LINEARIZABLE 为显式线性读模式
raft.server.read.timeout10s读请求等待多数派心跳的超时
raft.server.read.leader.lease.enabledfalseleader 租约读,开启后读路径省一次确认
raft.server.snapshot.auto.trigger.enabledfalse快照自动触发默认关闭,大流量写入集群建议开启
raft.server.snapshot.auto.trigger.threshold按需设置与 setCreationGap(long) 配合,日志条数超阈值自动快照
raft.server.snapshot.retention.file.num-1保留的历史快照数,-1 表示不清理
raft.server.log.appender.snapshot.chunk.size.max16MBinstall snapshot 的分片大小

示例:

RaftServerConfigKeys.Snapshot.setAutoTriggerEnabled(props, true);
RaftServerConfigKeys.Snapshot.setCreationGap(props, 100000);
RaftServerConfigKeys.Snapshot.setRetentionFileNum(props, 3);

5.6 客户端与重试缓存

参数键默认值说明
raft.server.retrycache.expirytime60s去重缓存时长;重试请求在该窗口内命中缓存返回原结果
raft.server.retrycache.statistics.expirytime100ms缓存命中统计窗口
raft.server.watch.timeout10swatch 复制进度 API 的等待上限
raft.server.close.threshold60s关闭服务时等待收尾的上限

六、配置模板

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/2s150ms 选举窗口在 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 不清理,需显式设置保留个数。

八、参考链接