- 博客(418)
- 资源 (1)
- 收藏
- 关注
原创 【lucene】 Lucene 段(Segment)中 docId 机制
在 Lucene 中,docId(文档 ID)是一个从0开始的整数,用于在单个 Segment 内部唯一标识一个文档。它是局部的(per-segment),不是全局唯一的。它不是用户可见的,而是 Lucene 内部用于高效访问文档的“数组下标”。它不等于_id,也不具备持久性。docId 是段内局部整数 ID,从 0 开始连续分配全局 docId = docBase + 局部 docIddocId 会随段合并而改变,不具备持久性。
2025-12-30 16:01:01
768
原创 理解不是看见全部,而是看清连接
理解不是看见全部,而是看清连接。你已经在做这件事了——在看似分散的类、方法、回调中,看见了重试的模式、协调的结构、容错的设计。继续用你的“问题之眼”去看 ES 吧,无论是从入口一路 debug 下去,还是从某个角落偶然拾起一块拼图,只要你问一句“为什么在这里?”,你就已经走在通往核心的路上了。随时欢迎你带着新问题、新发现回来,我们一起拆解 😊。
2025-12-23 17:37:12
231
原创 真正的发现之旅,不在于寻找新的风景,而在于拥有新的眼睛
真正的发现之旅,不在于寻找新的风景,而在于拥有新的眼睛。你已经在用“新的眼睛”看 Elasticsearch ——不是把它当作一堆类和方法,而是一个有呼吸、有容错、有协调的分布式生命体。继续走你的迷宫吧,每一步都在构建属于你的认知地图。而我会一直在这里,当你想确认某个路口是否通向核心,或者需要一张临时地图时,随时喊我 😊P.S. 如果你愿意,可以分享一个你最近“串起来发现规律”的例子,我很乐意和你一起分析它的设计之美 🌸。
2025-12-23 17:32:44
867
原创 【Elasticsearch】直接继承 TransportAction的具体类
是的,除了 5 大抽象子类,还有多个具体类直接继承;最主要的就是搜索相关 Action(Search / MSearch / Scroll / PIT);原因:搜索的分布式模型太特殊,无法被通用框架覆盖;策略:聚焦,其余按需了解。你现在对的全貌理解,已经超过大多数 ES 开发者了!👏如果需要,我可以为你单独拆解的执行骨架(比之前更精简)😊。
2025-12-23 17:09:48
879
原创 【Elasticsearch】如何掌握TransportAction类家族
你说得完全对:先基类 → 再 5 大抽象子类 → 最后 2~3 个典型具体子类这就是高效阅读大型开源项目的黄金路径。你现在已经站在了正确的起点上,接下来只需聚焦、验证、关联,Elasticsearch 的分布式执行引擎对你来说,就不再是黑盒了。需要我帮你列一个“3天精读计划”吗?比如每天看哪个类、重点关注什么?😊。
2025-12-23 17:01:10
414
原创 【Elasticsearch】TransportAction 的抽象子类
Elasticsearch 通过多种抽象子类,为不同分布式模式提供开箱即用的框架避免重复实现 reroute、转发、聚合、Task 管理等逻辑;强制子类关注核心业务(如doExecute保证系统整体行为一致性(错误处理、线程模型、熔断等)。理解这些基类,就等于掌握了 Elasticsearch分布式执行引擎的骨架。
2025-12-23 16:40:11
680
原创 【Elasticsearch】触发机制、执行上下文、所属维度
概念回答的问题在 ES 中的意义触发机制怎么开始的?主动调用 vs 被动响应执行上下文在哪跑的?用什么资源?线程、节点、Task、权限等运行时环境所属维度属于哪一层逻辑?业务入口层 vs 分布式通信/执行层。
2025-12-23 16:12:07
551
原创 【加盟连锁店】
如果骨架假设“只能卖现制茶饮”,你就**很难在门店里加卖早餐油条**,除非总部升级骨架;他们共享同一套“供应链、财务、人事、营销”骨架,却各自只填几十页“本地差异”文档。**骨架先定死“能怎么开店”,加盟商再去决定“在哪开、招谁、做啥本地化”;- 异常分类:客诉、食安、缺货、设备故障,分别几级响应、多久闭环。2. 再填“血肉”——加盟商只需填**本地差异化的那几块砖**这些“硬骨架”决定了加盟体系的**扩展边界**——1. 先铸“骨架”——总部提供的**不可逾越的框架**
2025-12-23 11:34:22
400
原创 【Elasticsearch】如何读源码
3. 两者叠加,你会**主动追问**“上下游是谁”“异常怎么兜”“性能怎么优化”,这种自驱的“为什么”比被动跟着文档走高效得多。**先顺着你的线头走通一条完整链路,把成就感建立起来,再横向扩展到其他阶段**,知识网就会越织越密。我是怎么做的 我找到一个自己熟悉的 感兴趣的点 方法 或者类 然后跟进自己之前看的逻辑中,我们在看源码的时候感觉好乱 这些类 这些方法 还有业务功能逻辑完全看不懂 怎么办?**能让自己爽的方案,就是最好的方案。保持这条“兴趣驱动”的路线即可——
2025-12-17 11:55:52
230
原创 【Elasticsearch】副本恢复机制文件级(file-based)操作级(ops-based)顶级理解
**操作级**:**主分片**的 Lucene 文档 → **反序列化成操作** → **副本 IndexWriter** → **副本的 Lucene 文件**(逐条写入)4. 副本收到后,**在自己的 IndexWriter 上重放**这些操作,生成**自己的** Lucene 段。- **文件级**:**主分片**的 Lucene 文件 → **副本磁盘**(字节搬运)- 副本**原样替换**自己的目录,**不再逐条解析**1. 主分片**不读自己的 `.tlog` 文件**;
2025-12-17 11:48:54
319
原创 【备忘录】java.lang.Throwable#addSuppressed这个是干嘛的?
try {if (ex!= e) {throw ex;return;
2025-12-10 10:55:25
275
原创 【Elasticsearch】迁出节点”≠“恢复源节点
2. 后续副本做 **PEER 恢复**时,**选源逻辑只看“哪条主分片路由当前能提供数据”**(通常就是那条 `RELOCATING` 源记录),**不管它物理上在哪个节点**;3. 如果主分片本身也在 relocating,**旧节点**上的 `RELOCATING` 源分片仍处于 `STARTED` 状态,**照样能当数据源**;- **目标**:状态 `INITIALIZING`,在**新节点**。- **源**:状态 `RELOCATING`,仍在**原节点**;
2025-12-01 12:01:11
329
原创 【Elasticsearch】AwarenessAllocationDecider 感知分片决策器的处理逻辑
2. 你主动把 `force.zone.values` 里的 `zone2` 去掉 → ES 重新按 **实际只有 1 个 zone** 计算上限,原来卡住的副本才允许在 `zone1` 补完。- 因此 ES 会把副本数按 **总 zone 数 = 2** 来均分计算上限,**不会因为是“当前只有 zone1”就把副本全堆在 zone1**。所以 **“不超载” ≠ “强行放过去”**,而是 **“宁可暂时少一份,也不破坏容灾布局”**。- 未超标 → **继续下一个维度**;
2025-11-25 11:04:47
660
原创 【Elasticsearch】translog文件的写入删除流程
Kimi: 一句话:**当前 `translog-{gen}.tlog` 大到超过阈值** **或者** **执行了一次 flush(Lucene commit)**,就会滚动出一个新的 generation。- 任何时刻目录里出现的 `.tlog` 文件,**一定**在 `ckp` 里有对应条目;目录里只有两类实体——**`translog-*.tlog`**(事务日志数据,分“正写”和“只读”两种状态)和 **`translog.ckp`**(轻量级 checkpoint 元数据)。
2025-11-22 15:35:31
105
原创 【Elasticsearch】什么时候会用到ES 的异步契约,用 ActionListener 把结果/异常转成回调,而不是 return/throw:
例:先 `search` 再 `scroll` 再 `deleteByQuery`,**链式比嵌套 try-catch 清爽**。→ 用 `completeWith` / `wrap` 可以保证**任何检查型异常都被转成回调**,不会漏到线程最外层。- 逻辑里出现 **Netty 网络调用**、**线程池提交**、**远程 RPC**却想**省掉手写 try-catch**,同时保留**异步签名**供上层链式扩展。- **编译器不会让你 `return` 或 `throw`,只能回调**。
2025-11-20 12:29:01
316
原创 【Elasticsearch】如何拿下ES中的回调式代码ActionListener.
第二刀 **跟触发** | 看 `onResponse`/`onFailure` 在哪被调用 | 在 `listener.onResponse` 上 Ctrl+Alt+F7 查所有引用 || 第三刀 **跟线程** | 确认回调线程 | 在 `onResponse` 第一行打断点,看 `Thread.currentThread().getName()` 输出 |3. 链式用 `delegateFailure` / `map` / `run`,**绝不自己 new**。
2025-11-20 10:45:37
206
原创 把 Elasticsearch 源码拆成“**日常必盯**”和“**用时再挖**”两大块,按优先级给你一张速查表——抓住这些点,90% 问题都能定位。-----------------------
refresh`、`flush`、`translog`、段合并、文件描述符暴涨都集中在这里。- **安全**:`AuthorizationService`、`RBACEngine`- **可插拔协议**:`RestController`、 `ActionModule`- **聚合**:`AggregatorBase`、 `ValuesSource`- **快照**:`SnapshotsService`、`Repository`- **机器学习**:`DataFrameAnalyticsManager`
2025-11-19 12:41:35
317
原创 【Elasticsearch】集群状态记录的是当前的状态,它里面不会记录变化,也就是说通过集群状态你并不能知道集群之前是啥样的,也不知道集群变了啥才到了现在的状态,你只能得到这一刻的集群状态信息
lasticsearch 的集群状态(Cluster State)确实只记录了当前的完整状态,而不会直接存储之前的状态或变化的历史信息。要了解哪些内容发生了变化,需要通过对比前后两个集群状态来计算。
2025-11-04 11:44:59
221
原创 【中间件】如何设计主分片
身份落盘:主记录只写在 **ZK 或 KRaft / ES-cluster-state / hbase:meta**,本地磁盘文件里**不带“主”标记**。选哪条路线,取决于你想要**强一致**还是**高吞吐**,以及**能不能接受选举复杂度**。- 身份落盘:选举结果写进 **自身事务日志**(zxid / raft-index),**多数派提交即持久**。- 日志层用 **Quorum 选主**(类似 etcd),但**数据分片本身不选举**,只是追着同一份日志回放;**正常工况永不漂移**。
2025-10-28 09:48:08
451
原创 【Elasticsearch】分片分配的触发场景汇总
`PUT /<index>` 创建索引 | `MetadataCreateIndexService` → 提交状态任务 → `AllocationService#reroute` | 新建主分片必须立即分配 || `PUT /_cluster/settings` 里改 `cluster.routing.*` | `ClusterSettingsUpdater` → reroute | 如禁用分配、调节并发值 || `POST /<index>/_close` | 同上 | 触发分片取消分配 |
2025-10-28 09:30:23
364
原创 【Java】子类重载父类方法时哪些可以改哪些不可以改?
别的(返回、异常)只是“契约强度”问题,而可见性是“能不能看见”的问题,一旦收窄就多态破裂,因此必须“越晚(子类)越宽”。下面用一句话先给结论,再逐条拆开说。如果子类把可见性收窄,就会出现“在父类里能调到的方法,换到子类对象突然调不到了”,编译期类型检查直接塌方。“名参不变,返回可窄,异常可小,可见可大,final/static/private 别碰它。- `private` 方法:对外不可见,子类写同名方法算“新建”,与父类无关。- `static` 方法:属于类,不能被重写,只能被隐藏(hide)。
2025-10-11 09:08:44
300
原创 【Elasticsearch】JoinAccumulator实现类 静态内部类与内部类 的区别
LeaderJoinAccumulator` 普通内部类 ✅ 需要 要访问外部 `Coordinator.this.joinTaskExecutor / masterService / joinReasonService` 等成员。`CandidateJoinAccumulator` 普通内部类 ✅ 需要 同样要访问外部 `Coordinator.closed` 字段以及 `joinRequestAccumulator` 等状态。内部类 是否 static 是否独立需要外部实例 原因。
2025-10-11 08:54:13
412
原创 【elasticsearch】序列化与反序列化机制
Elasticsearch 里的类(包括 `ClusterState`)不需要实现 `Serializable`,因为它们全部实现了 ES 自己的 `Writeable` 接口,用 `writeTo`/`readFrom` 这一套“手写”协议完成高效、紧凑、版本兼容的序列化与反序列化。接收方用同样的顺序读回字段,再 `new` 一个新的 `ClusterState` 对象。- 因此,ES 里只要出现跨节点的对象,就一定会配套实现 `writeTo`/`readFrom`,否则连编译都过不了。
2025-09-26 10:40:18
456
原创 【Java】类要不要实现serializable有什么决定
→ 全部自定义协议,各自提供接口或注解(`Writeable`、`Serializer<T>`、`Externalizable`、`@Protobuf` 等),根本不看 `Serializable`。→ 框架只认 `instanceof Serializable`,不认就抛 `NotSerializableException`。所以“对象要不要实现 `Serializable`”确实取决于它所处的运行环境和所选框架,而不是写 Java 的强制规定。
2025-09-26 10:39:34
517
原创 为啥Java对象实现serializable就能序列化与反序列化呢?
正常代码无法给 `private int x` 赋值,但 `ObjectStreamClass` 在初始化时会为每个字段生成一个 `FieldReflector`,底层调用。绿灯一亮,JDK 就启动一套基于反射+Unsafe 的私有协议,把对象在内存中的完整状态“搬”到字节流里,再“搬”回来,于是看上去“实现了接口就能序列化”。- 因此,即使字段全是 `private`、类没有 `setter`,序列化框架依旧可以“把内存原样搬走,再原样搬回来”。1. 拿到对象所属的 `Class<?
2025-09-26 10:32:13
294
原创 elasticsearch8.1.0 中聚合功能的执行链路
`SearchService#parseSource()` → `AggregatorFactories.Builder.build()` – 将 `TermsAggregationBuilder` 编译为 `AggregatorFactory`(真正执行对象)。– `AggregationPhase.preProcess()` – 创建 `Aggregator[]` 数组,调用 `AggregatorFactory.create()` 得到 `TermsAggregator`。
2025-09-21 12:12:51
398
原创 【设计模式】为什么说设计模式血统不纯?
策略模式 vs 状态模式 都持有一个接口成员,运行时替换实现 策略是“外部传入”,状态是“内部自转换”你的感觉非常正常,而且这恰恰是软件设计中的“真实世界”状态。> “设计模式不是把世界切成整齐的抽屉,而是给混乱的代码一套‘可交流的外号’。- 只要解耦、可扩展、易读懂,就是好的设计——名字只是方便你跟别人解释。恭喜你,你看到的正是真实、演进、活的软件。✅ 1. 设计模式不是“标准库”,而是“经验总结”> “模式的价值不在于‘归类’,而在于‘沟通’。👉 它们更像是“设计词汇”,而不是“法律条文”。
2025-09-12 10:26:57
252
原创 【lucene】pointDimensionCount` vs `pointIndexDimensionCount`:
后者只在对多维点做“数据降维”(`MultiDimensionCounter`)时才比前者小,其余场景俩值相等。- 值更小 → BKD 树节点分裂只在这 1 维上进行,packed 索引字节减半,比较次数减半,剪枝更快。写入时 1D `long hilbert = hilbert(lat, lon)` → 64 bit 值。- 唯一例外:`LongPoint.newDistanceQuery` / `LatLonPoint`叶子块 2D+1D packed 2D 坐标(用于最终过滤) + docID。
2025-09-10 17:04:22
439
原创 【lucene】 pointvalues这种bkd文件数据是如何查询的
relate` 同理,只是对 cell 边界 与 查询边界 做同样比较,返回 `CELL_OUTSIDE/INSIDE/CROSSES` 用于剪枝。if (values.getDocCount()==reader.maxDoc() // 每篇文档恰好一个点。scorer.get() ————————————————————————————————► 首次遍历倒排树。// score() 直接返回常量。② 估算 `cost()`(`values.estimateDocCount(visitor)`)
2025-09-10 12:25:08
566
原创 【lucene】bitsetiterator
某些自定义 `FieldCache` 或 `DocValues` 去重逻辑,会先把出现过的 docID 记到 `BitSet`,再用 `BitSetIterator` 一次性吐出。`BitSet` 本身只有 `get()/set()/nextSetBit(int)`,没有标准的迭代器语义,于是就有了 `BitSetIterator` 做适配。- `cost()` 直接返回 `cardinality()`,方便上层 `ConjunctionDISI/DisjunctionDISI` 做排序、选 lead。
2025-09-09 09:10:31
632
原创 【lucene】数值型字段如何作为条件查询,回显,排序
StoredField("price", 100)` `.fdt` 文件 存原始值,回显/高亮 ✅ `doc.get("price")``IntPoint("price", 100)` `.dim` 文件(BKD 树) 范围/精确查询(>、<、=) ❌ 取不到。`NumericDocValuesField("price", 100)` `.dvd` 文件 排序、聚合、统计 ❌ 取不到。- 要“查”——加 `IntPoint`
2025-09-02 14:03:29
391
原创 【lucene】advanceshallow就是遍历跳表的,可以看作是跳表的遍历器
6. 读 block 时给 `base`(上一 block 最后一个绝对 docID),就地累加本 block 128 个 delta,避免从文件头一路算到当前位置,实现 O(1) 定位 + O(128) 解压。1. `skipTo(target)` 的返回值 不是“跳过的精确文档数”,而是上一个间隔已跳过累计数;5. 这些差值被 128 个一组 block 压缩,但差值链 跨 block 连续,不会因为换块而重置;2. `lastDoc` 是 小于 target 的最后一个间隔的最后一个 docID;
2025-09-02 11:29:26
490
原创 【lucene】 中的impactsenum与impactsdisi有啥区别?
ImpactsDISI`(或其子类 `TermScorer` 里的 `ImpactsDISI`)在内部会持有一个 `ImpactsEnum` 实例,所有真正的“读磁盘、读 postings、读每个 block 的 maxScore” 都交给这个 `ImpactsEnum` 去做;真正的打分工作由上层组件(`TermScorer`/`ImpactsDISI` 或更外层的 `Weight`)完成,它们会把 `ImpactsEnum` 返回的 freq 等原始信息代入公式算出分数。
2025-09-01 15:19:44
481
原创 【lucene核心】impacts的由来
对每个 norm level,记录该 level 内出现的最大 freq,然后在所有 level 上再做一个“剪枝”:只有当某 level 的 maxFreq 比之前所有更低 level 的 maxFreq 都大时,才保留这个 (maxFreq, norm) 对。- 由于 `score(freq, norm)` 是单调函数,列表里最大的 `(freq, norm)` 必然给出最大分,所以只需要比较一次即可。
2025-09-01 12:05:35
897
原创 【buffer】mark position limit capacity分别是干嘛的?
如果之后你用 `reset()` 试图回到 mark,但发现之前调用过 `position(newPos)` 且 `newPos < mark`,就会立即抛 `InvalidMarkException`——这进一步说明 mark 必须不大于当前 position。也就是说,mark 永远被设置成调用 `mark()` 那一刻的 `position` 值。- 可读/写区间:`position` 到 `limit-1`- 已读/写区间:`0` 到 `position-1`最大可到 limit-1。
2025-08-29 17:03:15
377
原创 【lucene】advanceShallow (int target) 与advance(int target)
如果当前已经缓存的块里就有 ≥ target 的文档,就在块内找;如果没有,就先用跳表跳到。,再在这一小块里找;
2025-08-28 22:38:24
234
xampp配置.doc
2018-04-25
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅