知其然,知其所以然
Elasticsearch 2026-10-02

Segment Merge 的触发条件

本机真实30次单文档写入+refresh,理论上应攒出30个segment,真实只剩3个。merge统计显示total=3次合并处理了39个文档,generation编号21/31/32真实跳跃巨大证明大量中间段被消灭。全程没有手动force_merge,印证TieredMergePolicy自动在每次refresh后评估并触发体积相近小segment的合并。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

force_merge 的风险

本机真实删一半文档(10万删5万),store.size真实一个字节没变还是20.3mb。force_merge到1个segment后store.size真实降到10.6mb,但合并后唯一segment的docs.deleted真实依然是50000不是0——查到soft_deletes.retention_lease.period默认12小时,证明force_merge不会立刻彻底清空保留期内的软删除记录,这是容易被忽视的真实风险。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

删除文档为什么不会立刻释放磁盘

本机真实删2.5万条文档,store.size真实不降反升(5.2mb→5.5mb),docs.deleted真实是实际删除数的2倍(soft_deletes记两笔账)。全部5万条删光后store.size继续涨到5.8mb。force_merge带only_expunge_deletes后docs.deleted减半但store.size分毫未动——soft_deletes.retention_lease默认12小时阻止彻底回收。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

refresh_interval 对写入性能的影响

本机真实对比2000条文档每次都refresh=true(21.167秒)和完全不refresh(10.087秒),慢了约2.1倍。根源是每次refresh都真实生成一个全新segment文件,频繁刷新把这笔固定开销拆成每条文档单独承担,而降低频率能把开销摊销到更多写入上,这正是refresh_interval调大能提升写入吞吐的真实原理。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

index.translog.durability

本机真实对比translog.durability=request(默认,每次等fsync落盘)写2000条耗时10.305秒,async(每5秒批量fsync)同样2000条只要0.529秒,快约19.5倍。request模式真实保证写入成功即落盘(第96篇kill -9实验正是在此模式下验证),async模式真实在崩溃窗口内可能丢失最近几秒数据,这是吞吐与数据安全边界的真实权衡。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

Update API 的读改写过程

本机真实脚本update(counter+=1)验证_version/_seq_no都递增,证明底层是读-改-写整篇重写而非原地修改。真实20个并发update默认retry_on_conflict=0时只有1个成功19个冲突失败;调到5后成功数涨到8个但仍有12个重试耗尽后失败——证明retry_on_conflict只能缓解不能消除高并发竞争失败。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

乐观并发控制与 seq_no

本机真实索引文档拿到_seq_no=0,带这个值写入真实成功,seq_no前进到1。用已经过期的seq_no=0再写,真实直接409报错,错误信息精确回显'required seqNo[0]...current has seqNo[1]'——证明乐观并发控制真实靠比较版本标识的compare-and-swap机制,而非加锁。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

if_seq_no 与 if_primary_term

本机真实只传if_seq_no不传if_primary_term,真实400报错两者必须成对出现;反过来只传if_primary_term同样400报错。真实又验证正确seq_no=0配瞎编的primary_term=99,依然409失败文档完全没被改动——证明两个值真实是各自独立被精确检查的复合条件,不存在seq_no对了就放行的宽松逻辑。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

版本冲突与重试

本机真实用20线程手工实现读-算-写CAS逻辑,不重试时真实只有1个成功19个放弃。加上遇冲突就重读重试(最多10次)的循环后,成功数真实涨到17个,但仍有3个尝试10次后真实放弃——证明客户端重试能大幅缓解但不能消除高并发版本冲突失败,跟第103篇update的retry_on_conflict现象一致。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

Bulk Thread Pool 与写入拒绝

本机真实发现write线程池queue_size不支持动态修改,报错'not dynamically updateable'需改配置重启。真实改成size=1/queue_size=2重启后,30个并发写入真实只有2个成功,28个429拒绝(es_rejected_execution_exception),错误信息精确嵌着线程池实时状态——这是写入过载时真实的保护机制,应降速或退避重试而非丢弃数据。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

Indexing Pressure

本机真实查到indexing_pressure内存上限107374182字节,精确等于1GB堆的10%。真实构造6个约29.4MB的大bulk并发请求,只有3个成功3个被拒绝,错误信息精确嵌着内存记账(93.3MB已占用+31.1MB新请求超过107MB上限)。这是按字节数限制的独立保护机制,跟上一篇按数量限制的线程池队列拒绝互补运作。

Elasticsearch 真实验证 动画演示
Elasticsearch 2026-10-02

大文档写入的内存风险

本机真实用150MB单条文档直接413被拒绝,撞上http.max_content_length默认100mb上限。50MB文档(低于上限)成功写入但耗时明显更长。真实测keyword字段值32766字节成功、32767字节(多1字节)整条写入直接失败——Lucene硬编码单个term最大32766字节,错误信息'all were skipped'容易误导,实际是整条请求失败而非静默截断。

Elasticsearch 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号