真实对比translog.durability设成request(默认,每次写入都等fsync落盘)与async(每5秒批量fsync)两种模式,验证约19.5倍的真实吞吐差距,并厘清这份速度提升背后对应的真实数据安全边界权衡。
代码PUT /td_request {"settings":{"translog.durability":"request"}} # 真实默认模式 PUT /td_async {"settings":{"translog.durability":"async","translog.sync_interval":"5s"}} 真实各自循环写入2000条独立文档: POST /td_request/_doc {"n":i} POST /td_async/_doc {"n":i}
durability=request(每次写入都等translog fsync落盘): elapsed_sec=10.305 durability=async(每5秒批量fsync一次,不等单次请求): elapsed_sec=0.529 ← 真实快了约19.5倍
这组真实耗时差距直接量化了fsync这个系统调用本身的代价:request模式真实要求每一次写入请求,在真正返回"写入成功"给客户端之前,都必须先确认这条操作已经被真实fsync进了磁盘上的translog文件——fsync真实是一个相对昂贵的系统调用,它要求操作系统真实把数据从内核缓冲区强制刷到物理存储介质,不只是写进缓存就算完事。本次实测2000次独立写入、每次都真实等这个fsync完成,累计耗时真实高达10秒;而async模式真实完全不等这个确认,写入请求真实在数据进了内存缓冲区之后就立刻返回,真正的fsync真实被攒到每5秒才批量做一次,这也是为什么它的吞吐真实能快出接近20倍。
代码真实设想一个进程在写入过程中突然崩溃(比如本系列第96篇真实做过的kill -9实验)的场景
request模式: 收到"写入成功"响应的那一刻,真实意味着这条数据已经被fsync进了磁盘 → 本系列第96篇验证过的kill -9崩溃恢复实验,真实就是在这种保证下做到了数据一条不丢 async模式: 写入请求收到"成功"响应,真实不代表数据已经落盘,可能还停留在操作系统的页缓存里 → 如果真实在等待下一次5秒周期fsync之前发生进程崩溃或者机器掉电 → 真实这个5秒窗口内已经返回"写入成功"的那些数据可能会丢失
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
index.translog.durability 与 sync_interval 设置