网站改版后的内容台州网站建设网站
2026/4/8 0:23:53 网站建设 项目流程
网站改版后的内容,台州网站建设网站,wordpress 中国服务器,有没有做请帖的网站6.2 Elasticsearch-写入链路#xff1a;Index → Refresh → Flush → Merge 源码走读 Elasticsearch 的写入链路是一条“先写内存、再写事务日志、后刷盘、最终合并”的四级流水线。 整条链路由 Index → Refresh → Flush → Merge 四个阶段组成#xff0c;对应内核代码里…6.2 Elasticsearch-写入链路Index → Refresh → Flush → Merge 源码走读Elasticsearch 的写入链路是一条“先写内存、再写事务日志、后刷盘、最终合并”的四级流水线。整条链路由Index → Refresh → Flush → Merge四个阶段组成对应内核代码里的四个关键服务IndexService、RefreshService、FlushService、MergeScheduler。下面以 8.11 分支源码为基准按时间顺序把一次文档写入的完整旅程跑一遍并给出可直接打断点的位置与核心字段含义。1. Index文档进门的第一站入口TransportBulkAction#doExecute→BulkRequestHandler#executeBulk关键类InternalEngine#index关键字段versionMap、localCheckpoint、maxSeqNo路由计算TransportBulkAction把 bulk 拆成 shard 级别的BulkShardRequest通过IndexRouting#resolve得到目标主分片。主分片写内存PrimaryShardOperation#doRun→InternalEngine#index拿到Index操作对象先加writeLock。版本号与序列号Index#resolveVersion用versionMap做乐观锁冲突检测SequenceNumbers#nextSeqNo原子递增生成seqNo。写 Lucene 的 DWPTIndexWriter#addDocument只是把文档追加到DocumentsWriterPerThread的pendingDocs队列此时数据不可见。写 translogTranslog#add把Index操作序列化后追加到translog.ckp文件返回locationlocation被塞进Engine.Index结果里用于回放。主分片返回ReplicationOperation把location随ReplicationRequest发到副本副本走同一条InternalEngine#index路径保证主副一致。断点org.elasticsearch.index.engine.InternalEngine:index第 952 行assert seqNo localCheckpoint.get();可观察seqNo、version、primaryTerm三值是否连续。2. Refresh把内存数据变为可查入口IndexService#refresh→RefreshService#refresh关键类ElasticsearchDirectoryReader、ReadersAndUpdates关键字段lastRefreshedCheckpoint、refreshedSeqNo触发条件定时默认 1s (index.refresh_interval)。强制调用_refreshAPI 或bulk带refreshtrue。打开新 readerInternalEngine#refresh调IndexWriter#getReader(true)拿到StandardDirectoryReader内部是SegmentCoreReaders列表。更新 checkpointlastRefreshedCheckpoint被原子更新为当前已写完的最大seqNo只有 ≤ checkpoint 的文档才对 Searcher 可见。发布新的 SearcherIndexShard#storeNewSearcher把DirectoryReader包装成ElasticsearchDirectoryReader注册到ShardSearchRegistry旧 reader 引用计数归零后自动关闭。断点org.elasticsearch.index.engine.InternalEngine:refresh第 1273 行lastRefreshedCheckpoint localCheckpointTracker.getProcessedCheckpoint();可验证可见延迟 localCheckpoint - lastRefreshedCheckpoint。3. Flush把 translog 刷盘并提交 commit入口FlushService#flush→InternalEngine#flush关键类TranslogWriter、IndexWriter关键字段flushSeqNo、committedTranslogGeneration触发条件translog 大小超过 512 MB (index.translog.flush_threshold_size)。定时 5 min 一次。重启前必须 flushIndicesClusterStateService#applyClusterState。写 Lucene commitIndexWriter#commit()生成新的segments_N文件把内存中所有已 refresh的段 fsync 到磁盘。截断 translogTranslog#current被关闭并重命名为generation.ckp新 translog 从空文件开始committedTranslogGeneration指针推进。更新 shard stateIndexShard#persistMetadata把commitSeqNo、commitPrimaryTerm写进shard-state.st文件供节点重启后恢复。断点org.elasticsearch.index.translog.Translog:closeIntoReader第 568 行logger.debug(flushing translog generation {}, generation);可确认 flush 后旧 translog 文件是否被清理。4. Merge后台段合并与物理删除入口MergeScheduler#merge→TieredMergePolicy#findMerges关键类ElasticsearchMergePolicy、MergeTask关键字段maxMergedSegmentBytes、deletesPctAllowed策略选择TieredMergePolicy把段按大小分层优先合并大小相近且删除率高的段maxMergedSegmentGB默认 5 GB防止写出过大段。合并流程IndexWriter#merge创建MergeSpecification每个OneMerge包含待合并的SegmentCommitInfo列表Lucene 把多个段读出 → 去删除 → 重新写成一个新段。更新版本映射ElasticsearchMergePolicy#keepFullyDeletedSegment返回 false保证完全删除的段在合并后直接物理丢弃versionMap中对应uid的version被清理防止版本泄露。并发控制合并线程与写入线程共享IndexWriter的writeLock但merge本身使用flushLock的读锁因此refresh 不会被 block搜索仍可进行。断点org.apache.lucene.index.TieredMergePolicy:findMerges第 214 行if (segBytes maxMergedSegmentBytes) continue;可观察哪些段被选入合并列表。5. 端到端时序图简化Client ──► TransportBulkAction │ ├─► Index (DWPT Translog) │ ├─► Refresh (1s 默认) ──► Searcher 可见 │ ├─► Flush (512 MB / 5 min) ──► Commit Translog 清理 │ └─► Merge (后台) ──► 物理删除 段数量收敛6. 调优提示与源码黑魔法refresh_interval -1把 refresh 关掉后lastRefreshedCheckpoint不再推进搜索 0 结果但写入吞吐可提升 30 %适合离线灌数据场景。translog durability async异步刷盘每 5 s 一次减少 fsync 次数但宕机可能丢 5 s 数据源码位置TranslogWriter#syncBeforeReturn第 417 行。merge scheduler 限流MAX_MERGE_COUNT默认 3MAX_THREAD_COUNT默认 1机械盘可调到 2×2源码位置ElasticsearchMergeScheduler构造器。sequence number 回滚主分片失败时新主通过Store#readLastCommittedSegmentsInfo读取commitSeqNo把localCheckpoint回退到 commit 点保证主副切换不丢数。7. 小结Index 阶段只保证durabilitytranslog不保证visibilityRefresh 阶段把内存段暴露给 Searcher是 ES 近实时搜索的精髓Flush 阶段把内存 translog一起固化是重启恢复的基石Merge 阶段把碎片段 删除文档持续整理决定长期查询性能。四段代码环环相扣却通过lock-free checkpoint与引用计数 reader做到几乎互不阻塞值得反复走读。推荐阅读PyCharm 2018–2024使用指南更多技术文章见公众号: 大城市小农民

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询