自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(404)
  • 资源 (1)
  • 收藏
  • 关注

原创 【Elasticsearch】translog文件的写入删除流程

Kimi: 一句话:**当前 `translog-{gen}.tlog` 大到超过阈值** **或者** **执行了一次 flush(Lucene commit)**,就会滚动出一个新的 generation。- 任何时刻目录里出现的 `.tlog` 文件,**一定**在 `ckp` 里有对应条目;目录里只有两类实体——**`translog-*.tlog`**(事务日志数据,分“正写”和“只读”两种状态)和 **`translog.ckp`**(轻量级 checkpoint 元数据)。

2025-11-22 15:35:31 53

原创 【Elasticsearch】什么时候会用到ES 的异步契约,用 ActionListener 把结果/异常转成回调,而不是 return/throw:

例:先 `search` 再 `scroll` 再 `deleteByQuery`,**链式比嵌套 try-catch 清爽**。→ 用 `completeWith` / `wrap` 可以保证**任何检查型异常都被转成回调**,不会漏到线程最外层。- 逻辑里出现 **Netty 网络调用**、**线程池提交**、**远程 RPC**却想**省掉手写 try-catch**,同时保留**异步签名**供上层链式扩展。- **编译器不会让你 `return` 或 `throw`,只能回调**。

2025-11-20 12:29:01 290

原创 【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 188

原创 把 Elasticsearch 源码拆成“**日常必盯**”和“**用时再挖**”两大块,按优先级给你一张速查表——抓住这些点,90% 问题都能定位。-----------------------

refresh`、`flush`、`translog`、段合并、文件描述符暴涨都集中在这里。- **安全**:`AuthorizationService`、`RBACEngine`- **可插拔协议**:`RestController`、 `ActionModule`- **聚合**:`AggregatorBase`、 `ValuesSource`- **快照**:`SnapshotsService`、`Repository`- **机器学习**:`DataFrameAnalyticsManager`

2025-11-19 12:41:35 297

原创 【Elasticsearch】里面的关键类

持续更新中。。。

2025-11-12 10:58:43 104

原创 【Elasticsearch】集群状态记录的是当前的状态,它里面不会记录变化,也就是说通过集群状态你并不能知道集群之前是啥样的,也不知道集群变了啥才到了现在的状态,你只能得到这一刻的集群状态信息

lasticsearch 的集群状态(Cluster State)确实只记录了当前的完整状态,而不会直接存储之前的状态或变化的历史信息。要了解哪些内容发生了变化,需要通过对比前后两个集群状态来计算。

2025-11-04 11:44:59 207

原创 【中间件】如何设计主分片

身份落盘:主记录只写在 **ZK 或 KRaft / ES-cluster-state / hbase:meta**,本地磁盘文件里**不带“主”标记**。选哪条路线,取决于你想要**强一致**还是**高吞吐**,以及**能不能接受选举复杂度**。- 身份落盘:选举结果写进 **自身事务日志**(zxid / raft-index),**多数派提交即持久**。- 日志层用 **Quorum 选主**(类似 etcd),但**数据分片本身不选举**,只是追着同一份日志回放;**正常工况永不漂移**。

2025-10-28 09:48:08 431

原创 【Elasticsearch】分片分配的触发场景汇总

`PUT /<index>` 创建索引 | `MetadataCreateIndexService` → 提交状态任务 → `AllocationService#reroute` | 新建主分片必须立即分配 || `PUT /_cluster/settings` 里改 `cluster.routing.*` | `ClusterSettingsUpdater` → reroute | 如禁用分配、调节并发值 || `POST /<index>/_close` | 同上 | 触发分片取消分配 |

2025-10-28 09:30:23 352

原创 【Elasticsearch】核心功能模块

1.集群状态变更 流程未完待续~

2025-10-28 09:25:48 72

原创 【Java】子类重载父类方法时哪些可以改哪些不可以改?

别的(返回、异常)只是“契约强度”问题,而可见性是“能不能看见”的问题,一旦收窄就多态破裂,因此必须“越晚(子类)越宽”。下面用一句话先给结论,再逐条拆开说。如果子类把可见性收窄,就会出现“在父类里能调到的方法,换到子类对象突然调不到了”,编译期类型检查直接塌方。“名参不变,返回可窄,异常可小,可见可大,final/static/private 别碰它。- `private` 方法:对外不可见,子类写同名方法算“新建”,与父类无关。- `static` 方法:属于类,不能被重写,只能被隐藏(hide)。

2025-10-11 09:08:44 276

原创 【Elasticsearch】JoinAccumulator实现类 静态内部类与内部类 的区别

LeaderJoinAccumulator` 普通内部类 ✅ 需要 要访问外部 `Coordinator.this.joinTaskExecutor / masterService / joinReasonService` 等成员。`CandidateJoinAccumulator` 普通内部类 ✅ 需要 同样要访问外部 `Coordinator.closed` 字段以及 `joinRequestAccumulator` 等状态。内部类 是否 static 是否独立需要外部实例 原因。

2025-10-11 08:54:13 395

原创 【elasticsearch】序列化与反序列化机制

Elasticsearch 里的类(包括 `ClusterState`)不需要实现 `Serializable`,因为它们全部实现了 ES 自己的 `Writeable` 接口,用 `writeTo`/`readFrom` 这一套“手写”协议完成高效、紧凑、版本兼容的序列化与反序列化。接收方用同样的顺序读回字段,再 `new` 一个新的 `ClusterState` 对象。- 因此,ES 里只要出现跨节点的对象,就一定会配套实现 `writeTo`/`readFrom`,否则连编译都过不了。

2025-09-26 10:40:18 415

原创 【Java】类要不要实现serializable有什么决定

→ 全部自定义协议,各自提供接口或注解(`Writeable`、`Serializer<T>`、`Externalizable`、`@Protobuf` 等),根本不看 `Serializable`。→ 框架只认 `instanceof Serializable`,不认就抛 `NotSerializableException`。所以“对象要不要实现 `Serializable`”确实取决于它所处的运行环境和所选框架,而不是写 Java 的强制规定。

2025-09-26 10:39:34 483

原创 为啥Java对象实现serializable就能序列化与反序列化呢?

正常代码无法给 `private int x` 赋值,但 `ObjectStreamClass` 在初始化时会为每个字段生成一个 `FieldReflector`,底层调用。绿灯一亮,JDK 就启动一套基于反射+Unsafe 的私有协议,把对象在内存中的完整状态“搬”到字节流里,再“搬”回来,于是看上去“实现了接口就能序列化”。- 因此,即使字段全是 `private`、类没有 `setter`,序列化框架依旧可以“把内存原样搬走,再原样搬回来”。1. 拿到对象所属的 `Class<?

2025-09-26 10:32:13 277

原创 elasticsearch8.1.0 中聚合功能的执行链路

`SearchService#parseSource()` → `AggregatorFactories.Builder.build()` – 将 `TermsAggregationBuilder` 编译为 `AggregatorFactory`(真正执行对象)。– `AggregationPhase.preProcess()` – 创建 `Aggregator[]` 数组,调用 `AggregatorFactory.create()` 得到 `TermsAggregator`。

2025-09-21 12:12:51 368

原创 【设计模式】为什么说设计模式血统不纯?

策略模式 vs 状态模式 都持有一个接口成员,运行时替换实现 策略是“外部传入”,状态是“内部自转换”你的感觉非常正常,而且这恰恰是软件设计中的“真实世界”状态。> “设计模式不是把世界切成整齐的抽屉,而是给混乱的代码一套‘可交流的外号’。- 只要解耦、可扩展、易读懂,就是好的设计——名字只是方便你跟别人解释。恭喜你,你看到的正是真实、演进、活的软件。✅ 1. 设计模式不是“标准库”,而是“经验总结”> “模式的价值不在于‘归类’,而在于‘沟通’。👉 它们更像是“设计词汇”,而不是“法律条文”。

2025-09-12 10:26:57 242

原创 【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 428

原创 【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 530

原创 【lucene】bitsetiterator

某些自定义 `FieldCache` 或 `DocValues` 去重逻辑,会先把出现过的 docID 记到 `BitSet`,再用 `BitSetIterator` 一次性吐出。`BitSet` 本身只有 `get()/set()/nextSetBit(int)`,没有标准的迭代器语义,于是就有了 `BitSetIterator` 做适配。- `cost()` 直接返回 `cardinality()`,方便上层 `ConjunctionDISI/DisjunctionDISI` 做排序、选 lead。

2025-09-09 09:10:31 620

原创 【lucene核心必看】持续完善

ing~

2025-09-08 09:46:40 117

原创 【lucene】数值型字段如何作为条件查询,回显,排序

StoredField("price", 100)` `.fdt` 文件 存原始值,回显/高亮 ✅ `doc.get("price")``IntPoint("price", 100)` `.dim` 文件(BKD 树) 范围/精确查询(>、<、=) ❌ 取不到。`NumericDocValuesField("price", 100)` `.dvd` 文件 排序、聚合、统计 ❌ 取不到。- 要“查”——加 `IntPoint`

2025-09-02 14:03:29 386

原创 【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 485

原创 【lucene】 中的impactsenum与impactsdisi有啥区别?

ImpactsDISI`(或其子类 `TermScorer` 里的 `ImpactsDISI`)在内部会持有一个 `ImpactsEnum` 实例,所有真正的“读磁盘、读 postings、读每个 block 的 maxScore” 都交给这个 `ImpactsEnum` 去做;真正的打分工作由上层组件(`TermScorer`/`ImpactsDISI` 或更外层的 `Weight`)完成,它们会把 `ImpactsEnum` 返回的 freq 等原始信息代入公式算出分数。

2025-09-01 15:19:44 469

原创 【lucene核心】impacts的由来

对每个 norm level,记录该 level 内出现的最大 freq,然后在所有 level 上再做一个“剪枝”:只有当某 level 的 maxFreq 比之前所有更低 level 的 maxFreq 都大时,才保留这个 (maxFreq, norm) 对。- 由于 `score(freq, norm)` 是单调函数,列表里最大的 `(freq, norm)` 必然给出最大分,所以只需要比较一次即可。

2025-09-01 12:05:35 888

原创 【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 359

原创 【lucene】advanceShallow (int target) 与advance(int target)

如果当前已经缓存的块里就有 ≥ target 的文档,就在块内找;如果没有,就先用跳表跳到。,再在这一小块里找;

2025-08-28 22:38:24 221

原创 【lucene】如何评测一款分析器Analyzer

跑 `mvn package && java -jar target/benchmarks.jar -wi 3 -i 5 -f 1` 即可得吞吐量、延迟。把“功能指标”当尺子、“性能指标”当秒表、“扩展指标”当保险丝,三步走完就能给出一份可复现、可回归、可横向对比的 Lucene 分析器评测报告。// 1 MB 中文。2. 性能:吞吐量(MB/s)、延迟(ms/1000 docs)、内存峰值、GC 次数、索引膨胀率。1. 功能性:分词准确性、召回率、歧义处理、停用词、同义词、大小写、数字、标点。

2025-08-28 11:36:46 324

原创 【lucene】SpanFirstQuery的end参数

在你的例子中,由于 `"中国"` 的位置是 3,而 `end` 参数设置为 1,所以无法在第一个位置查到 `"中国"`。如果你使用 `SpanFirstQuery` 查询 `"中国"`,并设置 `end` 参数为 1,那么查询会失败,因为 `"中国"` 的位置是 3,而 `end` 参数设置为 1 表示只匹配位置 0 和 1 的词。在这个例子中,`SpanFirstQuery` 会失败,因为 `"中国"` 的位置是 3,而 `end` 设置为 1,表示只匹配位置 0 和 1 的词。

2025-08-27 12:40:55 380

原创 【lucene】SpanNearQuery中的slop

SpanNearQuery`的`slop`参数指的是两个`SpanTermQuery`之间的“不匹配位置”的最大数量。如果两个`SpanTermQuery`的`term`相同,可能会导致内部处理问题,影响匹配结果。- 使用其他查询类型:如果`SpanNearQuery`无法满足需求,可以考虑使用其他查询类型,如`PhraseQuery`,它直接支持短语匹配,并且可以通过`slop`参数进行调整。因此,对于这个示例,`slop`的最小值应该是`2`,这样`SpanNearQuery`才能匹配这个文档。

2025-08-27 11:51:18 566

原创 【lucene☞】重叠token token的pos位置

这个编号从 1 开始,表示 token 在分词结果中的相对顺序。重叠 token 是指在分词过程中,同一个文本片段被分词器切分成多个不同的 token,而这些 token 在文本中的位置有交集。- 在 Lucene 中,基于位置的查询(如 `SpanNearQuery`、`SpanFirstQuery` 等)依赖 token 的位置编号来计算 token 之间的相对位置关系。> Token 的位置编号是分词器在分词过程中为每个 token 分配的顺序编号,用于表示 token 在分词结果中的相对顺序。

2025-08-27 09:58:49 857

原创 【lucene】spancontainingquery

3. 只保留那些 big 区间把某个 little 区间完全包住 的 big 区间;SpanContainingQuery = “只保留那些完全包住给定 little 区间的 big 区间”。big大区间 little小区间 这里的区间指的是区间里面词项包括。// 只保留那些完整包含 "B C" 的 "A B C D" 区间。// big: 任意 4-gram 的 "A B C D" 短语。- 限定“长短语”必须包含某个“子短语”后再做高亮或打分。1. 先列出 `big` 产生的所有区间(较长、较宽)。

2025-08-26 17:20:36 573

原创 【lucene】SpanNotQuery 存在的意义

从 “整本书要不要” → “把书里具体几行裁掉或保留”,粒度细得多,能满足“邻近/排除/精准高亮”等更复杂的搜索需求。- 文档 C:“I like apple cake.” 里的 apple 没被罩住,就被保留,文档返回。- BooleanQuery 像“整本书”级别的标签:这本书贴了“apple”和“pie”两张标签。它让 Lucene 从“文档检索”升级到“短语/区间检索”,满足更复杂的业务需求。在“词的位置”这一更细粒度上做布尔运算,而不仅仅在“文档”级别做 AND/OR/NOT。

2025-08-26 16:33:11 701

原创 【lucene】lucene常用查询一览

`SpanContainingQuery`、`SpanWithinQuery`(sandbox)—— 判断一个 span 是否包含 / 位于另一个 span 内。- `MatchAllDocsQuery` 的脚本版本:`_score = doc['price'].value * 0.7`- `LatLonPoint.newDistanceQuery` / `newBoxQuery`(地理距离、矩形)9. **Wildcard / Prefix / Regexp 族(通配正则)**

2025-08-21 22:24:48 418

原创 【Java】方法内联

用 `-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining` 观察哪些方法被内联。`-XX:-Inline` 或 `-XX:CompileCommand=dontinline,com.pkg.MyClass::readBytes`把本来要“跳过去、再跳回来”的方法调用,在编译期直接把方法体代码原封不动地拷贝到调用点,从而省掉一次函数调用的开销(压栈、跳转、返回等)。astore_1 // 把结果给 x。

2025-08-20 09:31:36 318

原创 【Java】用二进制,八进制,16进制来给int整数类型进行赋值

/ 二进制 0b 或 0B 开头,值 = 11(十进制)int c = 0xB;// 十六进制 0x 或 0X 开头,值 = 11(十进制)int b = 013;// 八进制 0 开头,值 = 11(十进制)int d = 11;// 十进制,无前缀,值 = 11。- 八进制容易和十进制混淆,日常代码基本不用。- 二进制从 Java 7 开始支持。

2025-08-20 09:14:24 187

原创 Lucene 8.5.0 的 `.pos` 文件**逻辑结构**

2. **只要启用 payload 或 offset,则 PackedPosDeltaBlock 不出现**,全部走 VIntBlock;│ ├─ PackedPosDeltaBlock × N ← 仅当 **无 payload 且 无 offset** 时存在。3. **payload bytes** 在“尾巴”阶段 **内联在 `.pos`**,整块阶段 **在 `.pay`**;1. **PackedPosDeltaBlock** 只存 **纯 position delta**;

2025-08-18 22:29:46 310

原创 【lucene】tim文件解析 上

InnerNode(非叶子)= 词条 + 子块指针 → 子块指针条目 不存 `TermStats/Metadata`,只用 1 bit 标记“这是子块”。在 `.tip` 文件里,整棵 FST 已经用 共享前缀 把节点合并得足够紧凑,这里的前缀只服务于 FST 结构,与 `.tim` 无关。- 先读 `RootCodeLength` 字节 → 拆出前缀和指针 → 用指针直接 seek 到 `.tim` 的根 block。- 后面每个词条只需再写剩余后缀(`le`, `lication` …

2025-08-18 12:26:52 345

原创 【lucene】tip文件详解

.tip` = 文件头 + 若干 FST(每字段一棵)+ 它们的偏移表 + 偏移表的目录指针 + 校验尾;通过 FST 把前缀迅速映射到 .tim 中的 block,实现毫秒级随机访问。> 词 → 字段编号 → .tip 的 DirOffset → 字段 FST → blockFP → .tim 的 block → 最终词条。- 这棵 FST 的 输入 是 词的字节前缀,输出 是 “路标块”在 .tim 中的文件指针。- blockFP —— 该前缀对应的 block 在 `.tim` 的起始文件指针。

2025-08-18 11:05:12 624

原创 【lucene】SegmentInfos

【代码】【lucene】SegmentInfos。

2025-08-16 21:46:06 209

原创 【lucene】DocumentsWriterFlushControl

• `commit/close/forceMerge` 等操作会触发 full flush → `flushAllThreads()` → `markForFullFlush()` 把所有 active DWPT 一次性刷盘并生成 commit point。• `DocumentsWriterFlushControl` 内部持有一个 `FlushPolicy`(默认是 `FlushByRamOrCountsPolicy`),根据。• 每个线程写完文档后,都会把数据放到自己的 DWPT 缓冲区。

2025-08-14 17:56:42 375

xampp配置.doc

xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置xampp配置

2018-04-25

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除