Easysearch
Easysearch analysis-ik 多词典性能优化:从性能回退到分词性能提升 25%~30%
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 3443 次浏览 • 5 天前
Easysearch 版 analysis-ik 相比开源 IK 有一个重要的增强:支持多词典。简单说就是不同字段可以挂不同词库,可以叠加默认词典,也可以只用自定义词典。这是开源单词典 IK 做不到的。
功能实现初期,主要精力放在把能力跑通上。但在后来的一次写入压测中,我们发现 Easysearch 的写入吞吐和 Elasticsearch 有明显差距,最终定位到问题出在多词典的实现方式上——字段最终该用哪套词典,本来应该在分词前就算好,结果代码里把这个选择丢进了分词的热路径,每次分词都要反复切词典、重复扫同一段文本。
这篇文章记录的就是我们怎么一步步把性能拉回来、最终反超基线的过程。
问题怎么冒出来的
4 月 20 号,我们跑了一轮系统级写入压测。数据、mapping、settings、并发和 bulk 参数都一样,Elasticsearch 8.19.5 和 Easysearch 2.1.2 的写入吞吐差距大得有点不对劲:
| 时间 | 场景 | Elasticsearch | Easysearch | 说明 |
|---|---|---|---|---|
| 2026-04-20 第 2 次有效重跑 | 29900 docs / bulk=250 / concurrency=3 端到端写入压测 |
129.44 docs/s |
31.21 docs/s |
这是整条写入链路的 docs/s,不是单独分词吞吐 |
| 2026-04-20 诊断样本 | 5000 docs / bulk=250 / concurrency=3 |
156.25 docs/s |
30.67 docs/s |
Easysearch 的累计索引耗时约为 Elasticsearch 的 8.0x |
当时服务器上跑的就是早期多词典版本。后面修性能,追的就是这个版本和开源单词典 IK 基线之间的差距。
这一步还不能直接确定问题就在分词器。但差距摆在这儿了,得继续往下排。我们先排除了几个常见干扰因素:
refresh_interval- 动态同义词 HTTP 服务
- mapping / settings 不一致
- 网络层和 bulk 客户端本身
采样结果很快把范围收窄了。Elasticsearch 那边热点比较分散,Easysearch 这边呢,分词链路里出现了异常集中的开销——分词过程中反复做词典选择和字典查找。
瓶颈不在 Lucene 写入链路本身,就在 analysis-ik 的多词典实现上。
根因分析
第一类问题出在实现模型上。多词典想表达的是”这个字段最终用哪套词典”,这件事完全可以在分词前算好。但早期代码里,硬是把它变成了运行时的事:
- “字段用哪个词典”变成了”运行时多轮扫描”——同一段文本对着多套词典各来一遍。
- 全局字典切换的动作放进了每字符的热路径。
- 结果就是同一段文本的扫描和查找成本翻了好几倍。
所以问题不是多词典天然慢,是实现把本该提前算好的东西塞进了热路径反复做。
第二类问题是后续优化过程中留下的额外开销。后面加的跨边界、停用词、长文本等测试本身不是性能问题的来源,它们的作用是把正确性边界补齐,确保每次优化不会改变分词结果。
最后通过性能分析确认,残留开销主要来自两处:缓存命中前还在做不必要的数据复制;诊断逻辑在生产热路径上产生了额外开销。修完之后这两处热点都从火焰图上消失了,说明性能回退确实来自真实的代码路径成本,不是测试抖动。
修复过程
整个修复分四个阶段。
第一阶段:把多词典从”运行时分发”收敛为”最终有效词典视图”
多词典能力保留,但不再让分词器在热路径里反复切词典、重复扫文本。改成在分词前就把字段最终生效的词典算好,分词过程只面对一个已经收敛好的词典视图。
说白了就是把模型拉回正确方向——多词典管表达能力,热路径只管分词。
第二阶段:逐步打掉热路径上的常数开销
留下来的每一项优化,都经过正式性能测试和采样分析验证。原则就一条:不改分词语义,只减少热路径上反复发生的查找、分配和判断。
第三阶段:补齐正确性护栏
正确性测试必须先到位,不然吞吐提升没有意义——万一分词结果变了,跑得再快也白搭。
这一轮重点覆盖了这些容易出问题的场景:
- 真跨边界场景
- 数字和量词合并,如
1号 - 自定义词典里的含符号词
- 补充平面字符跨边界稳定性
- 停用词过滤后的偏移量
- 长文本样本的稳定性
- 正式性能测试数据集的分词结果对齐
后面所有的吞吐数字,前提都是分词结果一致,避免把分词行为的变化误当成性能提升。
第四阶段:清理最后的残留开销
到 4 月 28 号,最后一轮修复集中处理两个地方:
- 词典视图命中缓存时直接返回,不再多做一次数据复制
- 诊断逻辑默认关掉,不让线上请求为调试能力买单
这两处修完,Easysearch 版 IK 就不只是恢复到单词典版本附近了,在正式测试里已经明显领先。
用数据看恢复过程
为了不把系统级写入压测和分词器性能测试混在一起,下面只看几个关键节点。2026-04-20 的 docs/s 是系统级写入吞吐,后面的 tok/s 是单独的分词器吞吐。
这里说的”开源 IK 基线”就是开源 IK 的单词典实现对照版本。所有正式吞吐结论都建立在同一数据集、同一测试方法、分词结果一致的前提上。
| 时间 | 口径 | 关键结果 | 说明 |
|---|---|---|---|
| 2026-04-23 17:02 CST | 初期本地复现 | 服务器多词典版本 61.39 万 tok/s,单词典版本 114.48 万 tok/s |
单词典版本快 86.49%,性能差距被明确复现 |
| 2026-04-24 09:51:12~09:55:15 CST | 第一次正式追平 | smart 相对开源单词典基线 +7.26% |
从明显落后追到略微领先 |
| 2026-04-25 04:14~04:16 CST | 双模式阶段复核 | smart +16.88%,max_word +20.09% |
领先优势开始扩大 |
| 2026-04-28 12:30:56 CST | 最新正式复核 | smart +30.96%,max_word +21.31% |
当前最新结果 |
整个过程就是:
- 先暴露出明显的性能退化
- 逐步缩小差距
- 追平,然后开始领先
- 最终在分词结果完全一致的前提下,正式反超
最早的本地复现数据很关键:服务器当时跑的多词典版本只有 613896.67 tok/s,单词典版本 1144843.77 tok/s。后面所有修复就是冲着这个差距去的。
三张图分别对应问题暴露、分词复现和修复结果:第一张展示服务器 bulk 写入吞吐的系统级差距;第二张展示多词典版本和单词典版本的本地分词差距;第三张展示分词结果对齐后,Easysearch 版 IK 怎么一步步追上来,最终实现 25%~30% 的分词性能提升。
为什么说 Easysearch 版 IK 现在更好
这次修复的价值不只是消灭了几个热点,更重要的是把多词典能力、分词正确性和性能测试体系一起补齐了。
1. 功能更强,性能代价可控
开源单词典 IK 模型简单,但表达能力也弱。Easysearch 的多词典能力要解决的是字段级词库隔离、自定义词典叠加这些实际需求。
关键问题是:能不能把这些能力的性能开销压到足够低。修复后的结果证明,可以。
2. 正确性护栏更完整
这轮补上的测试不只是几个短样例,覆盖了更容易翻车的边界条件:
- 真跨边界场景
- 长文本稳定性
- 自定义词典和符号词
- 数字量词合并
- 停用词过滤后的偏移量
这意味着以后再做性能优化,必须同时保证分词结果不变。想靠改分词行为换吞吐,测试会先拦住。
3. 性能测试体系更严格
这轮之后,Easysearch 对 analysis-ik 的正式性能结论统一按一套标准出:
- 同一数据集
- 同一测试方法
smart和max_word双模式- 分词结果一致
- 有性能分析结果支撑
这套体系能避免两个常见坑:只看单轮吞吐波动就下结论,或者分词结果已经变了还在比性能。
小结
多词典能力在实现初期,主要精力放在功能补齐上——先把字段级词库隔离、自定义词典叠加这些能力跑通,性能优化是后面分阶段来的事,没办法一蹴而就。
这轮优化下来,核心思路其实就一条:把词典选择从分词热路径里挪出去,提前收敛好,让分词过程只面对最终的词典视图。再配合热点清理和正确性护栏,增强功能和更高性能完全可以兼得。
截至 2026 年 4 月 28 日,在本地 Mac 笔记本上的多轮 benchmark 中,Easysearch 版 IK 在 smart 模式大约领先开源单词典 IK 基线 25%~30%,max_word 模式大约领先 20% 左右,分词结果完全一致。具体数字每次跑会有波动,但趋势是稳定的。
这也是 Easysearch 版 IK 相对开源版更有价值的地方:不是多了几个配置项,而是在多词典能力、分词正确性和分词性能三个方面都给出了可验证的结果。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
Easysearch 正式支持插件开发:让你的搜索系统真正"为你所用"
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 10094 次浏览 • 2026-04-27 22:02
从"用搜索"到"造搜索"
搜索系统的需求千差万别。标准功能覆盖不了所有场景——行业特定的分词规则、定制化的业务逻辑、与外部系统的深度集成……
以往,这类定制需求需要依赖厂商支持。从 Easysearch 2.1.2 开始,你可以自己动手了。
随着构建依赖库正式发布到 Maven 中央仓库,Easysearch 的插件开发能力正式对外开放。这意味着 Easysearch 不再是一个黑盒产品,而是一个可扩展、可定制的搜索平台。你可以基于官方接口开发自定义插件,像使用原生功能一样使用它们。
插件能做什么
Easysearch 提供三类核心扩展点,覆盖搜索系统的关键环节:

1. 分析器插件(AnalysisPlugin)
自定义分词器、Token 过滤器、字符过滤器。适用于:
- 电商 SKU 的型号规格解析
- 医疗、法律等领域的专业术语分词
- 特殊符号或空格的规范化处理
注册后直接在索引设置中使用,与原生分析器完全等同。

2. REST/API 插件(ActionPlugin)
新增自定义 HTTP 接口。适用于:
- 封装业务查询逻辑,对外暴露简化 API
- 对接企业内部权限中心或监控系统
- 暴露插件自身的管理接口(如状态检查)

3. Ingest 插件(IngestPlugin)
在文档写入前进行字段转换。适用于:
- 自定义业务字段转换(如根据业务规则计算衍生字段)
- 数据标准化(统一日期格式、大小写转换)
- 富文本提取或元数据生成

5 分钟上手
我们准备了官方模板仓库,让你从克隆到运行只需几条命令:
# 克隆模板
git clone https://github.com/infinilabs/easysearch-plugin-template.git my-plugin
cd my-plugin
# 修改包名和类名,编写你的逻辑
# ...
方式一:开发调试——直接运行
# 构建插件并运行
./gradlew run
# 验证插件
curl -s "http://localhost:9200/_cat/plugins?v" | grep my-plugin
方式二:构建后安装到外部集群
# 构建插件
./gradlew build
# 安装到 Easysearch
bin/easysearch-plugin install file:///$(pwd)/build/distributions/my-plugin-0.1.0.zip
# 启动验证
bin/easysearch
curl -s "http://localhost:9200/_cat/plugins?v" | grep my-plugin
完整的开发指南请参考插件开发文档。
设计哲学
Easysearch 插件系统的设计遵循三个原则:
渐进式扩展——从最简单的 Plugin 类开始,按需实现 AnalysisPlugin、ActionPlugin 等接口,不必一次性掌握全部 API。
与原生同等——插件注册的分析器、处理器与系统原生组件在使用方式上完全一致,用户无需关心实现来源。
版本安全——插件加载时校验 easysearch.version,版本不匹配会拒绝加载,避免运行时异常。
从插件到生态
插件开发不只是技术能力的开放,更是产品理念的转变。
你可以将开发的插件发布到 GitHub Releases,通过 URL 直接安装:

bin/easysearch-plugin install https://github.com/yourname/my-plugin/releases/download/v0.1.0/my-plugin-0.1.0.zip
我们也欢迎社区贡献。如果你有通用的插件想法,欢迎与我们交流。
结语
搜索系统的最后一公里,只有业务开发者最清楚该怎么走。
Easysearch 2.1.2 的插件开发能力,让你能够自主掌控搜索系统的"最后一公里"。从"用搜索"到"造搜索",现在你可以让你的搜索系统真正"为你所用"。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
INFINI Agent v1.31.0 发布 | 全新 Easysearch 向导:一站式集群拉起与精细化管理
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12639 次浏览 • 2026-04-23 18:01

INFINI Agent v1.31.0 带来了本版本最重要的特性——Easysearch 安装向导。用户无需手动编辑任何配置文件,通过图形界面即可完成 Easysearch 集群的安装、配置和日常管理。
Easysearch 安装向导
一键拉起新集群
向导支持开发模式和生产模式两种方式创建 Easysearch 节点。用户只需填写集群名称、节点名称、监听地址、端口、数据目录等基本信息,向导便会自动完成软件下载、JDK 配置、安全证书生成、参数配置、插件安装、节点启动等全部步骤,并实时展示每一步的进度,支持随时暂停和恢复。

一键加入已有集群
通过粘贴现有集群提供的 Token,向导可自动从目标集群拉取证书、版本、插件等配置信息,完成新节点的安装和接入,全程无需手动复制任何证书文件。

安装前环境预检
向导在开始安装前会对当前机器进行全面检测,帮助用户提前发现潜在问题:
- 操作系统和 CPU 架构是否受支持
- 内存是否满足推荐要求
- 端口是否已被占用
- 数据目录磁盘空间是否充足、路径是否可写
- 系统参数(文件描述符限制、内核
max_map_count等)是否满足 Easysearch 运行需求 - TLS 证书填写后实时校验有效性,包括证书链完整性和过期时间

TLS 安全证书灵活配置
支持三种证书配置方式,满足不同安全需求:
- 自动生成:向导一键生成自签名证书,无需任何证书知识
- 手动上传(共享):为 HTTP 和节点通信层提供同一套证书
- 手动上传(分离):为 HTTP 层和节点通信层分别提供独立证书

完整的服务生命周期管理
集群建好后,向导提供持续的管理能力:
- 启动、停止、重启 Easysearch 节点

- 在线安装和卸载插件

- 在线编辑配置,包括
easysearch.yml、JVM 参数、日志配置、证书配置

- 在线日志排查:内置日志阅读器,支持查看节点日志文件列表,并提供类似 tail -f 的自动滚动功能,无需登录服务器即可快速定位报错。”

网络受限环境支持
针对无法直接访问外网的环境,向导支持配置 HTTP 代理,所有软件包(Easysearch、JDK、插件)均可通过代理下载,并提供连通性测试功能。

获取新版本
INFINI Agent v1.31.0 已正式发布,欢迎升级体验:
同样 15,000 条重规则,Percolate Query 比 Easysearch 慢 21.8 倍 —— Heavy-OR 场景实测
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 17145 次浏览 • 2026-04-15 16:44
15,000 条 heavy-OR 规则,200,000 条文档,同一台机器:Easysearch 在线规则引擎全流程 11.68 秒,Percolate Query 仅搜索阶段就跑了 254.30 秒——慢了 21.8 倍。
在"规则先存、文档后到"这类场景下,Percolate Query 的延迟会随规则数量和复杂度的增长快速恶化。规则涨到数千条后,每批文档匹配的耗时可以从秒级攀升至几分钟。这类问题换索引参数、调批次大小、精简 DSL,都治标不治本,根子在执行模型本身。
本文通过一组 heavy-OR 基准测试,量化两种方案的实际差距。
测试配置
测试在同一台主机上运行,使用同一套规则文本和文档样本。Percolate Query 的查询条件由相同规则翻译而来,保证两侧规则语义一致。
| 参数 | 值 |
|---|---|
| 规则总数 | 15,000 |
| 文档总数 | 200,000 |
| 批次大小 | 10,000 / 批 |
| 重规则数量 | 2,500 条大 OR 热点规则 |
| 单条大 OR 规模 | 随机 50 ~ 500 个 OR 条件 |
测试结果
| 路径 | 用时 |
|---|---|
纯写入 plain_bulk |
6.025535s |
在线规则引擎 rules_only |
11.684568s |
Percolate Query 搜索阶段 |
254.304583s |
同样 15,000 条规则 + 200,000 条文档
具体指标:
- Easysearch 在线规则引擎全流程:
11.68s - Percolate Query 搜索阶段:
254.30s - 差值:
242.62s - 倍数:
21.76 倍 - 每批(10,000 文档)平均耗时:Easysearch 约
0.49s,Percolate Query 约12.69s
开启规则引擎的增量成本
规则匹配会对写入链路产生多少额外开销,是评估在线规则引擎可行性的重要指标之一。
开启规则引擎的写入增量
与之对比,Percolate Query 仅搜索阶段就需要 254.30s。换言之,Easysearch 在线规则引擎把规则匹配叠加进写入流程,新增成本约为 Percolate Query 搜索耗时的 1/44.9。
只看匹配引擎本体
上一组数据(11.68s vs 254.30s)包含了 Easysearch 的在线写入、bulk 解析和索引处理等通用开销。为了单独衡量规则匹配引擎自身的性能,我们用 Java 直调 JNI 做了一次离线 match,绕过写入链路,只跑规则匹配逻辑。
| 路径 | 用时 |
|---|---|
| Easysearch 纯匹配(JNI 离线) | 5.046934s |
| Percolate Query 搜索阶段 | 254.304583s |
只比匹配本身
这组数据说明两点:Easysearch 的性能优势并非来自写入链路的整合效率,即便剔除通用写入成本,规则匹配引擎本体与 Percolate Query 之间依然存在约 50 倍的差距。
为什么 Percolate Query 会慢
根因在执行模型,OR 条件多只是放大器。
每批文档到达时,Percolate Query 都要走完这套流程:
- 把文档放进临时内存索引
- 基于规则中的 terms 筛选候选规则
- 对候选规则逐条验证
以本次测试为例,各阶段耗时分布如下:
- 规则翻译:
9.560294s - 规则导入:
7.451857s - percolate 搜索:
254.304583s
搜索阶段是每批文档都必须重新支付的代价。
Heavy-OR 规则在这套流程里两头放大:规则覆盖面广,候选集更难剪掉;单条规则条件多,逐条验证也更重。
Easysearch 规则引擎把规则提前编译好,文档到达后直接匹配,不走这套每批重建的流程,差距就在这里。
适用场景
以下场景对规则匹配的吞吐和延迟要求较高,是 Easysearch 在线规则引擎的典型适用范围:
- 内容审核:规则持续增长且复杂度高,需要稳定的处理吞吐,对单批延迟敏感。
- 舆情监测:热点词、别名、邻近词组合多,规则天然形成大 OR 结构,是 Percolate Query 最容易触及性能瓶颈的场景。
- 广告定向:人群包条件不断叠加,文档流量高,规则匹配需要足够轻量,避免影响整条投放链路。
- 告警规则:延迟直接影响告警有效性,规则命中需要尽量贴近文档写入时刻。
- 实时反欺诈:规则复杂、变更频繁、吞吐高,要求文档到达后立即完成判断。
小结
在本次 heavy-OR 基准测试中:
- 相同规则集(15,000 条)和文档量(200,000 条),Easysearch 在线规则引擎全流程耗时 11.68s,Percolate Query 仅搜索阶段耗时 254.30s,相差 21.8 倍。
- 开启规则引擎带来的写入链路增量成本为 5.66s,约为 Percolate Query 搜索阶段耗时的 1/44.9。
- 剔除写入通用开销后,规则匹配引擎本体的差距约为 50 倍。
如果你的业务已经有 Percolate Query 延迟随规则增长持续上升的问题,不用看 demo 数据——把你线上最重的那批规则拿出来,跑一次就知道差距在哪。
规则引擎功能当前需要试用 License。你可以先下载 Easysearch:https://infinilabs.cn/download,再联系售前申请试用 License 并获取开通指引。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
Easysearch BKD Merge 异常排查实录:最终定位到旧版 GraalVM JIT 运行时
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 11137 次浏览 • 2026-04-10 17:51
最近一次高并发写入压测中,我们遇到了一个非常诡异的 BKD merge 崩溃。从报错看,很像 Easysearch 2.1.2 在 merge 阶段把 segment 读成了错误状态。典型错误是这样的:
java.lang.ArrayIndexOutOfBoundsException: Index -3 out of bounds for length 8
java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8
异常栈最终落在 Lucene BKD 相关路径上:
BKDReader.readNodeData()BKDWriter.merge()Lucene90PointsWriter.merge()
如果只看栈,很容易把问题归到 Easysearch 的 BKD merge 逻辑。但排查到最后,结论恰恰相反。
问题不在 Easysearch 的代码,而在 JDK 运行时。 更精确地说,是某个特定 Oracle GraalVM 21 构建中的 JVMCI/Graal JIT 路径,把 Lucene BKD 的热点代码执行错了。
1、为什么这个问题难查
它有几个特别迷惑人的特征:
- 只在高并发写入压测下触发
- 服务重启后的前几轮最容易复现
- 同一进程里,删了索引重新压,后面复现率反而下降
- 不是固定字段,多个数字类型字段都中过招
ZSTD和best_compression两种 codec 下都能复现
实际命中过的字段包括 @timestamp、size、status、_seq_no。所以这不是某个字段、某种 codec 或某个 mapping 的偶发问题。
2、第一层排除:merge reader 不是第一现场
一开始我们确实怀疑 merge reader,毕竟异常直接出现在 merge 路径上。但日志顺序很快给出了相反的证据。在 merge 真正崩溃之前,source segment 已经先出现了这些异常信号:
point-sort-restore-multiple-zero-ordssource-write-point-doc-mismatchpointCount > docCountpack-index-negative-codereader-invalid-start-pos- 最后才是
ArrayIndexOutOfBoundsException
这意味着两件事:merge reader 不是第一现场,source segment 在写出阶段就已经坏了。merge reader 只是读到了已经损坏的 BKD index,并在那个阶段暴露了异常。
3、第二层排除:Easysearch 自己的 BKD 写入逻辑也没有先出错
继续往前追溯,我们发现问题比 OneDimensionBKDWriter.add() 还要早。真正的异常出现在排序/回填链路上:
PointValuesWriterMutablePointTreeReaderUtils.sort()StableMSBRadixSorter
关键证据来自两个探针:
point-sort-restore-multiple-zero-ordsunwrittenSlotCount == source-write-point-doc-mismatch delta
这说明在某次排序/回填过程中,有一部分槽位根本没有被写入,默认值 0 被 restore 回填到 ords[],再通过 docIDs[0] 放大成大量 docID=0,最终导致 pointCount > docCount,source segment 进入错误状态。
到这一步,排查重点已经不是“Easysearch 的 BKD merge 逻辑存在缺陷”,而是 Lucene points 排序链路的执行结果和源码语义不一致。
4、真正的转折点:抓到了 reorder() 自身的 coverage 异常
真正把方向扭转过来的,不是又一次复现,而是一个更早的探针:
point-sort-reorder-coverage-mismatch
这个探针验证的是:StableMSBRadixSorter.reorder() 是否真的按源码应有的次数完整执行。
我们抓到的典型样本之一如下:
targetSegment=_xfield=statusk=7expectedLoopCount=9800actualIterationCount=8204firstCoverageMismatchBucket=201firstCoverageExpected=9788firstCoverageActual=8192
更关键的是,同一条日志里还带出了这个信息:
skippedSourceSamples=[201:[{ord=8192,bucket=201,docID=9090,byteAtK=200}, ...]]
这条信息非常重要,因为它说明:bucket 201 理论上应该处理 9788 条,实际只处理了前 8192 条,但从 ord=8192 往后的样本,读出来仍然还是 bucket=201。这直接推翻了“后半段数据被污染后改桶”的旧解释,指向了一个更直接的结论:reorder() 自己的 coverage 被截断了。
另一个样本中出现了同类边界:firstCoverageExpected=31822,firstCoverageActual=16384。
到这里,一个很不自然的特征浮现出来:8192、16384——这些明显的 2 的幂边界,更像是运行时或 JIT 执行异常,而不是普通业务逻辑 bug。
5、哪段代码最可疑
此时怀疑对象已经不是泛泛的“BKD 整体有问题”,而是 Lucene 中的这段热点循环:
for (int i = 0; i < HISTOGRAM_SIZE; ++i) {
final int limit = endOffsets[i];
for (int h1 = fixedStartOffsets[i]; h1 < limit; h1++) {
final int b = getBucket(from + h1, k);
final int h2 = startOffsets[b]++;
save(from + h1, from + h2);
}
}
restore(from, to);
代码位于 org.apache.lucene.util.StableMSBRadixSorter#reorder(...)。
按源码语义,这段代码应该完整扫描每个 bucket 的范围,并最终把全部结果 restore 回去。但我们抓到的事实是:expectedLoopCount != actualIterationCount,某些 bucket 只跑到 8192 / 16384 就停了,随后出现未写槽位,restore 把默认 0 回填,最终 source segment 进入错误状态。
如果这是 Java 源码本身的稳定逻辑 bug,它在解释执行时也应该稳定触发,而不应该强烈依赖某个 JDK/JIT 组合。后面的 JVM 对照实验基本排除了这个可能性。
6、最强证据:只换 JDK / JIT 路径,结果就变了
这次排查中最有说服力的,不是某一条日志,而是对照实验。
基线组:旧版 Oracle GraalVM 21,默认 JVMCI/Graal JIT
环境:
Oracle GraalVM 21+35.121+35-jvmci-23.1-b15Linux aarch64 / ARM64UseJVMCICompiler = true
结果:很快复现,命中了 point-sort-reorder-coverage-mismatch、point-sort-reorder-underfilled、point-sort-restore-multiple-zero-ords,随后 merge 报 ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8。
对照组:关闭 JVMCI/Graal JIT 或纯解释执行
只改 JVM 参数,不改代码和压测口径:
-XX:-UseJVMCICompiler-Xint
结果一致:都没有再出现上述探针和异常。
这三组对照的意义很直接:如果这是 Easysearch 或 Lucene 的纯 Java 逻辑 bug,解释执行也应该能稳定复现。但现实是基线组复现,关闭 JVMCI 和纯解释执行都不复现。问题显然高度依赖 JIT 路径。
版本对照:较新的 GraalVM 21 构建在当前测试中未复现
这里需要补充一条重要的边界条件。我们后来又测试了一个较新的 GraalVM 版本:
java version "21.0.9" 2025-10-21 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.9+7.1 (build 21.0.9+7-LTS-jvmci-23.1-b79)
在当前压测中,这个版本没有再出现 merge 错误。
因此结论必须写得更精确:已知会复现的是较早的 21+35-jvmci-23.1-b15,已知在当前测试中未复现的是较新的 21.0.9+7-LTS-jvmci-23.1-b79。更准确的工程判断不是“GraalVM 21 整体都有问题”,而是某个特定 GraalVM 21 构建有问题,较新的构建很可能已经修复或规避了该问题。这里仍需保持严谨:只能说“在当前压测中未复现”,还不能直接说“已经被完整证明没有问题”。
平台边界:不能写成 ARM 专属
除了前面详细展开的 Linux aarch64 / ARM64 主要实验环境外,有用户反馈在以下环境中也出现过同类问题:
- 操作系统:
openEuler - 内核:
4.19.90-2112.8.0.0131.oe1.x86_64 - 架构:
x86_64
这是用户的测试环境,不是我们能够独立完整复现并逐项展开的。但这条信息已经足够说明:当前不能把问题简单写成“ARM 平台专属”。更准确的说法是:我们在 ARM64 上系统性复现并完成了主要对照实验,另外也有 openEuler x86_64 测试环境的同类现象反馈,因此平台边界目前还没有被完全钉死。
7、更强的同机对照:换成 Oracle HotSpot 21.0.10 后,全量写入跑完也没有问题
为了进一步排除“是不是所有 Java 21 都会这样”,我们在同一台服务器上把 /infini/easysearch/jdk 从 Oracle GraalVM 21 换成普通 Oracle HotSpot 21.0.10,恢复默认 JVM 参数,用同样的写入压测继续验证。
其中一轮的结果很有说服力:
- 索引:
nginx_zstd3_40mt4 - codec:
ZSTD threads=16bulk_size=1000target_docs=181463624
最终 after_count=181463624,delta_written=181463624,全量文档写入完成,服务端没有出现任何 BKD merge 错误。
这条结果至少说明:同一台机器、同一套 Easysearch、同样的数据规模和写入模型,只要把 JDK 从 Oracle GraalVM 21 换成 Oracle HotSpot 21.0.10,问题就不再出现。
到这一步,工程判断已经比较清晰了:不是 Easysearch 自身逻辑导致,也不是所有 Oracle JDK 21 都会出错,更像是特定 Oracle GraalVM 21 构建相关的 JVMCI/Graal JIT 路径问题。
8、最关键的外部对照:Elasticsearch 8.19.5 也复现了
如果说前面的结论还能被质疑为“Easysearch 某些实现差异触发的”,那么后面的外部对照基本排除了这个方向。
我们在同一台服务器上部署了 Elasticsearch 8.19.5(Lucene 9.12.2),JDK 也切到相同的 Oracle GraalVM 21,执行同类写入压测。结果 Elasticsearch 也复现了同样的 BKD merge 崩溃。
关键异常完全一致:
java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8
栈也一样落在 BKDReader.readNodeData、BKDWriter$MergeReader.collectNextLeaf、BKDWriter$MergeReader.next。
这条证据的力度很强:不是 Easysearch 独有的问题,不是当前这套 Lucene 代码路径独有的问题,Elasticsearch 8.19.5 + Lucene 9.12.2 在同类 GraalVM 21 环境下也会出现同类异常。到这一步,再把问题归因于 Easysearch 本身的代码逻辑,已经缺乏依据了。
9、这次排查最终说明了什么
把整条证据链串起来,当前阶段的结论已经比较清楚。
已验证的事实:
- 问题不是 merge reader 先制造坏数据,source segment 在更早阶段就已经进入错误状态
- 不是单字段问题,也不是
ZSTD或best_compression专属 - 已抓到
StableMSBRadixSorter.reorder()自身的 coverage 异常 - 关闭
UseJVMCICompiler后问题不复现,-Xint下也不复现 - 同机切到
Oracle HotSpot 21.0.10后,Easysearch 全量写入跑完未见 BKD merge 异常 Elasticsearch 8.19.5 + Lucene 9.12.2在同类 GraalVM 21 环境下也复现- 较新的
21.0.9+7-LTS-jvmci-23.1-b79在当前压测中未复现 - 某用户的
openEuler x86_64测试环境中也出现过同类错误,因此不能写成 ARM 专属
工程结论:
从工程证据来看,Easysearch 本身的代码逻辑没有问题。
当前最符合事实的结论是:问题高度相关于特定 Oracle GraalVM 21 构建,更具体地,是该构建相关的 JVMCI/Graal JIT 路径。它把 Lucene BKD 相关热点代码执行到了错误状态。已知较早构建 21+35-jvmci-23.1-b15 可复现,已知较新的 21.0.9+7-LTS-jvmci-23.1-b79 在当前测试中未复现。平台边界目前尚未完全钉死,不能再简单写成仅限 ARM64。
换句话说,这不是“Easysearch 的 BKD merge 实现有 bug”,而是特定 JDK/JIT 运行时把本来正确的 Lucene BKD 代码执行错了。
10、建议版本与规避方案
如果你在生产或测试环境中运行 Easysearch 或 Elasticsearch,并且使用的是某些 Oracle GraalVM 21 构建,且启用了默认的 JVMCI/Graal JIT,那么在高并发写入、频繁 merge、BKD 热点路径被充分打热的场景下,需要特别警惕这类问题。
现阶段比较明确的建议是:
- 避免继续使用已经验证可复现的旧版构建:
Oracle GraalVM 21+35.1或21+35-jvmci-23.1-b15 - 优先升级到当前测试中未复现的版本:
Oracle GraalVM 21.0.9+7.1(即21.0.9+7-LTS-jvmci-23.1-b79) - 如果短期内不方便升级 GraalVM,直接切换到普通
Oracle HotSpot 21.0.10
直接落到版本号上会更清晰:
- 已确认应避开:
21+35-jvmci-23.1-b15 - 当前更推荐:
21.0.9+7-LTS-jvmci-23.1-b79
原因很简单:前者我们已经复现了,后者在当前压测中没有复现。当然,这里的“推荐”是基于当前测试结果,不代表上游已经正式确认该问题已被修复。
11、最后
这次排查最大的价值,不是“又复现了一次 BKD merge 崩溃”,而是把一个看起来像 Easysearch 代码 bug 的现象,收敛成了一个有明确边界的运行时问题。
它至少说明两件事:
- 栈顶报错的位置不一定是真正的第一现场
- 真正有说服力的不是猜测,而是对照实验
这次结论之所以成立,不是因为主观判断,而是因为我们已经拿到了足够强的工程证据:同机 HotSpot 不复现,关闭 JVMCI 不复现,解释执行不复现,Elasticsearch 也复现,较新的 GraalVM 21.0.9+7.1 在当前测试中未复现,且某用户的 openEuler x86_64 测试环境也出现过同类错误。
所以,这一次,问题确实不在 Easysearch,而在特定版本的 JDK/JIT 运行时。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
【搜索客社区日报】第2214期 (2025-04-10)
社区日报 • Fred2000 发表了文章 • 0 个评论 • 10550 次浏览 • 2026-04-10 10:39
2026 春季招聘 | 春风十里,不如有你,别让才华埋没,来极限科技绽放光芒吧!
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12373 次浏览 • 2026-03-19 20:05
公司简介
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,在北京、上海、广州、长沙等城市设有研发中心,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
招聘信息
售前解决方案工程师(北京)
岗位职责:
1、深入分析客户业务场景与搜索需求,协助销售团队理解客户痛点,提供匹配的企业级搜索基础设施与整体架构建议 ;
2、负责公司产品与解决方案的售前技术支持,包括技术交流、方案编写、成本估算、产品演示及 PPT 制作与讲解 ;
3、协助销售进行客户需求调研、业务场景分析,提供基于分布式搜索引擎的技术方案与专业咨询 ;
4、参与客户培训与技术指导,提供现场售前技术支持,提升客户技术认知与产品信任度 ;
5、主导现场 POC,协调资源完成功能与非功能性测试,撰写测试报告并推动项目进展 ;
6、收集并反馈客户产品使用意见与需求,协助产品团队持续优化产品功能与用户体验 。
岗位要求:
1、全日制本科及以上学历,计算机、信息技术或相关专业优先 ;
2、3 年以上数据库、大数据或相关技术领域工作经验 ;
3、了解 Elasticsearch / Easysearch / OpenSearch 等搜索引擎,或熟悉至少一种主流数据库(如 MySQL、Oracle、MongoDB 等) ;
4、具备大型企业信息化项目经验,了解行业技术趋势、商业模式与主流 IT 服务商 ;
5、具备良好的沟通表达能力、应变能力,能独立与客户进行技术交流并精准把握需求 ;
6、具备客户需求深度挖掘与引导能力,能结合产品优势编写项目方案与技术建议书 ;
7、学习能力强,善于知识整合,具备良好的团队协作精神 。
加分项:
1、985 / 211 院校毕业优先 ;
2、拥有技术博客或在 AI、搜索、大数据、数据库等领域有内容输出经验 ;
3、持有 Elastic Certified Engineer(ECE)认证 ;
4、具备大规模搜索引擎集群设计、扩展与性能调优经验 ;
5、熟悉大数据相关技术栈,如 Kafka、Flink 等 ;
6、熟悉其他搜索引擎技术(如 Solr、Lucene)者优先 。
区域销售经理(北京)
岗位职责:
1、深耕 TO B 业务:专注于金融行业(特别是银行及证券)或央国企(特别是能源、大制造行业),建立并维护与该行业关键客户的良好关系,深入挖掘客户对企业搜索解决方案的需求 ;
2、攻坚克难,促成交易:面对复杂多变的销售环境,展现出强大的攻坚克难能力,有效应对客户异议,推动销售项目从初期接触到最终成交的全过程 ;
3、客户关系管理:建立并管理高价值的客户关系网络,通过定期的沟通、拜访及活动策划,增强客户粘性,促进长期合作 ;
4、解决方案设计与呈现:基于客户具体需求,结合公司产品与技术优势,设计并呈现定制化的解决方案,有效展现产品价值及实施效果 ;
5、技术学习与传递:快速学习并掌握最新的企业搜索、AI 搜索技术趋势、产品特性及竞争对手动态,能够准确、专业地向客户传达技术价值,提升客户信任度 ;
6、业绩达成与团队协作:确保达成公司设定的个人销售目标,同时与售前技术支支持、售后服务等部门紧密合作,确保项目顺利交付及客户满意度 。
岗位要求:
1、全日制本科及以上学历 ;
2、3 年以上 IT 解决方案或软件销售经验,具有 1 年以上金融或央国企相关行业销售背景 ;
3、面对挑战不退缩,能够积极寻找解决方案,推动项目进展直至成功 ;
4、了解所在行业业务流程及 IT 架构,能够快速学习并掌握新技术 ;
5、工作态度认真负责,勤奋敬业,能够承受一定的工作压力,确保任务按时按质完成 ;
6、良好的团队合作精神,能够与跨部门团队有效协作,共同达成目标 ;
7、销售提成额外签署补充协议 。
加分项:
1、计算机科学、信息技术或相关专业 ;
2、985 / 211 院校毕业优先 ;
3、了解开源行业及生态,理解相关技术及商业逻辑 ;
4、有数据库或大数据相关产品及解决方案销售经验 。
市场专员(北京)
岗位职责:
1、负责公司企业搜索、AI 搜索解决方案的技术生态运营工作,包括国内及全球市场 ;
2、负责市场活动策划,包括但不限于线上活动、线下活动、品牌合作等,提升品牌形象 ;
3、以技术角度,整合上下游合作伙伴资源,建立产品在市场上的知名度 ;
4、规划产品技术生态运营工作,包括自运营技术社区、展会合作、新媒体媒体投放等 ;
5、积极通过数字化体现运营价值,驱动产品知名度,配合一线最终实现销售业绩提升 ;
6、负责市场调研及相关情报搜集整理,同竞品的分析对比和信息搜集,根据市场反馈和数据,分析结果 ;
7、熟练使用 AI 工具做内容创作、 AI 作图、素材制作等,支持内容传播与活动落地 。
岗位要求:
1、市场运营或计算机科学、信息技术相关专业全日制本科或以上学历 ;
2、1-3 年以上科技产品公司市场运营经验 ;
3、具有良好的数据敏感度,善于从数据中发现问题点、机会点,具备良好的分析问题、解决问题的能力 ;
4、主导或参与过软件企业重大发布会、大型行业展会,或专题系列的技术巡展 ;
5、结果导向,执行力强,擅长跨部门协同,以获客转化为核心目标 。
加分项:
1、985 / 211 院校毕业优先 ;
2、有海外留学经验,英文阅读沟通能力强 ;
3、有数据分析基础,熟练使用 Python ;
4、有广告、AI 营销、IT 媒体或产业联盟工作经验优先 ;
5、熟悉使用 Office 办公软件,了解 PS、PR、剪映等设计软件者优先 ;
6、有在软件开发、数据库或大数据领域 维护运营博客或自媒体经验优先 。
客户成功经理(长沙)
岗位职责:
1、负责客户全生命周期的成功管理,包括 Onboarding、产品培训、日常维护、使用跟踪及定期回访,确保客户持续获得价值 ;
2、主动服务,发现那些客户需要帮助,提前介入,提供主动关怀,及时响应客户问题与需求,推动问题闭环解决 ;
3、筛选或发现优质客户,促进增购、续约购,给销售团队提供最佳信息 ;
4、技术学习与传递:快速学习并掌握最新的企业搜索、AI 搜索技术趋势、产品特性及竞争对手动态,能够准确、专业地向客户传达技术价值,提升客户信任度 ;
5、沟通与项目管理:协调内部资源(销售,售后服务,产品、开发等部门),提高客户满意度 ;
6、收集客户反馈与需求,输出产品优化建议,与产品团队紧密协作推动产品迭代 。
岗位要求:
1、全日制本科及以上学历,限 2026 年应届生 ;
2、快速学习能力,熟悉和理解行业客户的业务逻辑及IT架构(如金融、能源、制造业等) ;
3、具备一定的数据分析能力,通过客户使用数据预判需求或风险 ;
4、工作态度认真负责,勤奋敬业 ;
5、良好的团队合作精神,能够与跨部门团队有效协作,共同达成目标 。
加分项:
1、计算机科学、信息技术或相关专业 ;
2、985 / 211 院校毕业优先 ;
3、有过 数据库类或大数据类技术性工作经验 ;
4、熟悉 AI、搜索、大数据、数据库等相关行业知识 。
UI/交互设计实习生(长沙)
岗位职责:
1、负责产品界面与交互设计,优化用户体验 ;
2、支持运营活动视觉输出,熟练使用AI工具产出创意素材 ;
3、参与官网、海报等设计工作 ;
4、结合数据反馈优化设计,提升转化效果 ;
5、与产品、开发团队协作推进方案落地 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,视觉传达、人机交互、数字媒体艺术等相关专业优先 ;
2、关注设计趋势,学习能力强,能快速掌握新工具与方法 ;
3、具备较强的审美能力、逻辑思维能力、沟通表达能力以及对细节的极致追求 ;
4、应聘者请准备好自己的作品,请将作品集与简历一同发送 。
加分项:
1、有设计社区(Behance、Dribbble、站酷等)作品或运营经验 ;
2、有动效设计或动画制作经验 。
软件测试实习生(长沙)
岗位职责:
1、参与项目和日常产品需求分析,把控需求和系统分析质量和风险 ;
2、负责完成产品功能特性的测试设计以及测试用例的编写 ;
3、组织测试实施工作,跟进测试的进展和完成情况,记录测试结果并准备测试报告 ;
4、通过抓包或日志分析,能够对常见bug进行基本定位 ;
5、不断改进测试流程和方法,以提高质量和效率 ;
6、关注产品质量和客户需求,确保稳定、可靠和用户友好的软件交付 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,计算机以及相关专业 ;
2、熟悉软件测试基础理论、测试流程及常用测试方法 ;
3、良好的英文读写能力,能够有效的阅读和学习英文技术资料 ;
4、很强的自我驱动学习能力和技术钻研能力,具备优秀的沟通技巧,很好的责任心与高执行力 ;
5、能够承受压力,在快节奏的环境中高效工作 。
加分项:
1、熟悉 Go 或 Java 或 Python 编程语言,熟练 Linux,Git 常用命令 ;
2、熟悉 AI、搜索、大数据、数据库等相关行业知识 ;
3、熟悉 Easysearch / Elasticsearch / OpenSearch 等搜索引擎 。
内容运营实习生(长沙)
岗位职责:
1、负责社区内容的策划、文案、编辑,围绕团队成果产出技术解读文章,通过公众号、博客、社区等形式进行内容运营,提升公司的影响力 ;
2、支持市场营销中的内容输出,善于利用 AI 工具提供有吸引力的设计创意与素材 ;
3、参与其他新媒体相关工作,如视频号、小红书、抖音账号等内容创作和运营 ;
4、数据化运营,包括分析官网访问、下载等数据指标,根据数据反馈及时调整策略,提升运营效果 ;
5、定期与社区用户、媒体沟通,保持通畅的聆听反馈机制 ;
6、参与策划、组织及执行团队主办或承办的各类社区活动 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,新闻、营销、传媒、计算机等相关专业优先 ;
2、需要公众号运营、短视频运营相关工作经验;熟练掌握排版、拍摄、剪辑等各项能力 ;
3、具备较强的创意和策划能力、应变能力、语言和文字表达能力以及敏锐的市场触角 ;
4、对搜索技术、互联网产品及工具类信息怀有浓厚兴趣,具备快速学习并熟练掌握相关知识的能力,能够紧跟行业动态 。
加分项:
1、具有用户增长、数据分析、数据挖掘、信息检索经验者优先 ;
2、具有开源社区、开发者社区、开源媒体运营经验者优先 。
更多职位请访问 Boss 直聘
简历投递
- 邮件:hello@infini.ltd(邮件标题请备注姓名+求职岗位)
- 微信:INFINI-Labs (加微请备注求职岗位)

我们期待有才华、有激情的你加入我们,一起探索数据搜索的未来,共同创造无限可能!
INFINI Labs 产品更新 | Easysearch 2.1.0 新增高性能 Rules 规则引擎插件,数据探索 Discover 等
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9073 次浏览 • 2026-03-17 16:02

INFINI Easysearch v2.1.0 发布:新增 Rules 规则引擎(百万级规则、复杂表达式、自动同步恢复)与 形态学分析插件(俄语/英语词形还原,提升搜索召回率);审计日志支持动态用户审计,UI 新增日志查看、配置及数据探索页面,运维更高效。INFINI Console、Gateway、Agent、Loadgen v1.30.3 统一基于 Framework 升级,优化本地磁盘队列数据消费。详情见 Release Notes。
Easysearch v2.1.0
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
Easysearch 本次更新如下:
🚀 功能特性 (Features)
- 新增 Rules 规则引擎插件,提供高性能的规则匹配能力
- 支持 linux-x64 和 linux-aarch64 架构
- 支持 Ingest Pipeline 集成,数据写入时自动匹配规则并添加标签
- 支持复杂的规则表达式(AND/OR/NOT、near、正则、数值范围等)
- 支持百万级规则库,匹配性能是传统方案的上百倍。
- 支持多节点集群自动同步和广播编译规则
- 节点启动时自动同步缺失的规则库
- 规则库同步期间自动保护写入,确保规则完整性
- 本地元数据文件持久化记录编译历史,支持规则库文件丢失后的自动恢复
- 新增形态学分析插件(analysis-morphology),支持俄语和英语的形态分析
- 精准还原:基于词典将动词时态、名词格位等还原为标准原型(如 went → go)
- 词元扩展:同时索引原词与关联词根(如runner → runner, run),实现智能搜索匹配
- 高召回率:解决俄语复杂的变格与变位搜索难题,确保不同语法形式下均能精准检索
- 审计日志新增动态指定用户进行审计的功能
-
UI 插件新增如下能力
- 支持审计日志在线查看
- 支持审计日志模块动态配置
- 新增数据探索页面


✈️ 改进优化 (Improvements)
- 将“结巴”分词插件日志迁移至 Log4J,并降低周期性任务的日志级别以减少冗余
🐛 问题修复(Bug Fixes)
- 修复少量 UI 界面操作问题

Console v1.30.3
INFINI Console 是一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台。通过对流行的搜索引擎基础设施进行跨版本、多集群的集中纳管,企业可以快速方便的统一管理企业内部的不同版本的多套搜索集群。
Console 本次详细更新记录如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Console 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Console 受益。
🐛 问题修复(Bug Fixes)
- 修复 Agent 关联不成功问题
Gateway v1.30.3
INFINI Gateway 是一个开源的面向搜索场景的高性能数据网关,所有请求都经过网关处理后再转发到后端的搜索业务集群。基于 INFINI Gateway 可以实现索引级别的限速限流、常见查询的缓存加速、查询请求的审计、查询结果的动态修改等等。
Gateway 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Gateway 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Gateway 受益。
Agent v1.30.3
INFINI Agent 负责采集和上传 Elasticsearch, Easysearch, Opensearch 集群的日志和指标信息,通过 INFINI Console 管理,支持主流操作系统和平台,安装包轻量且无任何外部依赖,可以快速方便地安装。
Agent 本次更新如下:
🚀 功能特性 (Features)
- 在 Kubernetes 环境下通过环境变量 http.port 探测 Easysearch 的 HTTP 端口
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Agent 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Agent 受益。
Loadgen v1.30.3
INFINI Loadgen 是一款开源的专为 Easysearch、Elasticsearch、OpenSearch 设计的轻量级性能测试工具。
Loadgen 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Loadgen 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Loadgen 受益。
更多详情请查看以下各产品的 Release Notes 或联系我们的技术支持团队!
- Coco AI App
- Coco AI Server
- INFINI Easysearch
- INFINI Gateway
- INFINI Console
- INFINI Agent
- INFINI Loadgen
- INFINI Framework
期待反馈
欢迎下载体验使用,如果您在使用过程中遇到如何疑问或者问题,欢迎前往 INFINI Labs Github(https://github.com/infinilabs) 中的对应项目中提交 Feature Request 或提交 Bug。
下载地址: https://infinilabs.cn/download
邮件:hello@infini.ltd
电话:(+86) 400-139-9200
Discord:https://discord.gg/4tKTMkkvVX
也欢迎大家微信扫码添加小助手(INFINI-Labs),加入用户群一起讨论交流。

关于极限科技(INFINI Labs)

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
Easysearch ZSTD 基准测试:高压缩率下实现近 5 倍查询吞吐
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 4698 次浏览 • 2026-03-17 12:41
在搜索引擎领域,压缩算法的选择一直是一个经典的权衡难题:
- 选择高压缩率(如
best_compression/ DEFLATE),磁盘省了,但查询解压慢; - 选择高速编码(如默认 LZ4),查询快了,但磁盘占用大。
Easysearch 引入了基于 JDK 21 FFM(Foreign Function & Memory API) 直连本地 ZSTD 动态库的加速方案,试图打破这一困局。为了验证效果,我们在完全对等的环境下,对 Easysearch(ZSTD)和 Elasticsearch 7.10.2(best_compression)进行了一次严格的查询吞吐对比测试。
结果令人振奋——即使在系统明显背景负载下,Easysearch 也没有因为高压缩而变慢,反而在查询吞吐上实现了近 5 倍提升。
测试环境
为确保对比公平,两套集群的硬件资源、JVM 配置、数据规模、索引结构完全对齐:
| 配置项 | Easysearch | Elasticsearch 7.10.2 |
|---|---|---|
| 节点数 | 3 | 3 |
| JVM 堆内存 | 12GB × 3 | 12GB × 3 |
| node.processors | 16 × 3 | 16 × 3 |
| 文档数 | 10,000,000 | 10,000,000 |
| 主分片 / 副本 | 3 / 0 | 3 / 0 |
| 数据类型 | nginx 访问日志 | nginx 访问日志 |
| 字段数 | 17 | 17 |
| mapping | 完全一致(MD5 校验) | 完全一致(MD5 校验) |
| Stored fields 压缩模式 | ZSTD (JDK21 FFM/native, level=3) | best_compression (DEFLATE) |
压缩机制对比:
best_compression映射到 LuceneBEST_COMPRESSION;在 stored fields 路径上,压缩实现为DeflateWithPresetDictCompressionMode,内部使用java.util.zip.Deflater/Inflater(即 DEFLATE)。 Easysearch ZSTD 当前走 JDK 21 FFM 绑定本地 zstd 库(java.lang.foreign);index.compression.zstd.jni=true为当前这套实现的启用方式。
查询模型:JMeter 随机 match 查询,随机命中 service_name、method、error_code、url 四个字段,每次返回 10 条文档。
压测起始负载(_cat/nodes 快照):
| 负载项 | Easysearch run | Elasticsearch run |
|---|---|---|
| load_1m | 29.74 | 25.27 |
| load_5m | 27.10 | 28.15 |
| load_15m | 26.09 | 36.96 |
| ram.percent | 99 | 99 |
说明:压测并非在空闲机上进行,而是在已有明显背景负载的生产式环境下完成。
核心结果
1. 查询吞吐量(QPS):在高背景负载下,Easysearch 仍领先 372%
稳态阶段(3 轮平均),Easysearch 的查询吞吐是 Elasticsearch 的 4.7 倍:
| 指标 | Elasticsearch (DEFLATE) | Easysearch (ZSTD) | 差异 |
|---|---|---|---|
| 稳态 QPS | 532.8 | 2,518.0 | +372.6% |
| 平均响应时间 | 779.0 ms | 164.3 ms | -78.9% |
| 稳态 CPU 占用(系统总占用) | 92.43% | 89.59% | 仅作背景参考 |
注:压测期间服务器存在明显背景负载(其他进程占用较高),该 CPU 指标是系统总占用,不等价于“仅搜索进程”的纯业务 CPU 对比。
在系统总 CPU 均接近 90% 的背景下,Easysearch 仍达到接近 5 倍吞吐。
查询吞吐量 QPS 对比(稳态均值)
2. 响应时间:从近 1 秒降到 164 毫秒
平均响应时间对比(ms,越低越好)
用户体感上,这意味着:同样一个搜索请求,Elasticsearch 还在等解压,Easysearch 已经把结果送到了客户端。
3. 各轮次详细数据
各轮次 QPS 趋势
各轮次平均响应时间趋势(ms)
4. CPU 使用效率:每 1% CPU 产出的 QPS 差距惊人
单看 CPU 占用率,两者似乎差不多(89.59% vs 92.43%)。但如果换一个视角——每消耗 1% CPU 能产出多少 QPS,差距就一目了然了:
| 指标 | Elasticsearch (DEFLATE) | Easysearch (ZSTD) | 倍数 |
|---|---|---|---|
| 稳态 QPS | 532.8 | 2,518.0 | — |
| 稳态 CPU | 92.43% | 89.59% | — |
| QPS / 1% CPU | 5.76 | 28.10 | 4.88× |
CPU 使用效率:每 1% CPU 产出的 QPS
这意味着什么?
- ES 使用 DEFLATE(best_compression)时,解压路径更可能成为 CPU 热点;结合 ES 的高 CPU(92.43%)与较低 QPS,说明单位 CPU 产出偏低;
- Easysearch 使用 ZSTD(JDK21 FFM/native)时,解压开销更小;在相近 CPU 水位(89.59%)下获得更高 QPS,单位 CPU 产出明显更高。
换句话说,当前这组实测更支持“ZSTD 在该查询模型下单位 CPU 产出更高”。
5. 存储空间:ZSTD 并未膨胀
| 索引 | 压缩算法 | 磁盘占用 |
|---|---|---|
| nginx_best_10m (ES) | best_compression (DEFLATE) | 1.8 GB |
| nginx_zstd3 (Easysearch) | ZSTD (level=3, JDK21 FFM/native) | 1.9 GB |
两者存储空间接近。若按 _cat/indices 的 1 位小数展示是 1.8GB vs 1.9GB;若按 _stats/store 字节值计算,差异约 2.5%。因此可以认为 ZSTD 在 level=3 下与 DEFLATE best_compression 压缩率接近。
磁盘占用对比(GB)
为什么 ZSTD 能做到"又小又快"?
传统认知中,压缩率和解压速度是一对矛盾。但 ZSTD 算法天然具备非对称压缩的特性:
压缩算法特性对比
在搜索引擎场景中,查询会触发存储字段(_source)读取与解压路径,命中文件系统页缓存时,可能不发生实际磁盘 I/O,但仍需进行 _source 解压。
当查询涉及较多 _source 读取时:
- DEFLATE 的解压开销成为 CPU 瓶颈,拖慢了整体吞吐;
- ZSTD(JDK21 FFM/native) 的解压速度在该场景下明显更优,单次请求的解压 CPU 成本更低,从而释放出更多 CPU 资源用于并发查询处理。
这就是为什么 Easysearch 在 CPU 占用更低(89.59% vs 92.43%)的情况下,反而能处理近 5 倍的查询量。
一张图总结
Easysearch ZSTD vs Elasticsearch DEFLATE — 全维度对比
结论
Easysearch 的 ZSTD 压缩方案证明了一个事实:即使在高背景负载下,高压缩率和高查询性能依然可以兼得。
在 1000 万条 nginx 日志、且系统存在明显背景负载的实测中:
- 查询吞吐提升 372%,从 533 QPS 跃升至 2518 QPS
- 平均响应时间下降 79%,从 779ms 降至 164ms
- CPU 使用效率提升 388%,每 1% CPU 产出 28.10 QPS vs 5.76 QPS
- CPU 占用绝对值下降 2.84 个百分点(相对下降约 3.07%)
- 磁盘占用与 DEFLATE best_compression 接近(按字节口径约 +2.5%)
对于日志分析、可观测性、安全审计等需要兼顾存储成本和查询性能的场景,Easysearch ZSTD 是一个不需要妥协的选择。
ZSTD 使用方法
1) 新建索引时启用 ZSTD
curl -k -u 'admin:<password>' -X PUT 'https://127.0.0.1:9200/<index-name>' \
-H 'Content-Type: application/json' -d '{
"settings": {
"index.codec": "ZSTD",
"index.compression.zstd.jni": true
}
}'
可选参数:
index.compression.zstd.level(默认3)
说明:
index.compression.zstd.dict固定为true,无需单独配置index.compression.zstd.dict不作为独立开关来调整
2) 老索引切换到 ZSTD(推荐 reindex)
index.codec 是静态设置(打开状态不可动态改;可在关闭索引后调整)。
index.compression.zstd.jni 是 final 设置(关闭索引后也不可修改)。
如果老索引要启用 index.compression.zstd.jni=true,建议新建目标索引后 reindex 迁移:
如果对已有索引执行 PUT /<index-name>/_settings 直接修改,会报错:final <index-name> setting [index.compression.zstd.jni], not updateable。
# 先创建目标索引(启用 ZSTD)
curl -k -u 'admin:<password>' -X PUT 'https://127.0.0.1:9200/<target-index>' \
-H 'Content-Type: application/json' -d '{
"settings": {
"index.codec": "ZSTD",
"index.compression.zstd.jni": true
}
}'
# 再迁移数据
curl -k -u 'admin:<password>' -X POST 'https://127.0.0.1:9200/_reindex' \
-H 'Content-Type: application/json' -d '{
"source": { "index": "<source-index>" },
"dest": { "index": "<target-index>" }
}'
3) 校验是否生效
curl -k -u 'admin:<password>' \
'https://127.0.0.1:9200/<index-name>/_settings?include_defaults=true&pretty'
重点确认:
index.codec = ZSTDindex.compression.zstd.jni = true
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
【搜索客社区日报】第2193期 (2026-03-06)
社区日报 • Fred2000 发表了文章 • 0 个评论 • 3036 次浏览 • 2026-03-06 10:28
极限科技荣膺 2025 金猿奖 — “年度国产化优秀代表厂商”,自主可控搜索方案 Easysearch 获行业高度认可
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 24813 次浏览 • 2026-01-16 17:41
近日于上海明捷万丽酒店成功举办的 “2025 第八届金猿大数据产业发展论坛 — 暨 AI Infra & Data Agent 趋势论坛” 大会上,极限数据(北京)科技有限公司(以下简称“极限科技”) 凭借其在分布式搜索型数据库领域的技术突破与卓越的国产化实践,成功入选《2025 中国大数据产业「年度国产化优秀代表厂商」》榜单,并获颁这一行业重磅奖项。

本届论坛由金猿组委会、数据猿、上海市数商协会及上海大数据联盟联合主办,以“数据有猿·智见十年”为主题,吸引了近千家企业参与申报。经过严格的初审、公审与终审交叉验证机制,极限科技最终从众多竞争者中脱颖而出,荣登榜单。

深耕核心搜索技术,填补国产化空白
极限科技成立于 2021 年 12 月,是一家专注于大数据搜索与分析的基础软件公司。公司总部位于北京,在长沙设立研发中心,并在上海、广州设立办事处或服务中心。其核心团队均来自 Elasticsearch 原厂及中文社区,拥有多年 ES 源码开发经验,致力于“让搜索更简单”,打造极致易用的数据探索与分析体验。
公司自主研发的核心产品 Easysearch 搜索型数据库,是我国在分布式搜索型数据库领域实现关键国产化替代的代表性成果。该产品精准填补了国内在轻量化、高性能、自主可控搜索引擎方面的市场空白。
产品性能卓越,实现无缝迁移与超越
Easysearch 支持结构化与非结构化数据检索、全文检索、向量检索、空间地理位置信息检索、多模态混合检索、组合查询、多语种支持、语义分析、聚合分析等多种核心功能。测试表明,其性能已达到甚至优于国外领先产品。
在产品能力上,Easysearch 不仅完全兼容 Elasticsearch 的生态接口,保障了用户业务的无缝平滑迁移,更在性能优化、存储效率、企业级安全及原生中文处理等方面实现了显著超越。其内置的 Web 管理控制台、全面的数据加密与权限管控功能,提供了开箱即用的企业级体验。
构建完整信创生态
尤为关键的是,Easysearch 率先完成了与国产主流 CPU(如鲲鹏、飞腾、海光、龙芯、申威、兆芯等)和操作系统(如统信 UOS、银河麒麟、开源欧拉等)的深度适配与互认证,构建了完整的信创技术栈支持能力,彻底解决了国外产品在国产化环境下兼容性差、维护困难、更新受限等长期存在的痛点。
在核心技术国产化意义上,Easysearch 通过完全自主可控的分布式搜索技术体系,突破了关键基础软件依赖国外企业的局面,满足了政府、金融、能源、运营商等行业对“可控、安全、可替代”的战略需求。同时,其向量搜索和 AI 检索能力填补了国内在智能搜索与大模型结合领域的技术缺口。
获权威资质认可,落地众多头部客户
极限科技及 Easysearch 已获得多项权威资质认证,包括国家高新技术企业、ISO 三大管理体系认证,并荣获 2023 年星河案例数据库标杆案例。产品亦通过了信通院基础能力专项测评及中国泰尔实验室检验测试。
目前,Easysearch 已在金融、运营商、制造、政企等多领域实现规模化落地,服务客户包括移动云、中国一汽、中国人保、东莞证券、航天信息等头部企业,累计下载部署量已超过 500 万次。其中,公司开发的中文分词器(IK、Pinyin)、压测工具(Loadgen)、数据迁移工具(ESM)已被 85% 的中国 Elasticsearch 用户部署在生产环境中。
荣获行业大奖,彰显标杆价值
此次荣获 “年度国产化优秀代表厂商” 奖项,不仅是行业对极限科技技术实力与国产化贡献的高度认可,更彰显了公司在推动大数据产业自主创新进程中的标杆作用。
极限科技创始人表示:
“我们坚信‘追求极致,无限可能’。获得这份荣誉,是对我们团队多年来坚持自主创新、深耕搜索技术的最好鼓励。未来,极限科技将持续加大研发投入,以技术创新驱动产业升级,为各行业客户提供更高效、更安全、更智能的数据探索与分析能力,助力中国大数据产业在智能时代实现高质量、自主可控的发展。”
相关链接:
APM(二):监控 Python 服务
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 15687 次浏览 • 2025-12-31 18:04
上一篇我们已经安装好了 Skywalking 和 Easysearch,这次我们来写个简单的 Python 服务,并把它的服务调用信息发送给 Skywalking,通过 Skywalking 的 Web UI 进行展示。
启动后端服务
先启动好后端服务,包括 Skywalking 和 Easysearch。启动完成后能通过 Web UI 访问 Skywalking。

构建 Python 服务
我们编写一个简单的 Flask 服务程序,只要访问 localhost:8081/a 就会返回 "Hello, I'm Service A!" 信息。
from flask import Flask
app = Flask(__name__)
@app.route('/a', methods=['GET'])
def service_b():
return "Hello, I'm Service A!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8081)
运行前,要安装好依赖。
pip3 install flask
pip3 install apache-skywalking
依赖关系展示如下:

设置环境变量
为了让服务能成功把相关信息发送到 Skywalking 后端,启动前我们还要设置两个环境变量告诉服务程序该往哪里发送信息。
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800
export SW_AGENT_NAME=AService-python
启动 Python 程序
一切准备妥当后,运行我们的服务程序。
sw-python run python3 AService.py
程序启动后会监听 8081 端口。

我们通过浏览器访问下。

在 Skywalking 的 Web UI 上查看服务的信息是否采集到。




可以看到服务 A 的调用信息都已经被记录到 Skywalking 中了。
作者:杨帆,极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。
INFINI Labs 产品更新 | Coco AI v0.10 × Easysearch v2.0 联袂上线:UI 全面重构,体验焕然一新
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12080 次浏览 • 2025-12-20 16:34

此次更新主要包括 Coco AI v0.10.0 更换全新的 UI 组件,服务端新增 milvus 和 dropbox 连接器;Easysearch v2.0.2 正式发布, 新增嵌入文档语义搜索,优化内置 UI 响应速度,无需依赖 Kibana,实现集群“开箱即管”;INFINI Console、Gateway、Agent、Loadgen v1.30.1 统一基于 Framework v1.4.0 升级,优化本地磁盘队列数据消费。详情见 Release Notes。
Coco AI 0.10
Coco AI 是一款完全开源、跨平台的企业级智能搜索与助手系统,专为现代企业打造。它通过统一搜索入口,连接企业内外部的异构数据源,融合大模型能力,帮助团队高效访问知识,智能决策协作。
Coco AI 本次详细更新记录如下:
Coco AI 客户端 0.10
🚀 功能特性 (Features)
- 扩展程序 UI 支持可调整窗口大小

- 添加打开按钮以启动已安装的扩展程序

✈️ 改进优化 (Improvements)
- 将应用程序和文件搜索视为普通扩展
- 通过深度链接安装扩展失败时,显示错误消息(而非错误代码)
- 用 shadcn/ui 组件替换旧组件

🐛 问题修复(Bug Fixes)
- 修复输入框高度异常问题
- 为 Extension.minimum_coco_version 实现自定义序列化
Coco AI 服务端 0.10
🚀 功能特性 (Features)
- 新增 milvus 连接器

- 新增 dropbox 连接器

🐛 问题修复(Bug Fixes)
- 修复搜索 API 中图标绝对 URL 的解析问题
- 修复集成商店读取剪贴板数据后的显示问题
✈️ 改进优化 (Improvements)
- 移除分页并在全屏模式下添加无限滚动
Easysearch v2.0.2
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
Easysearch 本次更新如下:
💥 重大变更(Breaking Changes)
- 正式发布 Easysearch 2.0.2 版本,底层 Lucene 更新到 9.12.2
- 新增 ui 插件,为 Easysearch 提供了轻量级界面化管理功能,不再依赖第三方对集群进行管理,真正做到开箱即用
🚀 功能特性 (Features)
- 语义搜索新增支持 NestedQueryBuilder
- KNN mapping 的 L 和 k 参数支持大小写不敏感,提升易用性
✈️ 改进优化 (Improvements)
- UI 插件静态文件支持 gzip 压缩,加快页面加载
- 优化了图标资源大小
- 调整了内部构建流程和 CSP 策略
🐛 问题修复(Bug Fixes)
- 修复了开发者工具的主题颜色显示问题
Console v1.30.1
INFINI Console 是一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台。通过对流行的搜索引擎基础设施进行跨版本、多集群的集中纳管,企业可以快速方便的统一管理企业内部的不同版本的多套搜索集群。
Console 本次详细更新记录如下:
🚀 功能特性 (Features)
- 支持 Easysearch 2.x 和 Opensearch 3.x
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Console 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Console 受益。
Gateway v1.30.1
INFINI Gateway 是一个开源的面向搜索场景的高性能数据网关,所有请求都经过网关处理后再转发到后端的搜索业务集群。基于 INFINI Gateway 可以实现索引级别的限速限流、常见查询的缓存加速、查询请求的审计、查询结果的动态修改等等。
Gateway 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Gateway 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Gateway 受益。
Agent v1.30.1
INFINI Agent 负责采集和上传 Elasticsearch, Easysearch, Opensearch 集群的日志和指标信息,通过 INFINI Console 管理,支持主流操作系统和平台,安装包轻量且无任何外部依赖,可以快速方便地安装。
Agent 本次更新如下:
🚀 功能特性 (Features)
- 在 Kubernetes 环境下通过环境变量 http.port 探测 Easysearch 的 HTTP 端口
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Agent 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Agent 受益。
Loadgen v1.30.1
INFINI Loadgen 是一款开源的专为 Easysearch、Elasticsearch、OpenSearch 设计的轻量级性能测试工具。
Loadgen 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Loadgen 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Loadgen 受益。
Framework 1.4.0
INFINI Framework 是 INFINI Labs 基于 Golang 的产品的核心基础,已开源。该框架以开发者为中心设计,简化了构建高性能、可扩展且可靠的应用程序的过程。
Framework 本次更新如下:
🚀 功能特性 (Features)
- 为 curl 添加 p12 证书支持(#239)
- 从 util 中移除 curl(#242)
- 优先使用集群名称(#243)
- 为 access_token 添加标签(#244)
- 为用户主体(principal)添加头像配置(#246)
🐛 问题修复 (Bug Fixes)
- 修复重复写入和未写入的问题(#234)
- 当 filePath 为绝对路径时,检查其是否存在(#241)
✈️ 改进 (Improvements)
- 改进 TryGetFileAbsPath() 的 panic 错误信息(#240)
更多详情请查看以下各产品的 Release Notes 或联系我们的技术支持团队!
- Coco AI App
- Coco AI Server
- INFINI Easysearch
- INFINI Gateway
- INFINI Console
- INFINI Agent
- INFINI Loadgen
- INFINI Framework
期待反馈
欢迎下载体验使用,如果您在使用过程中遇到如何疑问或者问题,欢迎前往 INFINI Labs Github(https://github.com/infinilabs) 中的对应项目中提交 Feature Request 或提交 Bug。
下载地址: https://infinilabs.cn/download
邮件:hello@infini.ltd
电话:(+86) 400-139-9200
Discord:https://discord.gg/4tKTMkkvVX
也欢迎大家微信扫码添加小助手(INFINI-Labs),加入用户群一起讨论交流。

关于极限科技(INFINI Labs)

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
Easy-Es 2.1.0-easysearch 版本发布
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9365 次浏览 • 2025-12-15 17:42

01 | 版本更新概述
经过极限科技与 Dromara 开源社区下 Easy-Es 项目的紧密合作与共同努力,我们很荣幸地联合推出 Easy-Es 2.1.0-easysearch 版本!
作为双方携手打造的第一个合作成果,本版本已正式发布:
- 源码仓库:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch/
- Maven 依赖:https://mvnrepository.com/artifact/org.dromara.easy-es/easy-es-boot-starter/2.1.0-easysearch
本次更新的核心内容是将 Easy-Es 框架底层增加兼容极限科技自主研发的 Easysearch 搜索引擎,这标志着国产搜索引擎与国内优秀开源项目深度融合的重要里程碑,是极限科技与 Dromara 社区携手共建国产技术生态的创新实践。
02 | 迁移至 Easysearch 的背景与优势
随着国内对自主可控技术需求的日益增长,特别是在基础设施软件领域,企业对于信创合规的要求不断提升。极限科技自主研发的 Easysearch 搜索引擎具备以下显著优势:
- 国产化自主可控:完全自主研发,符合信创要求,无许可证风险,为企业提供安全可靠的技术保障
- 轻量级架构:相比传统搜索引擎,资源占用更少,启动更快速,显著降低企业运维成本
- 卓越性能表现:查询性能优异,能够满足大部分业务场景需求,用户体验流畅
- 良好兼容性:与 Elasticsearch 的 API 接口基本兼容,迁移成本较低,保护用户现有投资
基于以上优势,双方决定共同将 Easy-Es 框架底层迁移至 Easysearch,这不仅为用户提供更多选择,更是双方携手推动国产搜索引擎生态建设的重要举措。
03 | Easy-Es 框架优势
Easy-Es 框架在搜索开发领域具备以下核心优势:
- 极简代码开发:相比原生 API 可减少 50%-80% 的代码量,大幅提升开发效率。
// 使用 Easy-Es 仅需一行代码完成查询
List<Document> documents = documentMapper.selectList(
EsWrappers.lambdaQuery(Document.class).eq(Document::getTitle, "测试")
);
-
自动索引管理: 框架提供全自动智能索引托管功能,开发者无需关心索引的创建、更新及数据迁移等复杂操作,索引全生命周期由框架自动管理,过程零停机。
-
SQL 语法兼容: 支持使用 MySQL 语法完成搜索查询操作,无需学习复杂的 DSL 语句。支持 and、or、like、in 等常用 SQL 语法。
-
Lambda 表达式支持: 采用 Lambda 风格编程,提供类型安全的字段访问,避免手动输入字段名可能产生的错误,提升代码可读性和开发效率。
-
无缝 Spring Boot 集成: 与 Spring Boot 生态深度集成,提供开箱即用的自动配置,无需复杂的手动配置,支持 Spring Boot Actuator 监控,完美融入企业级应用架构。
-
丰富的查询功能: 支持复杂的嵌套查询、聚合查询、范围查询、高亮显示等高级搜索功能,同时保持 API 的简洁易用,满足各种业务场景需求。
-
分布式架构支持: 完美适配 Easysearch 的分布式特性,支持集群模式部署,具备高可用性和横向扩展能力,满足企业级大规模数据处理需求。
- 成熟稳定的国产 ORM 框架: 作为 Dromara 开源社区下的顶级开源项目,Easy-Es 已在国内众多企业和项目中得到广泛应用和验证,拥有活跃的中文社区和完善的文档支持,为企业级应用提供了可靠的技术保障。
04 | 快速上手示例
1. 添加依赖
根据您使用的构建工具,选择对应的配置方式:
Maven 项目
pom.xml 配置:
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring-boot.version>2.7.0</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.dromara.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>2.1.0-easysearch</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven 启动命令:
# 运行应用
mvn spring-boot:run
# 编译打包
mvn clean package
Gradle 项目
build.gradle 配置:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
group = 'org.easysearch'
version = '1.0-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.dromara.easy-es:easy-es-boot-starter:2.1.0-easysearch'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
Gradle 启动命令:
# 运行应用
./gradlew bootRun
# 编译打包
./gradlew clean build
2. 配置文件设置
application.yml(根据实际 Easysearch 部署情况修改):
easy-es:
enable: true
# Easysearch 服务地址
address: localhost:9200
# 协议:http 或 https
schema: https
# Easysearch 用户名
username: admin
# Easysearch 密码
password: your_password_here
# 连接保持时间(毫秒)
keep-alive-millis: 18000
global-config:
# 开启彩蛋模式(启动时显示 ASCII 艺术图案)
i-kun-mode: true
# 索引处理模式:smoothly 表示平滑模式(零停机更新索引)
process-index-mode: smoothly
# 异步处理索引时是否阻塞
async-process-index-blocking: true
# 是否打印 DSL 语句(开发调试时可设为 true)
print-dsl: false
db-config:
# 下划线转驼峰
map-underscore-to-camel-case: true
# 索引前缀
index-prefix: dev_
# 主键类型:customize 表示自定义
id-type: customize
# 字段更新策略:not_empty 表示非空时才更新
field-strategy: not_empty
# 刷新策略:immediate 表示立即刷新
refresh-policy: immediate
# 开启追踪总命中数
enable-track-total-hits: true
3. 实体类定义
package org.dromara.easyes.sample.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.HighLight;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexId;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.annotation.Settings;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldStrategy;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.annotation.rely.IdType;
import java.time.LocalDateTime;
/**
* es 数据模型
*/
@Data
@Accessors(chain = true)
@Settings(shardsNum = 3, replicasNum = 2)
@IndexName(value = "easyes_document", keepGlobalPrefix = true)
public class Document {
/**
* es 中的唯一 id
*/
@IndexId(type = IdType.CUSTOMIZE)
private String id;
/**
* 文档标题,默认为 keyword 类型,可进行精确查询
*/
private String title;
/**
* 文档内容,指定为 TEXT 类型,使用 IK 分词器
* 支持高亮显示,高亮结果映射到 highlightContent 字段
*/
@HighLight(mappingField = "highlightContent")
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART)
private String content;
/**
* 创建者,字段策略为非空时才更新
*/
@IndexField(strategy = FieldStrategy.NOT_EMPTY)
private String creator;
/**
* 创建时间
*/
@IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime gmtCreate;
/**
* 高亮返回值被映射的字段
*/
private String highlightContent;
/**
* 文档点赞数
*/
private Integer starNum;
/**
* 地理位置经纬度坐标,例如: "40.13933715136454,116.63441990026217"
*/
@IndexField(fieldType = FieldType.GEO_POINT)
private String location;
}
4. Mapper 接口
package org.dromara.easyes.sample.mapper;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.sample.entity.Document;
/**
* Mapper 接口,继承 BaseEsMapper 即可获得所有 CRUD 方法
*/
public interface DocumentMapper extends BaseEsMapper<Document> {
}
5. 启动类配置
package org.dromara.easyes.sample;
import org.dromara.easyes.spring.annotation.EsMapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*/
@SpringBootApplication
@EsMapperScan("org.dromara.easyes.sample.mapper")
public class EasyEsApplication {
public static void main(String[] args) {
SpringApplication.run(EasyEsApplication.class, args);
}
}
6. 业务使用示例
package org.dromara.easyes.sample.controller;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.sample.entity.Document;
import org.dromara.easyes.sample.mapper.DocumentMapper;
import org.easysearch.action.search.SearchResponse;
import org.easysearch.search.aggregations.Aggregations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@RestController
public class SampleController {
@Resource
private DocumentMapper documentMapper;
/**
* 初始化插入数据
*/
@GetMapping("/insert")
public Integer insert() {
int count = 0;
// 插入 5 条测试数据
for (int i = 1; i <= 5; i++) {
Document document = new Document();
document.setId(String.valueOf(i));
document.setTitle("测试" + i);
document.setContent("测试内容" + i);
document.setCreator("创建者" + i);
document.setGmtCreate(LocalDateTime.now());
document.setStarNum(i * 10);
count += documentMapper.insert(document);
}
return count;
}
/**
* 根据标题精确查询
*/
@GetMapping("/listDocumentByTitle")
public List<Document> listDocumentByTitle(@RequestParam String title) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, title);
return documentMapper.selectList(wrapper);
}
/**
* 高亮搜索
*/
@GetMapping("/highlightSearch")
public List<Document> highlightSearch(@RequestParam String content) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getContent, content);
return documentMapper.selectList(wrapper);
}
/**
* 查询所有数据
*/
@GetMapping("/selectAll")
public List<Document> selectAll() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
return documentMapper.selectList(wrapper);
}
/**
* 聚合查询 - 按创建时间和点赞数分组统计
*/
@GetMapping("/aggByDateAndStar")
public Aggregations aggByDateAndStar() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.groupBy(Document::getGmtCreate)
.max(Document::getStarNum)
.min(Document::getStarNum);
SearchResponse response = documentMapper.search(wrapper);
return response.getAggregations();
}
/**
* 使用 SQL 语句查询文档
*/
@GetMapping("/queryBySQL")
public String queryBySQL(@RequestParam(required = false) String title) {
String sql;
if (title != null && !title.isEmpty()) {
sql = String.format("SELECT * FROM dev_easyes_document WHERE title = '%s'", title);
} else {
sql = "SELECT * FROM dev_easyes_document LIMIT 10";
}
return documentMapper.executeSQL(sql);
}
}
7. 快速测试
启动应用后,可以通过以下接口测试:
# 1. 插入测试数据
curl http://localhost:8080/insert
# 2. 查询所有数据
curl http://localhost:8080/selectAll
# 3. 根据标题精确查询
curl "http://localhost:8080/listDocumentByTitle?title=测试1"
# 4. 高亮搜索
curl "http://localhost:8080/highlightSearch?content=测试"
# 5. SQL 查询
curl "http://localhost:8080/queryBySQL?title=测试1"
# 6. 聚合查询
curl http://localhost:8080/aggByDateAndStar
05 | 相关链接
- Easy-Es 官方网站:https://easy-es.cn
- Gitee 仓库:https://gitee.com/dromara/easy-es
- GitHub 仓库:https://github.com/dromara/easy-es
- Easysearch 官方网站:https://infinilabs.cn/products/easysearch
06 | 特别致谢
在此,极限科技要特别感谢 Easy-Es 项目的核心开发者“老汉”和各位贡献者和维护者们。正是因为有了你们的辛勤付出、专业精神以及对开源事业的热忱奉献,Easy-Es 项目才能在国内外获得如此广泛的认可和应用。
也感谢你们对国产技术生态建设的信任与支持。此次 Easy-Es 与 Easysearch 的深度整合,正是双方通力合作、互利共赢的最佳体现。
我们相信,在 Easy-Es 项目团队的持续推动下,国产开源软件必将迎来更加辉煌的明天。极限科技将继续致力于提供优质的国产技术解决方案,与 Easy-Es 项目团队携手共进,为中国开源生态的发展贡献更多力量!
关于 Easy-Es
Easy-Es(简称 EE)是一款基于 Elasticsearch(简称 ES)官方提供的 ElasticsearchClient 打造的 ORM 开发框架,在 ElasticsearchClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过 Mybatis-Plus(简称 MP),那么您基本可以零学习成本直接上手 EE,EE 是 MP 的 ES 平替版,在有些方面甚至比 MP 更简单,同时也融入了更多 ES 独有的功能,助力您快速实现各种场景的开发。
Easy-Es for Easysearch 是一款简化 Easysearch 国产化搜索引擎操作的开源框架,全自动智能索引托管。同时也是国内首家专门针对 Easysearch 客户端简化的工具。它简化 CRUD 及其它高阶操作,可以更好的帮助开发者减轻开发负担。底层采用 Easysearch Java Client,保证其原生性能及拓展性。
项目地址:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch
关于极限科技
极限科技(全称:极限数据(北京)科技有限公司)是一家专注于实时搜索与数据分析的软件公司。
旗下品牌:极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验,为用户提供安全、稳定、高性能的国产搜索解决方案。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
Easysearch 2.0.0 性能测试
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9326 次浏览 • 2025-12-04 00:17
概述
Easysearch 2.0.0 正式版带来了显著的性能提升和优化改进。通过与上一个稳定版本 1.15.6 的全面对比测试,我们使用 esrally 基准测试工具在 append-no-conflicts 场景下进行了深入的性能评估。测试结果表明,2.0.0 版本在索引性能、查询延迟、内存管理等核心指标上都实现了突破性改进。
核心性能提升
1. 索引性能更加稳定
写入效率提升 12.81%
Easysearch 2.0.0 索引性能表现更加稳定:
- 累计索引 CPU 时间(所有主分片):从 225.1 分钟缩短至 196.3 分钟,减少 28.8 分钟(-12.81%)
- 索引吞吐量:
- 平均吞吐量从 180,868 docs/s 提升至 190,712 docs/s(+5.44%)
- 最大吞吐量从 198,184 docs/s 提升至 220,460 docs/s(+11.24%)
- 最小吞吐量从 164,263 docs/s 提升至 178,961 docs/s(+8.95%)
累计索引 CPU 时间的减少,表明 2.0.0 版本在索引操作上更加高效,CPU 利用率更优。这意味着在相同硬件条件下,Easysearch 2.0.0 能够更快地完成数据摄入任务,对于需要处理大规模数据写入的场景具有重要意义。
Indexing Throughput (docs/s) - Higher is Better
2. Refresh 和 Flush 耗时缩短
Refresh 和 Flush 性能大幅改善
在 Elasticsearch/Easysearch 中,Refresh 和 Flush 操作对写入性能有直接影响。2.0.0 版本在这两个关键操作上实现了重大优化:
Refresh 性能提升 54.46%
- 累计刷新时间:从 9.14 分钟降至 4.16 分钟
- 中位刷新时间:减少 61.86%(从 0.133 分钟降至 0.051 分钟)
- 最大刷新时间:减少 65.62%(从 1.12 分钟降至 0.39 分钟)
Flush 性能提升 40%
- 累计刷盘时间:从 12.57 分钟降至 7.54 分钟
- 中位刷盘时间:减少 57.57%
- 最大刷盘时间:减少 31.93%
Cumulative Refresh Time (min) - Lower is Better
Cumulative Flush Time (min) - Lower is Better
这些优化使得 Easysearch 2.0.0 能够更高效地将数据持久化到磁盘,同时减少对写入操作的阻塞。
3. 垃圾回收(GC)性能优化
GC 效率显著提升
- Young GC 次数:从 525 次降至 426 次,减少 18.86%
- Young GC 时间:从 16.547 秒降至 15.985 秒,减少 3.40%
- Old GC:两个版本均无 Old GC 发生,内存管理健康
更少的 GC 次数意味着:
- 应用程序 STW(Stop-The-World)暂停更少
- 更稳定的查询响应时间
- 更好的系统吞吐量
查询性能提升
1. 基础查询延迟降低
多类型查询性能全面提升
| 查询类型 | 延迟指标 | 改进幅度 |
|---|---|---|
| Default 查询 | 50 分位延迟 | -11.40% (19.97ms → 17.69ms) |
| 99 分位延迟 | -15.23% (25.66ms → 21.75ms) | |
| Term 查询 | 50 分位延迟 | -19.88% (4049ms → 3244ms) |
| 90 分位延迟 | -18.73% (4137ms → 3362ms) | |
| Range 查询 | 50 分位延迟 | -31.71% (42.19ms → 28.81ms) |
| 100 分位延迟 | -64.68% (111.42ms → 39.35ms) |
Query Latency Improvements (ms) - Lower is Better
2. 排序查询性能飞跃
时间戳排序查询优化高达 97%
Easysearch 2.0.0 在排序查询场景下实现了令人瞩目的性能突破:
降序排序(desc_sort_timestamp)
- 50 分位延迟:从 516.07ms 降至 98.89ms(-80.84%)
- 90 分位延迟:从 544.84ms 降至 123.59ms(-77.32%)
- 99 分位延迟:从 603.14ms 降至 139.93ms(-76.80%)
升序排序 + After 分页(asc_sort_with_after_timestamp)
- 50 分位延迟:从 1272.58ms 降至 33.56ms(-97.36%)
- 90 分位延迟:从 1386.92ms 降至 37.25ms(-97.31%)
- 99 分位延迟:从 1474.98ms 降至 38.11ms(-97.42%)
Sort Query Latency (ms) - Lower is Better
Force Merge 后的排序查询
在强制合并为单段后,排序查询性能更加出色:
降序排序(force-merge-1-seg)
- 50 分位延迟:从 131,617ms 降至 115.01ms(-99.91%)
- 这一改进相当于从 2 分钟以上降至 0.1 秒!
升序 + After 分页(force-merge-1-seg)
- 50 分位延迟:从 1387.01ms 降至 132.42ms(-90.45%)
- 90 分位延迟:从 1509.03ms 降至 159.05ms(-89.46%)
3. 聚合查询性能提升
hourly_agg 聚合查询优化
- 50 分位延迟:从 4192.57ms 降至 3866.07ms(-7.79%)
- 90 分位延迟:从 4303.51ms 降至 4053.80ms(-5.80%)
- 99 分位延迟:从 4475.32ms 降至 4269.91ms(-4.59%)
4. Scroll 查询性能改进
大数据量遍历场景优化
- 50 分位延迟:从 6511.65ms 降至 4623.87ms(-28.99%)
- 90 分位延迟:从 6881.70ms 降至 5972.79ms(-13.21%)
- 平均吞吐量:从 24.192 pages/s 提升至 24.485 pages/s(+1.21%)
Scroll Query Latency (ms) - Lower is Better
5. 高百分位延迟大幅改善
极端场景下的稳定性提升
在衡量系统稳定性的高百分位延迟指标上,2.0.0 版本表现卓越:
| 场景 | 99.9 分位延迟改进 | 99.99 分位延迟改进 | 100 分位延迟改进 |
|---|---|---|---|
| index-append | -43.40% | -65.35% | -70.91% |
| (3364ms → 1904ms) | (9618ms → 3333ms) | (13427ms → 3906ms) |
这意味着即使在最坏的情况下,2.0.0 版本也能提供更加稳定和可预测的性能表现。
范围查询性能提升
200s-in-range 和 400s-in-range 查询优化
-
200s-in-range:
- 50 分位延迟降低 15.60%
- 吞吐量提升 1.20%
- 400s-in-range:
- 50 分位延迟降低 8.44%
- 吞吐量提升 0.23%
存储优化
磁盘空间使用更高效
- 存储大小:从 19.51 GB 降至 19.14 GB(-1.93%)
- 段数量:从 43 个增至 50 个(+16.28%)
虽然段数量略有增加,但总存储空间仍然减少,说明数据压缩和存储效率得到了提升。
Merge 策略调整
合并操作的权衡
需要注意的是,2.0.0 版本在 Merge 方面有以下变化:
- Merge 次数从 184 次增至 192 次(+4.35%)
- Merge 限流时间从 9.53 分钟增至 11.17 分钟(+17.20%)
这是为了平衡写入性能和查询性能所做的策略调整。用户可以根据实际场景需求,通过以下参数进行优化:
{
"index.merge.scheduler.max_thread_count": "1",
"index.merge.policy.max_merged_segment": "5gb"
}
技术架构改进
1. 段数据结构优化
通过将段元数据从堆内存迁移到堆外内存,Easysearch 2.0.0 实现了:
- 更低的 JVM 堆压力
- 更少的 GC 频率
- 更稳定的内存使用模式
- 更好的大数据集支持能力
2. 查询缓存优化
排序查询性能的巨大提升表明 2.0.0 版本可能在以下方面进行了优化:
- 改进的 Doc Values 访问机制
- 优化的排序算法
- 更高效的分页实现
- 智能的查询结果缓存
3. I/O 优化
Refresh 和 Flush 时间的大幅减少说明:
- 改进了磁盘 I/O 调度策略
- 优化了文件系统操作
- 可能引入了更高效的批量写入机制
适用场景
Easysearch 2.0.0 的性能提升使其在以下场景中表现更加出色:
1. 大规模日志与事件流处理
- 更高的写入吞吐量(+11.24% 峰值)
- 更低的索引延迟
- 适合 APM、日志分析、安全监控等场景
2. 时序数据存储与分析
- 时间戳排序查询性能提升高达 97%
- 适合 IoT、监控指标、金融交易数据等场景
3. 全文搜索应用
- 多类型查询延迟降低 10-30%
- 高并发场景下更稳定的响应时间
- 适合电商搜索、内容管理系统等场景
4. 实时分析与 Dashboard
- 聚合查询性能提升 5-8%
- 更低的极端延迟,用户体验更好
- 适合实时报表、业务 BI 等场景
5. 大数据量遍历与导出
- Scroll 查询延迟降低 29%
- 适合数据迁移、全量导出等场景
升级建议
兼容性
Easysearch 2.0.0 与 1.15.6 在 API 层面保持兼容,但建议:
- 测试环境验证:先在测试环境进行充分验证
- 配置审查:检查 Merge 相关配置是否需要调整
- 监控指标:升级后密切关注 GC、内存、延迟等指标
- 滚动升级:生产环境建议采用滚动升级方式
性能测试环境
本次测试使用 esrally 基准测试工具,测试配置如下:
- 测试场景:append-no-conflicts
- 测试时间:
- Baseline (1.15.6): 2025-11-14
- Contender (2.0.0): 2025-11-21
- 部署方式:External(独立部署)
- CPU 绑定:使用
taskset绑定 Easysearch 进程 0 到 15 cpu - JVM 配置:
-Xms16g -Xmx16g
总结
Easysearch 2.0.0 版本在性能方面取得了全面提升:
- 索引性能提升 12.81%
- 查询延迟降低 10-97%(不同场景)
- 内存使用优化 100%(堆内段数据)
- GC 频率降低 18.86%
- Refresh 性能提升 54.46%
- Flush 性能提升 40%
- 高百分位延迟改善 43-70%
这些改进使得 Easysearch 2.0.0 成为一个更加高效、稳定和可靠的搜索与分析引擎,特别适合处理大规模数据和实时查询场景。无论是日志分析、时序数据处理,还是全文搜索应用,2.0.0 版本都能提供更优秀的性能表现。
我们强烈建议用户升级到 Easysearch 2.0.0,以获得这些显著的性能提升和更好的使用体验。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
原文:https://infinilabs.cn/blog/2025/easysearch-2.0.0-performance-improvements/
【 INFINI Workshop 北京站】1月18日一起动手实验玩转 Easysearch
活动 • liaosy 发表了文章 • 0 个评论 • 5854 次浏览 • 2023-12-15 16:22
与 INFINI Labs 的技术专家面对面,第一时间了解极限实验室的发布最新产品和功能特性,通过动手实战,快速掌握最前沿的搜索技术,并用于实际项目中。欢迎大家扫描海报二维码免费报名参加。
活动时间:2024-01-18 13:30~17:30
活动地点:北京市海淀区 Wework 辉煌时代大厦 3 楼 3E 会议室
分享议题
- Easysearch 总体介绍及搭建实战
- 基于 INFINI Console 实现跨版本、跨引擎统一管控
- Elasticsearch -> Easysearch 在线迁移实操
参会提示
- 请务必自备电脑(Windows 系统环境请提前安装好 Linux 虚拟机)
- 请提前在 INFINI Labs 官网下载对应平台最新安装包(INFINI Easysearch、INFINI Gateway、INFINI Console)
- 下载地址:https://www.infinilabs.com/download
- 如有任何疑问可添加 INFINI Labs 小助手(微信号: INFINI-Labs)进行联系
【INFINI Workshop 上海站】7 月 27 日一起动手实验玩转 Easysearch
资讯动态 • liaosy 发表了文章 • 1 个评论 • 4127 次浏览 • 2023-07-07 16:30
Easysearch analysis-ik 多词典性能优化:从性能回退到分词性能提升 25%~30%
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 3443 次浏览 • 5 天前
Easysearch 版 analysis-ik 相比开源 IK 有一个重要的增强:支持多词典。简单说就是不同字段可以挂不同词库,可以叠加默认词典,也可以只用自定义词典。这是开源单词典 IK 做不到的。
功能实现初期,主要精力放在把能力跑通上。但在后来的一次写入压测中,我们发现 Easysearch 的写入吞吐和 Elasticsearch 有明显差距,最终定位到问题出在多词典的实现方式上——字段最终该用哪套词典,本来应该在分词前就算好,结果代码里把这个选择丢进了分词的热路径,每次分词都要反复切词典、重复扫同一段文本。
这篇文章记录的就是我们怎么一步步把性能拉回来、最终反超基线的过程。
问题怎么冒出来的
4 月 20 号,我们跑了一轮系统级写入压测。数据、mapping、settings、并发和 bulk 参数都一样,Elasticsearch 8.19.5 和 Easysearch 2.1.2 的写入吞吐差距大得有点不对劲:
| 时间 | 场景 | Elasticsearch | Easysearch | 说明 |
|---|---|---|---|---|
| 2026-04-20 第 2 次有效重跑 | 29900 docs / bulk=250 / concurrency=3 端到端写入压测 |
129.44 docs/s |
31.21 docs/s |
这是整条写入链路的 docs/s,不是单独分词吞吐 |
| 2026-04-20 诊断样本 | 5000 docs / bulk=250 / concurrency=3 |
156.25 docs/s |
30.67 docs/s |
Easysearch 的累计索引耗时约为 Elasticsearch 的 8.0x |
当时服务器上跑的就是早期多词典版本。后面修性能,追的就是这个版本和开源单词典 IK 基线之间的差距。
这一步还不能直接确定问题就在分词器。但差距摆在这儿了,得继续往下排。我们先排除了几个常见干扰因素:
refresh_interval- 动态同义词 HTTP 服务
- mapping / settings 不一致
- 网络层和 bulk 客户端本身
采样结果很快把范围收窄了。Elasticsearch 那边热点比较分散,Easysearch 这边呢,分词链路里出现了异常集中的开销——分词过程中反复做词典选择和字典查找。
瓶颈不在 Lucene 写入链路本身,就在 analysis-ik 的多词典实现上。
根因分析
第一类问题出在实现模型上。多词典想表达的是”这个字段最终用哪套词典”,这件事完全可以在分词前算好。但早期代码里,硬是把它变成了运行时的事:
- “字段用哪个词典”变成了”运行时多轮扫描”——同一段文本对着多套词典各来一遍。
- 全局字典切换的动作放进了每字符的热路径。
- 结果就是同一段文本的扫描和查找成本翻了好几倍。
所以问题不是多词典天然慢,是实现把本该提前算好的东西塞进了热路径反复做。
第二类问题是后续优化过程中留下的额外开销。后面加的跨边界、停用词、长文本等测试本身不是性能问题的来源,它们的作用是把正确性边界补齐,确保每次优化不会改变分词结果。
最后通过性能分析确认,残留开销主要来自两处:缓存命中前还在做不必要的数据复制;诊断逻辑在生产热路径上产生了额外开销。修完之后这两处热点都从火焰图上消失了,说明性能回退确实来自真实的代码路径成本,不是测试抖动。
修复过程
整个修复分四个阶段。
第一阶段:把多词典从”运行时分发”收敛为”最终有效词典视图”
多词典能力保留,但不再让分词器在热路径里反复切词典、重复扫文本。改成在分词前就把字段最终生效的词典算好,分词过程只面对一个已经收敛好的词典视图。
说白了就是把模型拉回正确方向——多词典管表达能力,热路径只管分词。
第二阶段:逐步打掉热路径上的常数开销
留下来的每一项优化,都经过正式性能测试和采样分析验证。原则就一条:不改分词语义,只减少热路径上反复发生的查找、分配和判断。
第三阶段:补齐正确性护栏
正确性测试必须先到位,不然吞吐提升没有意义——万一分词结果变了,跑得再快也白搭。
这一轮重点覆盖了这些容易出问题的场景:
- 真跨边界场景
- 数字和量词合并,如
1号 - 自定义词典里的含符号词
- 补充平面字符跨边界稳定性
- 停用词过滤后的偏移量
- 长文本样本的稳定性
- 正式性能测试数据集的分词结果对齐
后面所有的吞吐数字,前提都是分词结果一致,避免把分词行为的变化误当成性能提升。
第四阶段:清理最后的残留开销
到 4 月 28 号,最后一轮修复集中处理两个地方:
- 词典视图命中缓存时直接返回,不再多做一次数据复制
- 诊断逻辑默认关掉,不让线上请求为调试能力买单
这两处修完,Easysearch 版 IK 就不只是恢复到单词典版本附近了,在正式测试里已经明显领先。
用数据看恢复过程
为了不把系统级写入压测和分词器性能测试混在一起,下面只看几个关键节点。2026-04-20 的 docs/s 是系统级写入吞吐,后面的 tok/s 是单独的分词器吞吐。
这里说的”开源 IK 基线”就是开源 IK 的单词典实现对照版本。所有正式吞吐结论都建立在同一数据集、同一测试方法、分词结果一致的前提上。
| 时间 | 口径 | 关键结果 | 说明 |
|---|---|---|---|
| 2026-04-23 17:02 CST | 初期本地复现 | 服务器多词典版本 61.39 万 tok/s,单词典版本 114.48 万 tok/s |
单词典版本快 86.49%,性能差距被明确复现 |
| 2026-04-24 09:51:12~09:55:15 CST | 第一次正式追平 | smart 相对开源单词典基线 +7.26% |
从明显落后追到略微领先 |
| 2026-04-25 04:14~04:16 CST | 双模式阶段复核 | smart +16.88%,max_word +20.09% |
领先优势开始扩大 |
| 2026-04-28 12:30:56 CST | 最新正式复核 | smart +30.96%,max_word +21.31% |
当前最新结果 |
整个过程就是:
- 先暴露出明显的性能退化
- 逐步缩小差距
- 追平,然后开始领先
- 最终在分词结果完全一致的前提下,正式反超
最早的本地复现数据很关键:服务器当时跑的多词典版本只有 613896.67 tok/s,单词典版本 1144843.77 tok/s。后面所有修复就是冲着这个差距去的。
三张图分别对应问题暴露、分词复现和修复结果:第一张展示服务器 bulk 写入吞吐的系统级差距;第二张展示多词典版本和单词典版本的本地分词差距;第三张展示分词结果对齐后,Easysearch 版 IK 怎么一步步追上来,最终实现 25%~30% 的分词性能提升。
为什么说 Easysearch 版 IK 现在更好
这次修复的价值不只是消灭了几个热点,更重要的是把多词典能力、分词正确性和性能测试体系一起补齐了。
1. 功能更强,性能代价可控
开源单词典 IK 模型简单,但表达能力也弱。Easysearch 的多词典能力要解决的是字段级词库隔离、自定义词典叠加这些实际需求。
关键问题是:能不能把这些能力的性能开销压到足够低。修复后的结果证明,可以。
2. 正确性护栏更完整
这轮补上的测试不只是几个短样例,覆盖了更容易翻车的边界条件:
- 真跨边界场景
- 长文本稳定性
- 自定义词典和符号词
- 数字量词合并
- 停用词过滤后的偏移量
这意味着以后再做性能优化,必须同时保证分词结果不变。想靠改分词行为换吞吐,测试会先拦住。
3. 性能测试体系更严格
这轮之后,Easysearch 对 analysis-ik 的正式性能结论统一按一套标准出:
- 同一数据集
- 同一测试方法
smart和max_word双模式- 分词结果一致
- 有性能分析结果支撑
这套体系能避免两个常见坑:只看单轮吞吐波动就下结论,或者分词结果已经变了还在比性能。
小结
多词典能力在实现初期,主要精力放在功能补齐上——先把字段级词库隔离、自定义词典叠加这些能力跑通,性能优化是后面分阶段来的事,没办法一蹴而就。
这轮优化下来,核心思路其实就一条:把词典选择从分词热路径里挪出去,提前收敛好,让分词过程只面对最终的词典视图。再配合热点清理和正确性护栏,增强功能和更高性能完全可以兼得。
截至 2026 年 4 月 28 日,在本地 Mac 笔记本上的多轮 benchmark 中,Easysearch 版 IK 在 smart 模式大约领先开源单词典 IK 基线 25%~30%,max_word 模式大约领先 20% 左右,分词结果完全一致。具体数字每次跑会有波动,但趋势是稳定的。
这也是 Easysearch 版 IK 相对开源版更有价值的地方:不是多了几个配置项,而是在多词典能力、分词正确性和分词性能三个方面都给出了可验证的结果。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
Easysearch 正式支持插件开发:让你的搜索系统真正"为你所用"
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 10094 次浏览 • 2026-04-27 22:02
从"用搜索"到"造搜索"
搜索系统的需求千差万别。标准功能覆盖不了所有场景——行业特定的分词规则、定制化的业务逻辑、与外部系统的深度集成……
以往,这类定制需求需要依赖厂商支持。从 Easysearch 2.1.2 开始,你可以自己动手了。
随着构建依赖库正式发布到 Maven 中央仓库,Easysearch 的插件开发能力正式对外开放。这意味着 Easysearch 不再是一个黑盒产品,而是一个可扩展、可定制的搜索平台。你可以基于官方接口开发自定义插件,像使用原生功能一样使用它们。
插件能做什么
Easysearch 提供三类核心扩展点,覆盖搜索系统的关键环节:

1. 分析器插件(AnalysisPlugin)
自定义分词器、Token 过滤器、字符过滤器。适用于:
- 电商 SKU 的型号规格解析
- 医疗、法律等领域的专业术语分词
- 特殊符号或空格的规范化处理
注册后直接在索引设置中使用,与原生分析器完全等同。

2. REST/API 插件(ActionPlugin)
新增自定义 HTTP 接口。适用于:
- 封装业务查询逻辑,对外暴露简化 API
- 对接企业内部权限中心或监控系统
- 暴露插件自身的管理接口(如状态检查)

3. Ingest 插件(IngestPlugin)
在文档写入前进行字段转换。适用于:
- 自定义业务字段转换(如根据业务规则计算衍生字段)
- 数据标准化(统一日期格式、大小写转换)
- 富文本提取或元数据生成

5 分钟上手
我们准备了官方模板仓库,让你从克隆到运行只需几条命令:
# 克隆模板
git clone https://github.com/infinilabs/easysearch-plugin-template.git my-plugin
cd my-plugin
# 修改包名和类名,编写你的逻辑
# ...
方式一:开发调试——直接运行
# 构建插件并运行
./gradlew run
# 验证插件
curl -s "http://localhost:9200/_cat/plugins?v" | grep my-plugin
方式二:构建后安装到外部集群
# 构建插件
./gradlew build
# 安装到 Easysearch
bin/easysearch-plugin install file:///$(pwd)/build/distributions/my-plugin-0.1.0.zip
# 启动验证
bin/easysearch
curl -s "http://localhost:9200/_cat/plugins?v" | grep my-plugin
完整的开发指南请参考插件开发文档。
设计哲学
Easysearch 插件系统的设计遵循三个原则:
渐进式扩展——从最简单的 Plugin 类开始,按需实现 AnalysisPlugin、ActionPlugin 等接口,不必一次性掌握全部 API。
与原生同等——插件注册的分析器、处理器与系统原生组件在使用方式上完全一致,用户无需关心实现来源。
版本安全——插件加载时校验 easysearch.version,版本不匹配会拒绝加载,避免运行时异常。
从插件到生态
插件开发不只是技术能力的开放,更是产品理念的转变。
你可以将开发的插件发布到 GitHub Releases,通过 URL 直接安装:

bin/easysearch-plugin install https://github.com/yourname/my-plugin/releases/download/v0.1.0/my-plugin-0.1.0.zip
我们也欢迎社区贡献。如果你有通用的插件想法,欢迎与我们交流。
结语
搜索系统的最后一公里,只有业务开发者最清楚该怎么走。
Easysearch 2.1.2 的插件开发能力,让你能够自主掌控搜索系统的"最后一公里"。从"用搜索"到"造搜索",现在你可以让你的搜索系统真正"为你所用"。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
INFINI Agent v1.31.0 发布 | 全新 Easysearch 向导:一站式集群拉起与精细化管理
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12639 次浏览 • 2026-04-23 18:01

INFINI Agent v1.31.0 带来了本版本最重要的特性——Easysearch 安装向导。用户无需手动编辑任何配置文件,通过图形界面即可完成 Easysearch 集群的安装、配置和日常管理。
Easysearch 安装向导
一键拉起新集群
向导支持开发模式和生产模式两种方式创建 Easysearch 节点。用户只需填写集群名称、节点名称、监听地址、端口、数据目录等基本信息,向导便会自动完成软件下载、JDK 配置、安全证书生成、参数配置、插件安装、节点启动等全部步骤,并实时展示每一步的进度,支持随时暂停和恢复。

一键加入已有集群
通过粘贴现有集群提供的 Token,向导可自动从目标集群拉取证书、版本、插件等配置信息,完成新节点的安装和接入,全程无需手动复制任何证书文件。

安装前环境预检
向导在开始安装前会对当前机器进行全面检测,帮助用户提前发现潜在问题:
- 操作系统和 CPU 架构是否受支持
- 内存是否满足推荐要求
- 端口是否已被占用
- 数据目录磁盘空间是否充足、路径是否可写
- 系统参数(文件描述符限制、内核
max_map_count等)是否满足 Easysearch 运行需求 - TLS 证书填写后实时校验有效性,包括证书链完整性和过期时间

TLS 安全证书灵活配置
支持三种证书配置方式,满足不同安全需求:
- 自动生成:向导一键生成自签名证书,无需任何证书知识
- 手动上传(共享):为 HTTP 和节点通信层提供同一套证书
- 手动上传(分离):为 HTTP 层和节点通信层分别提供独立证书

完整的服务生命周期管理
集群建好后,向导提供持续的管理能力:
- 启动、停止、重启 Easysearch 节点

- 在线安装和卸载插件

- 在线编辑配置,包括
easysearch.yml、JVM 参数、日志配置、证书配置

- 在线日志排查:内置日志阅读器,支持查看节点日志文件列表,并提供类似 tail -f 的自动滚动功能,无需登录服务器即可快速定位报错。”

网络受限环境支持
针对无法直接访问外网的环境,向导支持配置 HTTP 代理,所有软件包(Easysearch、JDK、插件)均可通过代理下载,并提供连通性测试功能。

获取新版本
INFINI Agent v1.31.0 已正式发布,欢迎升级体验:
同样 15,000 条重规则,Percolate Query 比 Easysearch 慢 21.8 倍 —— Heavy-OR 场景实测
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 17145 次浏览 • 2026-04-15 16:44
15,000 条 heavy-OR 规则,200,000 条文档,同一台机器:Easysearch 在线规则引擎全流程 11.68 秒,Percolate Query 仅搜索阶段就跑了 254.30 秒——慢了 21.8 倍。
在"规则先存、文档后到"这类场景下,Percolate Query 的延迟会随规则数量和复杂度的增长快速恶化。规则涨到数千条后,每批文档匹配的耗时可以从秒级攀升至几分钟。这类问题换索引参数、调批次大小、精简 DSL,都治标不治本,根子在执行模型本身。
本文通过一组 heavy-OR 基准测试,量化两种方案的实际差距。
测试配置
测试在同一台主机上运行,使用同一套规则文本和文档样本。Percolate Query 的查询条件由相同规则翻译而来,保证两侧规则语义一致。
| 参数 | 值 |
|---|---|
| 规则总数 | 15,000 |
| 文档总数 | 200,000 |
| 批次大小 | 10,000 / 批 |
| 重规则数量 | 2,500 条大 OR 热点规则 |
| 单条大 OR 规模 | 随机 50 ~ 500 个 OR 条件 |
测试结果
| 路径 | 用时 |
|---|---|
纯写入 plain_bulk |
6.025535s |
在线规则引擎 rules_only |
11.684568s |
Percolate Query 搜索阶段 |
254.304583s |
同样 15,000 条规则 + 200,000 条文档
具体指标:
- Easysearch 在线规则引擎全流程:
11.68s - Percolate Query 搜索阶段:
254.30s - 差值:
242.62s - 倍数:
21.76 倍 - 每批(10,000 文档)平均耗时:Easysearch 约
0.49s,Percolate Query 约12.69s
开启规则引擎的增量成本
规则匹配会对写入链路产生多少额外开销,是评估在线规则引擎可行性的重要指标之一。
开启规则引擎的写入增量
与之对比,Percolate Query 仅搜索阶段就需要 254.30s。换言之,Easysearch 在线规则引擎把规则匹配叠加进写入流程,新增成本约为 Percolate Query 搜索耗时的 1/44.9。
只看匹配引擎本体
上一组数据(11.68s vs 254.30s)包含了 Easysearch 的在线写入、bulk 解析和索引处理等通用开销。为了单独衡量规则匹配引擎自身的性能,我们用 Java 直调 JNI 做了一次离线 match,绕过写入链路,只跑规则匹配逻辑。
| 路径 | 用时 |
|---|---|
| Easysearch 纯匹配(JNI 离线) | 5.046934s |
| Percolate Query 搜索阶段 | 254.304583s |
只比匹配本身
这组数据说明两点:Easysearch 的性能优势并非来自写入链路的整合效率,即便剔除通用写入成本,规则匹配引擎本体与 Percolate Query 之间依然存在约 50 倍的差距。
为什么 Percolate Query 会慢
根因在执行模型,OR 条件多只是放大器。
每批文档到达时,Percolate Query 都要走完这套流程:
- 把文档放进临时内存索引
- 基于规则中的 terms 筛选候选规则
- 对候选规则逐条验证
以本次测试为例,各阶段耗时分布如下:
- 规则翻译:
9.560294s - 规则导入:
7.451857s - percolate 搜索:
254.304583s
搜索阶段是每批文档都必须重新支付的代价。
Heavy-OR 规则在这套流程里两头放大:规则覆盖面广,候选集更难剪掉;单条规则条件多,逐条验证也更重。
Easysearch 规则引擎把规则提前编译好,文档到达后直接匹配,不走这套每批重建的流程,差距就在这里。
适用场景
以下场景对规则匹配的吞吐和延迟要求较高,是 Easysearch 在线规则引擎的典型适用范围:
- 内容审核:规则持续增长且复杂度高,需要稳定的处理吞吐,对单批延迟敏感。
- 舆情监测:热点词、别名、邻近词组合多,规则天然形成大 OR 结构,是 Percolate Query 最容易触及性能瓶颈的场景。
- 广告定向:人群包条件不断叠加,文档流量高,规则匹配需要足够轻量,避免影响整条投放链路。
- 告警规则:延迟直接影响告警有效性,规则命中需要尽量贴近文档写入时刻。
- 实时反欺诈:规则复杂、变更频繁、吞吐高,要求文档到达后立即完成判断。
小结
在本次 heavy-OR 基准测试中:
- 相同规则集(15,000 条)和文档量(200,000 条),Easysearch 在线规则引擎全流程耗时 11.68s,Percolate Query 仅搜索阶段耗时 254.30s,相差 21.8 倍。
- 开启规则引擎带来的写入链路增量成本为 5.66s,约为 Percolate Query 搜索阶段耗时的 1/44.9。
- 剔除写入通用开销后,规则匹配引擎本体的差距约为 50 倍。
如果你的业务已经有 Percolate Query 延迟随规则增长持续上升的问题,不用看 demo 数据——把你线上最重的那批规则拿出来,跑一次就知道差距在哪。
规则引擎功能当前需要试用 License。你可以先下载 Easysearch:https://infinilabs.cn/download,再联系售前申请试用 License 并获取开通指引。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
Easysearch BKD Merge 异常排查实录:最终定位到旧版 GraalVM JIT 运行时
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 11137 次浏览 • 2026-04-10 17:51
最近一次高并发写入压测中,我们遇到了一个非常诡异的 BKD merge 崩溃。从报错看,很像 Easysearch 2.1.2 在 merge 阶段把 segment 读成了错误状态。典型错误是这样的:
java.lang.ArrayIndexOutOfBoundsException: Index -3 out of bounds for length 8
java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8
异常栈最终落在 Lucene BKD 相关路径上:
BKDReader.readNodeData()BKDWriter.merge()Lucene90PointsWriter.merge()
如果只看栈,很容易把问题归到 Easysearch 的 BKD merge 逻辑。但排查到最后,结论恰恰相反。
问题不在 Easysearch 的代码,而在 JDK 运行时。 更精确地说,是某个特定 Oracle GraalVM 21 构建中的 JVMCI/Graal JIT 路径,把 Lucene BKD 的热点代码执行错了。
1、为什么这个问题难查
它有几个特别迷惑人的特征:
- 只在高并发写入压测下触发
- 服务重启后的前几轮最容易复现
- 同一进程里,删了索引重新压,后面复现率反而下降
- 不是固定字段,多个数字类型字段都中过招
ZSTD和best_compression两种 codec 下都能复现
实际命中过的字段包括 @timestamp、size、status、_seq_no。所以这不是某个字段、某种 codec 或某个 mapping 的偶发问题。
2、第一层排除:merge reader 不是第一现场
一开始我们确实怀疑 merge reader,毕竟异常直接出现在 merge 路径上。但日志顺序很快给出了相反的证据。在 merge 真正崩溃之前,source segment 已经先出现了这些异常信号:
point-sort-restore-multiple-zero-ordssource-write-point-doc-mismatchpointCount > docCountpack-index-negative-codereader-invalid-start-pos- 最后才是
ArrayIndexOutOfBoundsException
这意味着两件事:merge reader 不是第一现场,source segment 在写出阶段就已经坏了。merge reader 只是读到了已经损坏的 BKD index,并在那个阶段暴露了异常。
3、第二层排除:Easysearch 自己的 BKD 写入逻辑也没有先出错
继续往前追溯,我们发现问题比 OneDimensionBKDWriter.add() 还要早。真正的异常出现在排序/回填链路上:
PointValuesWriterMutablePointTreeReaderUtils.sort()StableMSBRadixSorter
关键证据来自两个探针:
point-sort-restore-multiple-zero-ordsunwrittenSlotCount == source-write-point-doc-mismatch delta
这说明在某次排序/回填过程中,有一部分槽位根本没有被写入,默认值 0 被 restore 回填到 ords[],再通过 docIDs[0] 放大成大量 docID=0,最终导致 pointCount > docCount,source segment 进入错误状态。
到这一步,排查重点已经不是“Easysearch 的 BKD merge 逻辑存在缺陷”,而是 Lucene points 排序链路的执行结果和源码语义不一致。
4、真正的转折点:抓到了 reorder() 自身的 coverage 异常
真正把方向扭转过来的,不是又一次复现,而是一个更早的探针:
point-sort-reorder-coverage-mismatch
这个探针验证的是:StableMSBRadixSorter.reorder() 是否真的按源码应有的次数完整执行。
我们抓到的典型样本之一如下:
targetSegment=_xfield=statusk=7expectedLoopCount=9800actualIterationCount=8204firstCoverageMismatchBucket=201firstCoverageExpected=9788firstCoverageActual=8192
更关键的是,同一条日志里还带出了这个信息:
skippedSourceSamples=[201:[{ord=8192,bucket=201,docID=9090,byteAtK=200}, ...]]
这条信息非常重要,因为它说明:bucket 201 理论上应该处理 9788 条,实际只处理了前 8192 条,但从 ord=8192 往后的样本,读出来仍然还是 bucket=201。这直接推翻了“后半段数据被污染后改桶”的旧解释,指向了一个更直接的结论:reorder() 自己的 coverage 被截断了。
另一个样本中出现了同类边界:firstCoverageExpected=31822,firstCoverageActual=16384。
到这里,一个很不自然的特征浮现出来:8192、16384——这些明显的 2 的幂边界,更像是运行时或 JIT 执行异常,而不是普通业务逻辑 bug。
5、哪段代码最可疑
此时怀疑对象已经不是泛泛的“BKD 整体有问题”,而是 Lucene 中的这段热点循环:
for (int i = 0; i < HISTOGRAM_SIZE; ++i) {
final int limit = endOffsets[i];
for (int h1 = fixedStartOffsets[i]; h1 < limit; h1++) {
final int b = getBucket(from + h1, k);
final int h2 = startOffsets[b]++;
save(from + h1, from + h2);
}
}
restore(from, to);
代码位于 org.apache.lucene.util.StableMSBRadixSorter#reorder(...)。
按源码语义,这段代码应该完整扫描每个 bucket 的范围,并最终把全部结果 restore 回去。但我们抓到的事实是:expectedLoopCount != actualIterationCount,某些 bucket 只跑到 8192 / 16384 就停了,随后出现未写槽位,restore 把默认 0 回填,最终 source segment 进入错误状态。
如果这是 Java 源码本身的稳定逻辑 bug,它在解释执行时也应该稳定触发,而不应该强烈依赖某个 JDK/JIT 组合。后面的 JVM 对照实验基本排除了这个可能性。
6、最强证据:只换 JDK / JIT 路径,结果就变了
这次排查中最有说服力的,不是某一条日志,而是对照实验。
基线组:旧版 Oracle GraalVM 21,默认 JVMCI/Graal JIT
环境:
Oracle GraalVM 21+35.121+35-jvmci-23.1-b15Linux aarch64 / ARM64UseJVMCICompiler = true
结果:很快复现,命中了 point-sort-reorder-coverage-mismatch、point-sort-reorder-underfilled、point-sort-restore-multiple-zero-ords,随后 merge 报 ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8。
对照组:关闭 JVMCI/Graal JIT 或纯解释执行
只改 JVM 参数,不改代码和压测口径:
-XX:-UseJVMCICompiler-Xint
结果一致:都没有再出现上述探针和异常。
这三组对照的意义很直接:如果这是 Easysearch 或 Lucene 的纯 Java 逻辑 bug,解释执行也应该能稳定复现。但现实是基线组复现,关闭 JVMCI 和纯解释执行都不复现。问题显然高度依赖 JIT 路径。
版本对照:较新的 GraalVM 21 构建在当前测试中未复现
这里需要补充一条重要的边界条件。我们后来又测试了一个较新的 GraalVM 版本:
java version "21.0.9" 2025-10-21 LTS
Java(TM) SE Runtime Environment Oracle GraalVM 21.0.9+7.1 (build 21.0.9+7-LTS-jvmci-23.1-b79)
在当前压测中,这个版本没有再出现 merge 错误。
因此结论必须写得更精确:已知会复现的是较早的 21+35-jvmci-23.1-b15,已知在当前测试中未复现的是较新的 21.0.9+7-LTS-jvmci-23.1-b79。更准确的工程判断不是“GraalVM 21 整体都有问题”,而是某个特定 GraalVM 21 构建有问题,较新的构建很可能已经修复或规避了该问题。这里仍需保持严谨:只能说“在当前压测中未复现”,还不能直接说“已经被完整证明没有问题”。
平台边界:不能写成 ARM 专属
除了前面详细展开的 Linux aarch64 / ARM64 主要实验环境外,有用户反馈在以下环境中也出现过同类问题:
- 操作系统:
openEuler - 内核:
4.19.90-2112.8.0.0131.oe1.x86_64 - 架构:
x86_64
这是用户的测试环境,不是我们能够独立完整复现并逐项展开的。但这条信息已经足够说明:当前不能把问题简单写成“ARM 平台专属”。更准确的说法是:我们在 ARM64 上系统性复现并完成了主要对照实验,另外也有 openEuler x86_64 测试环境的同类现象反馈,因此平台边界目前还没有被完全钉死。
7、更强的同机对照:换成 Oracle HotSpot 21.0.10 后,全量写入跑完也没有问题
为了进一步排除“是不是所有 Java 21 都会这样”,我们在同一台服务器上把 /infini/easysearch/jdk 从 Oracle GraalVM 21 换成普通 Oracle HotSpot 21.0.10,恢复默认 JVM 参数,用同样的写入压测继续验证。
其中一轮的结果很有说服力:
- 索引:
nginx_zstd3_40mt4 - codec:
ZSTD threads=16bulk_size=1000target_docs=181463624
最终 after_count=181463624,delta_written=181463624,全量文档写入完成,服务端没有出现任何 BKD merge 错误。
这条结果至少说明:同一台机器、同一套 Easysearch、同样的数据规模和写入模型,只要把 JDK 从 Oracle GraalVM 21 换成 Oracle HotSpot 21.0.10,问题就不再出现。
到这一步,工程判断已经比较清晰了:不是 Easysearch 自身逻辑导致,也不是所有 Oracle JDK 21 都会出错,更像是特定 Oracle GraalVM 21 构建相关的 JVMCI/Graal JIT 路径问题。
8、最关键的外部对照:Elasticsearch 8.19.5 也复现了
如果说前面的结论还能被质疑为“Easysearch 某些实现差异触发的”,那么后面的外部对照基本排除了这个方向。
我们在同一台服务器上部署了 Elasticsearch 8.19.5(Lucene 9.12.2),JDK 也切到相同的 Oracle GraalVM 21,执行同类写入压测。结果 Elasticsearch 也复现了同样的 BKD merge 崩溃。
关键异常完全一致:
java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8
栈也一样落在 BKDReader.readNodeData、BKDWriter$MergeReader.collectNextLeaf、BKDWriter$MergeReader.next。
这条证据的力度很强:不是 Easysearch 独有的问题,不是当前这套 Lucene 代码路径独有的问题,Elasticsearch 8.19.5 + Lucene 9.12.2 在同类 GraalVM 21 环境下也会出现同类异常。到这一步,再把问题归因于 Easysearch 本身的代码逻辑,已经缺乏依据了。
9、这次排查最终说明了什么
把整条证据链串起来,当前阶段的结论已经比较清楚。
已验证的事实:
- 问题不是 merge reader 先制造坏数据,source segment 在更早阶段就已经进入错误状态
- 不是单字段问题,也不是
ZSTD或best_compression专属 - 已抓到
StableMSBRadixSorter.reorder()自身的 coverage 异常 - 关闭
UseJVMCICompiler后问题不复现,-Xint下也不复现 - 同机切到
Oracle HotSpot 21.0.10后,Easysearch 全量写入跑完未见 BKD merge 异常 Elasticsearch 8.19.5 + Lucene 9.12.2在同类 GraalVM 21 环境下也复现- 较新的
21.0.9+7-LTS-jvmci-23.1-b79在当前压测中未复现 - 某用户的
openEuler x86_64测试环境中也出现过同类错误,因此不能写成 ARM 专属
工程结论:
从工程证据来看,Easysearch 本身的代码逻辑没有问题。
当前最符合事实的结论是:问题高度相关于特定 Oracle GraalVM 21 构建,更具体地,是该构建相关的 JVMCI/Graal JIT 路径。它把 Lucene BKD 相关热点代码执行到了错误状态。已知较早构建 21+35-jvmci-23.1-b15 可复现,已知较新的 21.0.9+7-LTS-jvmci-23.1-b79 在当前测试中未复现。平台边界目前尚未完全钉死,不能再简单写成仅限 ARM64。
换句话说,这不是“Easysearch 的 BKD merge 实现有 bug”,而是特定 JDK/JIT 运行时把本来正确的 Lucene BKD 代码执行错了。
10、建议版本与规避方案
如果你在生产或测试环境中运行 Easysearch 或 Elasticsearch,并且使用的是某些 Oracle GraalVM 21 构建,且启用了默认的 JVMCI/Graal JIT,那么在高并发写入、频繁 merge、BKD 热点路径被充分打热的场景下,需要特别警惕这类问题。
现阶段比较明确的建议是:
- 避免继续使用已经验证可复现的旧版构建:
Oracle GraalVM 21+35.1或21+35-jvmci-23.1-b15 - 优先升级到当前测试中未复现的版本:
Oracle GraalVM 21.0.9+7.1(即21.0.9+7-LTS-jvmci-23.1-b79) - 如果短期内不方便升级 GraalVM,直接切换到普通
Oracle HotSpot 21.0.10
直接落到版本号上会更清晰:
- 已确认应避开:
21+35-jvmci-23.1-b15 - 当前更推荐:
21.0.9+7-LTS-jvmci-23.1-b79
原因很简单:前者我们已经复现了,后者在当前压测中没有复现。当然,这里的“推荐”是基于当前测试结果,不代表上游已经正式确认该问题已被修复。
11、最后
这次排查最大的价值,不是“又复现了一次 BKD merge 崩溃”,而是把一个看起来像 Easysearch 代码 bug 的现象,收敛成了一个有明确边界的运行时问题。
它至少说明两件事:
- 栈顶报错的位置不一定是真正的第一现场
- 真正有说服力的不是猜测,而是对照实验
这次结论之所以成立,不是因为主观判断,而是因为我们已经拿到了足够强的工程证据:同机 HotSpot 不复现,关闭 JVMCI 不复现,解释执行不复现,Elasticsearch 也复现,较新的 GraalVM 21.0.9+7.1 在当前测试中未复现,且某用户的 openEuler x86_64 测试环境也出现过同类错误。
所以,这一次,问题确实不在 Easysearch,而在特定版本的 JDK/JIT 运行时。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
【搜索客社区日报】第2214期 (2025-04-10)
社区日报 • Fred2000 发表了文章 • 0 个评论 • 10550 次浏览 • 2026-04-10 10:39
2026 春季招聘 | 春风十里,不如有你,别让才华埋没,来极限科技绽放光芒吧!
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12373 次浏览 • 2026-03-19 20:05
公司简介
极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,在北京、上海、广州、长沙等城市设有研发中心,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
招聘信息
售前解决方案工程师(北京)
岗位职责:
1、深入分析客户业务场景与搜索需求,协助销售团队理解客户痛点,提供匹配的企业级搜索基础设施与整体架构建议 ;
2、负责公司产品与解决方案的售前技术支持,包括技术交流、方案编写、成本估算、产品演示及 PPT 制作与讲解 ;
3、协助销售进行客户需求调研、业务场景分析,提供基于分布式搜索引擎的技术方案与专业咨询 ;
4、参与客户培训与技术指导,提供现场售前技术支持,提升客户技术认知与产品信任度 ;
5、主导现场 POC,协调资源完成功能与非功能性测试,撰写测试报告并推动项目进展 ;
6、收集并反馈客户产品使用意见与需求,协助产品团队持续优化产品功能与用户体验 。
岗位要求:
1、全日制本科及以上学历,计算机、信息技术或相关专业优先 ;
2、3 年以上数据库、大数据或相关技术领域工作经验 ;
3、了解 Elasticsearch / Easysearch / OpenSearch 等搜索引擎,或熟悉至少一种主流数据库(如 MySQL、Oracle、MongoDB 等) ;
4、具备大型企业信息化项目经验,了解行业技术趋势、商业模式与主流 IT 服务商 ;
5、具备良好的沟通表达能力、应变能力,能独立与客户进行技术交流并精准把握需求 ;
6、具备客户需求深度挖掘与引导能力,能结合产品优势编写项目方案与技术建议书 ;
7、学习能力强,善于知识整合,具备良好的团队协作精神 。
加分项:
1、985 / 211 院校毕业优先 ;
2、拥有技术博客或在 AI、搜索、大数据、数据库等领域有内容输出经验 ;
3、持有 Elastic Certified Engineer(ECE)认证 ;
4、具备大规模搜索引擎集群设计、扩展与性能调优经验 ;
5、熟悉大数据相关技术栈,如 Kafka、Flink 等 ;
6、熟悉其他搜索引擎技术(如 Solr、Lucene)者优先 。
区域销售经理(北京)
岗位职责:
1、深耕 TO B 业务:专注于金融行业(特别是银行及证券)或央国企(特别是能源、大制造行业),建立并维护与该行业关键客户的良好关系,深入挖掘客户对企业搜索解决方案的需求 ;
2、攻坚克难,促成交易:面对复杂多变的销售环境,展现出强大的攻坚克难能力,有效应对客户异议,推动销售项目从初期接触到最终成交的全过程 ;
3、客户关系管理:建立并管理高价值的客户关系网络,通过定期的沟通、拜访及活动策划,增强客户粘性,促进长期合作 ;
4、解决方案设计与呈现:基于客户具体需求,结合公司产品与技术优势,设计并呈现定制化的解决方案,有效展现产品价值及实施效果 ;
5、技术学习与传递:快速学习并掌握最新的企业搜索、AI 搜索技术趋势、产品特性及竞争对手动态,能够准确、专业地向客户传达技术价值,提升客户信任度 ;
6、业绩达成与团队协作:确保达成公司设定的个人销售目标,同时与售前技术支支持、售后服务等部门紧密合作,确保项目顺利交付及客户满意度 。
岗位要求:
1、全日制本科及以上学历 ;
2、3 年以上 IT 解决方案或软件销售经验,具有 1 年以上金融或央国企相关行业销售背景 ;
3、面对挑战不退缩,能够积极寻找解决方案,推动项目进展直至成功 ;
4、了解所在行业业务流程及 IT 架构,能够快速学习并掌握新技术 ;
5、工作态度认真负责,勤奋敬业,能够承受一定的工作压力,确保任务按时按质完成 ;
6、良好的团队合作精神,能够与跨部门团队有效协作,共同达成目标 ;
7、销售提成额外签署补充协议 。
加分项:
1、计算机科学、信息技术或相关专业 ;
2、985 / 211 院校毕业优先 ;
3、了解开源行业及生态,理解相关技术及商业逻辑 ;
4、有数据库或大数据相关产品及解决方案销售经验 。
市场专员(北京)
岗位职责:
1、负责公司企业搜索、AI 搜索解决方案的技术生态运营工作,包括国内及全球市场 ;
2、负责市场活动策划,包括但不限于线上活动、线下活动、品牌合作等,提升品牌形象 ;
3、以技术角度,整合上下游合作伙伴资源,建立产品在市场上的知名度 ;
4、规划产品技术生态运营工作,包括自运营技术社区、展会合作、新媒体媒体投放等 ;
5、积极通过数字化体现运营价值,驱动产品知名度,配合一线最终实现销售业绩提升 ;
6、负责市场调研及相关情报搜集整理,同竞品的分析对比和信息搜集,根据市场反馈和数据,分析结果 ;
7、熟练使用 AI 工具做内容创作、 AI 作图、素材制作等,支持内容传播与活动落地 。
岗位要求:
1、市场运营或计算机科学、信息技术相关专业全日制本科或以上学历 ;
2、1-3 年以上科技产品公司市场运营经验 ;
3、具有良好的数据敏感度,善于从数据中发现问题点、机会点,具备良好的分析问题、解决问题的能力 ;
4、主导或参与过软件企业重大发布会、大型行业展会,或专题系列的技术巡展 ;
5、结果导向,执行力强,擅长跨部门协同,以获客转化为核心目标 。
加分项:
1、985 / 211 院校毕业优先 ;
2、有海外留学经验,英文阅读沟通能力强 ;
3、有数据分析基础,熟练使用 Python ;
4、有广告、AI 营销、IT 媒体或产业联盟工作经验优先 ;
5、熟悉使用 Office 办公软件,了解 PS、PR、剪映等设计软件者优先 ;
6、有在软件开发、数据库或大数据领域 维护运营博客或自媒体经验优先 。
客户成功经理(长沙)
岗位职责:
1、负责客户全生命周期的成功管理,包括 Onboarding、产品培训、日常维护、使用跟踪及定期回访,确保客户持续获得价值 ;
2、主动服务,发现那些客户需要帮助,提前介入,提供主动关怀,及时响应客户问题与需求,推动问题闭环解决 ;
3、筛选或发现优质客户,促进增购、续约购,给销售团队提供最佳信息 ;
4、技术学习与传递:快速学习并掌握最新的企业搜索、AI 搜索技术趋势、产品特性及竞争对手动态,能够准确、专业地向客户传达技术价值,提升客户信任度 ;
5、沟通与项目管理:协调内部资源(销售,售后服务,产品、开发等部门),提高客户满意度 ;
6、收集客户反馈与需求,输出产品优化建议,与产品团队紧密协作推动产品迭代 。
岗位要求:
1、全日制本科及以上学历,限 2026 年应届生 ;
2、快速学习能力,熟悉和理解行业客户的业务逻辑及IT架构(如金融、能源、制造业等) ;
3、具备一定的数据分析能力,通过客户使用数据预判需求或风险 ;
4、工作态度认真负责,勤奋敬业 ;
5、良好的团队合作精神,能够与跨部门团队有效协作,共同达成目标 。
加分项:
1、计算机科学、信息技术或相关专业 ;
2、985 / 211 院校毕业优先 ;
3、有过 数据库类或大数据类技术性工作经验 ;
4、熟悉 AI、搜索、大数据、数据库等相关行业知识 。
UI/交互设计实习生(长沙)
岗位职责:
1、负责产品界面与交互设计,优化用户体验 ;
2、支持运营活动视觉输出,熟练使用AI工具产出创意素材 ;
3、参与官网、海报等设计工作 ;
4、结合数据反馈优化设计,提升转化效果 ;
5、与产品、开发团队协作推进方案落地 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,视觉传达、人机交互、数字媒体艺术等相关专业优先 ;
2、关注设计趋势,学习能力强,能快速掌握新工具与方法 ;
3、具备较强的审美能力、逻辑思维能力、沟通表达能力以及对细节的极致追求 ;
4、应聘者请准备好自己的作品,请将作品集与简历一同发送 。
加分项:
1、有设计社区(Behance、Dribbble、站酷等)作品或运营经验 ;
2、有动效设计或动画制作经验 。
软件测试实习生(长沙)
岗位职责:
1、参与项目和日常产品需求分析,把控需求和系统分析质量和风险 ;
2、负责完成产品功能特性的测试设计以及测试用例的编写 ;
3、组织测试实施工作,跟进测试的进展和完成情况,记录测试结果并准备测试报告 ;
4、通过抓包或日志分析,能够对常见bug进行基本定位 ;
5、不断改进测试流程和方法,以提高质量和效率 ;
6、关注产品质量和客户需求,确保稳定、可靠和用户友好的软件交付 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,计算机以及相关专业 ;
2、熟悉软件测试基础理论、测试流程及常用测试方法 ;
3、良好的英文读写能力,能够有效的阅读和学习英文技术资料 ;
4、很强的自我驱动学习能力和技术钻研能力,具备优秀的沟通技巧,很好的责任心与高执行力 ;
5、能够承受压力,在快节奏的环境中高效工作 。
加分项:
1、熟悉 Go 或 Java 或 Python 编程语言,熟练 Linux,Git 常用命令 ;
2、熟悉 AI、搜索、大数据、数据库等相关行业知识 ;
3、熟悉 Easysearch / Elasticsearch / OpenSearch 等搜索引擎 。
内容运营实习生(长沙)
岗位职责:
1、负责社区内容的策划、文案、编辑,围绕团队成果产出技术解读文章,通过公众号、博客、社区等形式进行内容运营,提升公司的影响力 ;
2、支持市场营销中的内容输出,善于利用 AI 工具提供有吸引力的设计创意与素材 ;
3、参与其他新媒体相关工作,如视频号、小红书、抖音账号等内容创作和运营 ;
4、数据化运营,包括分析官网访问、下载等数据指标,根据数据反馈及时调整策略,提升运营效果 ;
5、定期与社区用户、媒体沟通,保持通畅的聆听反馈机制 ;
6、参与策划、组织及执行团队主办或承办的各类社区活动 。
岗位要求:
1、985 / 211 全日制本科及以上学历在读,新闻、营销、传媒、计算机等相关专业优先 ;
2、需要公众号运营、短视频运营相关工作经验;熟练掌握排版、拍摄、剪辑等各项能力 ;
3、具备较强的创意和策划能力、应变能力、语言和文字表达能力以及敏锐的市场触角 ;
4、对搜索技术、互联网产品及工具类信息怀有浓厚兴趣,具备快速学习并熟练掌握相关知识的能力,能够紧跟行业动态 。
加分项:
1、具有用户增长、数据分析、数据挖掘、信息检索经验者优先 ;
2、具有开源社区、开发者社区、开源媒体运营经验者优先 。
更多职位请访问 Boss 直聘
简历投递
- 邮件:hello@infini.ltd(邮件标题请备注姓名+求职岗位)
- 微信:INFINI-Labs (加微请备注求职岗位)

我们期待有才华、有激情的你加入我们,一起探索数据搜索的未来,共同创造无限可能!
INFINI Labs 产品更新 | Easysearch 2.1.0 新增高性能 Rules 规则引擎插件,数据探索 Discover 等
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9073 次浏览 • 2026-03-17 16:02

INFINI Easysearch v2.1.0 发布:新增 Rules 规则引擎(百万级规则、复杂表达式、自动同步恢复)与 形态学分析插件(俄语/英语词形还原,提升搜索召回率);审计日志支持动态用户审计,UI 新增日志查看、配置及数据探索页面,运维更高效。INFINI Console、Gateway、Agent、Loadgen v1.30.3 统一基于 Framework 升级,优化本地磁盘队列数据消费。详情见 Release Notes。
Easysearch v2.1.0
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
Easysearch 本次更新如下:
🚀 功能特性 (Features)
- 新增 Rules 规则引擎插件,提供高性能的规则匹配能力
- 支持 linux-x64 和 linux-aarch64 架构
- 支持 Ingest Pipeline 集成,数据写入时自动匹配规则并添加标签
- 支持复杂的规则表达式(AND/OR/NOT、near、正则、数值范围等)
- 支持百万级规则库,匹配性能是传统方案的上百倍。
- 支持多节点集群自动同步和广播编译规则
- 节点启动时自动同步缺失的规则库
- 规则库同步期间自动保护写入,确保规则完整性
- 本地元数据文件持久化记录编译历史,支持规则库文件丢失后的自动恢复
- 新增形态学分析插件(analysis-morphology),支持俄语和英语的形态分析
- 精准还原:基于词典将动词时态、名词格位等还原为标准原型(如 went → go)
- 词元扩展:同时索引原词与关联词根(如runner → runner, run),实现智能搜索匹配
- 高召回率:解决俄语复杂的变格与变位搜索难题,确保不同语法形式下均能精准检索
- 审计日志新增动态指定用户进行审计的功能
-
UI 插件新增如下能力
- 支持审计日志在线查看
- 支持审计日志模块动态配置
- 新增数据探索页面


✈️ 改进优化 (Improvements)
- 将“结巴”分词插件日志迁移至 Log4J,并降低周期性任务的日志级别以减少冗余
🐛 问题修复(Bug Fixes)
- 修复少量 UI 界面操作问题

Console v1.30.3
INFINI Console 是一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台。通过对流行的搜索引擎基础设施进行跨版本、多集群的集中纳管,企业可以快速方便的统一管理企业内部的不同版本的多套搜索集群。
Console 本次详细更新记录如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Console 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Console 受益。
🐛 问题修复(Bug Fixes)
- 修复 Agent 关联不成功问题
Gateway v1.30.3
INFINI Gateway 是一个开源的面向搜索场景的高性能数据网关,所有请求都经过网关处理后再转发到后端的搜索业务集群。基于 INFINI Gateway 可以实现索引级别的限速限流、常见查询的缓存加速、查询请求的审计、查询结果的动态修改等等。
Gateway 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Gateway 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Gateway 受益。
Agent v1.30.3
INFINI Agent 负责采集和上传 Elasticsearch, Easysearch, Opensearch 集群的日志和指标信息,通过 INFINI Console 管理,支持主流操作系统和平台,安装包轻量且无任何外部依赖,可以快速方便地安装。
Agent 本次更新如下:
🚀 功能特性 (Features)
- 在 Kubernetes 环境下通过环境变量 http.port 探测 Easysearch 的 HTTP 端口
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Agent 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Agent 受益。
Loadgen v1.30.3
INFINI Loadgen 是一款开源的专为 Easysearch、Elasticsearch、OpenSearch 设计的轻量级性能测试工具。
Loadgen 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Loadgen 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Loadgen 受益。
更多详情请查看以下各产品的 Release Notes 或联系我们的技术支持团队!
- Coco AI App
- Coco AI Server
- INFINI Easysearch
- INFINI Gateway
- INFINI Console
- INFINI Agent
- INFINI Loadgen
- INFINI Framework
期待反馈
欢迎下载体验使用,如果您在使用过程中遇到如何疑问或者问题,欢迎前往 INFINI Labs Github(https://github.com/infinilabs) 中的对应项目中提交 Feature Request 或提交 Bug。
下载地址: https://infinilabs.cn/download
邮件:hello@infini.ltd
电话:(+86) 400-139-9200
Discord:https://discord.gg/4tKTMkkvVX
也欢迎大家微信扫码添加小助手(INFINI-Labs),加入用户群一起讨论交流。

关于极限科技(INFINI Labs)

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
Easysearch ZSTD 基准测试:高压缩率下实现近 5 倍查询吞吐
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 4698 次浏览 • 2026-03-17 12:41
在搜索引擎领域,压缩算法的选择一直是一个经典的权衡难题:
- 选择高压缩率(如
best_compression/ DEFLATE),磁盘省了,但查询解压慢; - 选择高速编码(如默认 LZ4),查询快了,但磁盘占用大。
Easysearch 引入了基于 JDK 21 FFM(Foreign Function & Memory API) 直连本地 ZSTD 动态库的加速方案,试图打破这一困局。为了验证效果,我们在完全对等的环境下,对 Easysearch(ZSTD)和 Elasticsearch 7.10.2(best_compression)进行了一次严格的查询吞吐对比测试。
结果令人振奋——即使在系统明显背景负载下,Easysearch 也没有因为高压缩而变慢,反而在查询吞吐上实现了近 5 倍提升。
测试环境
为确保对比公平,两套集群的硬件资源、JVM 配置、数据规模、索引结构完全对齐:
| 配置项 | Easysearch | Elasticsearch 7.10.2 |
|---|---|---|
| 节点数 | 3 | 3 |
| JVM 堆内存 | 12GB × 3 | 12GB × 3 |
| node.processors | 16 × 3 | 16 × 3 |
| 文档数 | 10,000,000 | 10,000,000 |
| 主分片 / 副本 | 3 / 0 | 3 / 0 |
| 数据类型 | nginx 访问日志 | nginx 访问日志 |
| 字段数 | 17 | 17 |
| mapping | 完全一致(MD5 校验) | 完全一致(MD5 校验) |
| Stored fields 压缩模式 | ZSTD (JDK21 FFM/native, level=3) | best_compression (DEFLATE) |
压缩机制对比:
best_compression映射到 LuceneBEST_COMPRESSION;在 stored fields 路径上,压缩实现为DeflateWithPresetDictCompressionMode,内部使用java.util.zip.Deflater/Inflater(即 DEFLATE)。 Easysearch ZSTD 当前走 JDK 21 FFM 绑定本地 zstd 库(java.lang.foreign);index.compression.zstd.jni=true为当前这套实现的启用方式。
查询模型:JMeter 随机 match 查询,随机命中 service_name、method、error_code、url 四个字段,每次返回 10 条文档。
压测起始负载(_cat/nodes 快照):
| 负载项 | Easysearch run | Elasticsearch run |
|---|---|---|
| load_1m | 29.74 | 25.27 |
| load_5m | 27.10 | 28.15 |
| load_15m | 26.09 | 36.96 |
| ram.percent | 99 | 99 |
说明:压测并非在空闲机上进行,而是在已有明显背景负载的生产式环境下完成。
核心结果
1. 查询吞吐量(QPS):在高背景负载下,Easysearch 仍领先 372%
稳态阶段(3 轮平均),Easysearch 的查询吞吐是 Elasticsearch 的 4.7 倍:
| 指标 | Elasticsearch (DEFLATE) | Easysearch (ZSTD) | 差异 |
|---|---|---|---|
| 稳态 QPS | 532.8 | 2,518.0 | +372.6% |
| 平均响应时间 | 779.0 ms | 164.3 ms | -78.9% |
| 稳态 CPU 占用(系统总占用) | 92.43% | 89.59% | 仅作背景参考 |
注:压测期间服务器存在明显背景负载(其他进程占用较高),该 CPU 指标是系统总占用,不等价于“仅搜索进程”的纯业务 CPU 对比。
在系统总 CPU 均接近 90% 的背景下,Easysearch 仍达到接近 5 倍吞吐。
查询吞吐量 QPS 对比(稳态均值)
2. 响应时间:从近 1 秒降到 164 毫秒
平均响应时间对比(ms,越低越好)
用户体感上,这意味着:同样一个搜索请求,Elasticsearch 还在等解压,Easysearch 已经把结果送到了客户端。
3. 各轮次详细数据
各轮次 QPS 趋势
各轮次平均响应时间趋势(ms)
4. CPU 使用效率:每 1% CPU 产出的 QPS 差距惊人
单看 CPU 占用率,两者似乎差不多(89.59% vs 92.43%)。但如果换一个视角——每消耗 1% CPU 能产出多少 QPS,差距就一目了然了:
| 指标 | Elasticsearch (DEFLATE) | Easysearch (ZSTD) | 倍数 |
|---|---|---|---|
| 稳态 QPS | 532.8 | 2,518.0 | — |
| 稳态 CPU | 92.43% | 89.59% | — |
| QPS / 1% CPU | 5.76 | 28.10 | 4.88× |
CPU 使用效率:每 1% CPU 产出的 QPS
这意味着什么?
- ES 使用 DEFLATE(best_compression)时,解压路径更可能成为 CPU 热点;结合 ES 的高 CPU(92.43%)与较低 QPS,说明单位 CPU 产出偏低;
- Easysearch 使用 ZSTD(JDK21 FFM/native)时,解压开销更小;在相近 CPU 水位(89.59%)下获得更高 QPS,单位 CPU 产出明显更高。
换句话说,当前这组实测更支持“ZSTD 在该查询模型下单位 CPU 产出更高”。
5. 存储空间:ZSTD 并未膨胀
| 索引 | 压缩算法 | 磁盘占用 |
|---|---|---|
| nginx_best_10m (ES) | best_compression (DEFLATE) | 1.8 GB |
| nginx_zstd3 (Easysearch) | ZSTD (level=3, JDK21 FFM/native) | 1.9 GB |
两者存储空间接近。若按 _cat/indices 的 1 位小数展示是 1.8GB vs 1.9GB;若按 _stats/store 字节值计算,差异约 2.5%。因此可以认为 ZSTD 在 level=3 下与 DEFLATE best_compression 压缩率接近。
磁盘占用对比(GB)
为什么 ZSTD 能做到"又小又快"?
传统认知中,压缩率和解压速度是一对矛盾。但 ZSTD 算法天然具备非对称压缩的特性:
压缩算法特性对比
在搜索引擎场景中,查询会触发存储字段(_source)读取与解压路径,命中文件系统页缓存时,可能不发生实际磁盘 I/O,但仍需进行 _source 解压。
当查询涉及较多 _source 读取时:
- DEFLATE 的解压开销成为 CPU 瓶颈,拖慢了整体吞吐;
- ZSTD(JDK21 FFM/native) 的解压速度在该场景下明显更优,单次请求的解压 CPU 成本更低,从而释放出更多 CPU 资源用于并发查询处理。
这就是为什么 Easysearch 在 CPU 占用更低(89.59% vs 92.43%)的情况下,反而能处理近 5 倍的查询量。
一张图总结
Easysearch ZSTD vs Elasticsearch DEFLATE — 全维度对比
结论
Easysearch 的 ZSTD 压缩方案证明了一个事实:即使在高背景负载下,高压缩率和高查询性能依然可以兼得。
在 1000 万条 nginx 日志、且系统存在明显背景负载的实测中:
- 查询吞吐提升 372%,从 533 QPS 跃升至 2518 QPS
- 平均响应时间下降 79%,从 779ms 降至 164ms
- CPU 使用效率提升 388%,每 1% CPU 产出 28.10 QPS vs 5.76 QPS
- CPU 占用绝对值下降 2.84 个百分点(相对下降约 3.07%)
- 磁盘占用与 DEFLATE best_compression 接近(按字节口径约 +2.5%)
对于日志分析、可观测性、安全审计等需要兼顾存储成本和查询性能的场景,Easysearch ZSTD 是一个不需要妥协的选择。
ZSTD 使用方法
1) 新建索引时启用 ZSTD
curl -k -u 'admin:<password>' -X PUT 'https://127.0.0.1:9200/<index-name>' \
-H 'Content-Type: application/json' -d '{
"settings": {
"index.codec": "ZSTD",
"index.compression.zstd.jni": true
}
}'
可选参数:
index.compression.zstd.level(默认3)
说明:
index.compression.zstd.dict固定为true,无需单独配置index.compression.zstd.dict不作为独立开关来调整
2) 老索引切换到 ZSTD(推荐 reindex)
index.codec 是静态设置(打开状态不可动态改;可在关闭索引后调整)。
index.compression.zstd.jni 是 final 设置(关闭索引后也不可修改)。
如果老索引要启用 index.compression.zstd.jni=true,建议新建目标索引后 reindex 迁移:
如果对已有索引执行 PUT /<index-name>/_settings 直接修改,会报错:final <index-name> setting [index.compression.zstd.jni], not updateable。
# 先创建目标索引(启用 ZSTD)
curl -k -u 'admin:<password>' -X PUT 'https://127.0.0.1:9200/<target-index>' \
-H 'Content-Type: application/json' -d '{
"settings": {
"index.codec": "ZSTD",
"index.compression.zstd.jni": true
}
}'
# 再迁移数据
curl -k -u 'admin:<password>' -X POST 'https://127.0.0.1:9200/_reindex' \
-H 'Content-Type: application/json' -d '{
"source": { "index": "<source-index>" },
"dest": { "index": "<target-index>" }
}'
3) 校验是否生效
curl -k -u 'admin:<password>' \
'https://127.0.0.1:9200/<index-name>/_settings?include_defaults=true&pretty'
重点确认:
index.codec = ZSTDindex.compression.zstd.jni = true
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
官网文档:https://docs.infinilabs.com/easysearch
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
相关文章:
【搜索客社区日报】第2193期 (2026-03-06)
社区日报 • Fred2000 发表了文章 • 0 个评论 • 3036 次浏览 • 2026-03-06 10:28
极限科技荣膺 2025 金猿奖 — “年度国产化优秀代表厂商”,自主可控搜索方案 Easysearch 获行业高度认可
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 24813 次浏览 • 2026-01-16 17:41
近日于上海明捷万丽酒店成功举办的 “2025 第八届金猿大数据产业发展论坛 — 暨 AI Infra & Data Agent 趋势论坛” 大会上,极限数据(北京)科技有限公司(以下简称“极限科技”) 凭借其在分布式搜索型数据库领域的技术突破与卓越的国产化实践,成功入选《2025 中国大数据产业「年度国产化优秀代表厂商」》榜单,并获颁这一行业重磅奖项。

本届论坛由金猿组委会、数据猿、上海市数商协会及上海大数据联盟联合主办,以“数据有猿·智见十年”为主题,吸引了近千家企业参与申报。经过严格的初审、公审与终审交叉验证机制,极限科技最终从众多竞争者中脱颖而出,荣登榜单。

深耕核心搜索技术,填补国产化空白
极限科技成立于 2021 年 12 月,是一家专注于大数据搜索与分析的基础软件公司。公司总部位于北京,在长沙设立研发中心,并在上海、广州设立办事处或服务中心。其核心团队均来自 Elasticsearch 原厂及中文社区,拥有多年 ES 源码开发经验,致力于“让搜索更简单”,打造极致易用的数据探索与分析体验。
公司自主研发的核心产品 Easysearch 搜索型数据库,是我国在分布式搜索型数据库领域实现关键国产化替代的代表性成果。该产品精准填补了国内在轻量化、高性能、自主可控搜索引擎方面的市场空白。
产品性能卓越,实现无缝迁移与超越
Easysearch 支持结构化与非结构化数据检索、全文检索、向量检索、空间地理位置信息检索、多模态混合检索、组合查询、多语种支持、语义分析、聚合分析等多种核心功能。测试表明,其性能已达到甚至优于国外领先产品。
在产品能力上,Easysearch 不仅完全兼容 Elasticsearch 的生态接口,保障了用户业务的无缝平滑迁移,更在性能优化、存储效率、企业级安全及原生中文处理等方面实现了显著超越。其内置的 Web 管理控制台、全面的数据加密与权限管控功能,提供了开箱即用的企业级体验。
构建完整信创生态
尤为关键的是,Easysearch 率先完成了与国产主流 CPU(如鲲鹏、飞腾、海光、龙芯、申威、兆芯等)和操作系统(如统信 UOS、银河麒麟、开源欧拉等)的深度适配与互认证,构建了完整的信创技术栈支持能力,彻底解决了国外产品在国产化环境下兼容性差、维护困难、更新受限等长期存在的痛点。
在核心技术国产化意义上,Easysearch 通过完全自主可控的分布式搜索技术体系,突破了关键基础软件依赖国外企业的局面,满足了政府、金融、能源、运营商等行业对“可控、安全、可替代”的战略需求。同时,其向量搜索和 AI 检索能力填补了国内在智能搜索与大模型结合领域的技术缺口。
获权威资质认可,落地众多头部客户
极限科技及 Easysearch 已获得多项权威资质认证,包括国家高新技术企业、ISO 三大管理体系认证,并荣获 2023 年星河案例数据库标杆案例。产品亦通过了信通院基础能力专项测评及中国泰尔实验室检验测试。
目前,Easysearch 已在金融、运营商、制造、政企等多领域实现规模化落地,服务客户包括移动云、中国一汽、中国人保、东莞证券、航天信息等头部企业,累计下载部署量已超过 500 万次。其中,公司开发的中文分词器(IK、Pinyin)、压测工具(Loadgen)、数据迁移工具(ESM)已被 85% 的中国 Elasticsearch 用户部署在生产环境中。
荣获行业大奖,彰显标杆价值
此次荣获 “年度国产化优秀代表厂商” 奖项,不仅是行业对极限科技技术实力与国产化贡献的高度认可,更彰显了公司在推动大数据产业自主创新进程中的标杆作用。
极限科技创始人表示:
“我们坚信‘追求极致,无限可能’。获得这份荣誉,是对我们团队多年来坚持自主创新、深耕搜索技术的最好鼓励。未来,极限科技将持续加大研发投入,以技术创新驱动产业升级,为各行业客户提供更高效、更安全、更智能的数据探索与分析能力,助力中国大数据产业在智能时代实现高质量、自主可控的发展。”
相关链接:
APM(二):监控 Python 服务
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 15687 次浏览 • 2025-12-31 18:04
上一篇我们已经安装好了 Skywalking 和 Easysearch,这次我们来写个简单的 Python 服务,并把它的服务调用信息发送给 Skywalking,通过 Skywalking 的 Web UI 进行展示。
启动后端服务
先启动好后端服务,包括 Skywalking 和 Easysearch。启动完成后能通过 Web UI 访问 Skywalking。

构建 Python 服务
我们编写一个简单的 Flask 服务程序,只要访问 localhost:8081/a 就会返回 "Hello, I'm Service A!" 信息。
from flask import Flask
app = Flask(__name__)
@app.route('/a', methods=['GET'])
def service_b():
return "Hello, I'm Service A!"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8081)
运行前,要安装好依赖。
pip3 install flask
pip3 install apache-skywalking
依赖关系展示如下:

设置环境变量
为了让服务能成功把相关信息发送到 Skywalking 后端,启动前我们还要设置两个环境变量告诉服务程序该往哪里发送信息。
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800
export SW_AGENT_NAME=AService-python
启动 Python 程序
一切准备妥当后,运行我们的服务程序。
sw-python run python3 AService.py
程序启动后会监听 8081 端口。

我们通过浏览器访问下。

在 Skywalking 的 Web UI 上查看服务的信息是否采集到。




可以看到服务 A 的调用信息都已经被记录到 Skywalking 中了。
作者:杨帆,极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。
INFINI Labs 产品更新 | Coco AI v0.10 × Easysearch v2.0 联袂上线:UI 全面重构,体验焕然一新
资讯动态 • INFINI Labs 小助手 发表了文章 • 0 个评论 • 12080 次浏览 • 2025-12-20 16:34

此次更新主要包括 Coco AI v0.10.0 更换全新的 UI 组件,服务端新增 milvus 和 dropbox 连接器;Easysearch v2.0.2 正式发布, 新增嵌入文档语义搜索,优化内置 UI 响应速度,无需依赖 Kibana,实现集群“开箱即管”;INFINI Console、Gateway、Agent、Loadgen v1.30.1 统一基于 Framework v1.4.0 升级,优化本地磁盘队列数据消费。详情见 Release Notes。
Coco AI 0.10
Coco AI 是一款完全开源、跨平台的企业级智能搜索与助手系统,专为现代企业打造。它通过统一搜索入口,连接企业内外部的异构数据源,融合大模型能力,帮助团队高效访问知识,智能决策协作。
Coco AI 本次详细更新记录如下:
Coco AI 客户端 0.10
🚀 功能特性 (Features)
- 扩展程序 UI 支持可调整窗口大小

- 添加打开按钮以启动已安装的扩展程序

✈️ 改进优化 (Improvements)
- 将应用程序和文件搜索视为普通扩展
- 通过深度链接安装扩展失败时,显示错误消息(而非错误代码)
- 用 shadcn/ui 组件替换旧组件

🐛 问题修复(Bug Fixes)
- 修复输入框高度异常问题
- 为 Extension.minimum_coco_version 实现自定义序列化
Coco AI 服务端 0.10
🚀 功能特性 (Features)
- 新增 milvus 连接器

- 新增 dropbox 连接器

🐛 问题修复(Bug Fixes)
- 修复搜索 API 中图标绝对 URL 的解析问题
- 修复集成商店读取剪贴板数据后的显示问题
✈️ 改进优化 (Improvements)
- 移除分页并在全屏模式下添加无限滚动
Easysearch v2.0.2
INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
Easysearch 本次更新如下:
💥 重大变更(Breaking Changes)
- 正式发布 Easysearch 2.0.2 版本,底层 Lucene 更新到 9.12.2
- 新增 ui 插件,为 Easysearch 提供了轻量级界面化管理功能,不再依赖第三方对集群进行管理,真正做到开箱即用
🚀 功能特性 (Features)
- 语义搜索新增支持 NestedQueryBuilder
- KNN mapping 的 L 和 k 参数支持大小写不敏感,提升易用性
✈️ 改进优化 (Improvements)
- UI 插件静态文件支持 gzip 压缩,加快页面加载
- 优化了图标资源大小
- 调整了内部构建流程和 CSP 策略
🐛 问题修复(Bug Fixes)
- 修复了开发者工具的主题颜色显示问题
Console v1.30.1
INFINI Console 是一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台。通过对流行的搜索引擎基础设施进行跨版本、多集群的集中纳管,企业可以快速方便的统一管理企业内部的不同版本的多套搜索集群。
Console 本次详细更新记录如下:
🚀 功能特性 (Features)
- 支持 Easysearch 2.x 和 Opensearch 3.x
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Console 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Console 受益。
Gateway v1.30.1
INFINI Gateway 是一个开源的面向搜索场景的高性能数据网关,所有请求都经过网关处理后再转发到后端的搜索业务集群。基于 INFINI Gateway 可以实现索引级别的限速限流、常见查询的缓存加速、查询请求的审计、查询结果的动态修改等等。
Gateway 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Gateway 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Gateway 受益。
Agent v1.30.1
INFINI Agent 负责采集和上传 Elasticsearch, Easysearch, Opensearch 集群的日志和指标信息,通过 INFINI Console 管理,支持主流操作系统和平台,安装包轻量且无任何外部依赖,可以快速方便地安装。
Agent 本次更新如下:
🚀 功能特性 (Features)
- 在 Kubernetes 环境下通过环境变量 http.port 探测 Easysearch 的 HTTP 端口
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Agent 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Agent 受益。
Loadgen v1.30.1
INFINI Loadgen 是一款开源的专为 Easysearch、Elasticsearch、OpenSearch 设计的轻量级性能测试工具。
Loadgen 本次更新如下:
✈️ 改进优化 (Improvements)
- 此版本包含了底层 Framework v1.4.0 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Loadgen 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Loadgen 受益。
Framework 1.4.0
INFINI Framework 是 INFINI Labs 基于 Golang 的产品的核心基础,已开源。该框架以开发者为中心设计,简化了构建高性能、可扩展且可靠的应用程序的过程。
Framework 本次更新如下:
🚀 功能特性 (Features)
- 为 curl 添加 p12 证书支持(#239)
- 从 util 中移除 curl(#242)
- 优先使用集群名称(#243)
- 为 access_token 添加标签(#244)
- 为用户主体(principal)添加头像配置(#246)
🐛 问题修复 (Bug Fixes)
- 修复重复写入和未写入的问题(#234)
- 当 filePath 为绝对路径时,检查其是否存在(#241)
✈️ 改进 (Improvements)
- 改进 TryGetFileAbsPath() 的 panic 错误信息(#240)
更多详情请查看以下各产品的 Release Notes 或联系我们的技术支持团队!
- Coco AI App
- Coco AI Server
- INFINI Easysearch
- INFINI Gateway
- INFINI Console
- INFINI Agent
- INFINI Loadgen
- INFINI Framework
期待反馈
欢迎下载体验使用,如果您在使用过程中遇到如何疑问或者问题,欢迎前往 INFINI Labs Github(https://github.com/infinilabs) 中的对应项目中提交 Feature Request 或提交 Bug。
下载地址: https://infinilabs.cn/download
邮件:hello@infini.ltd
电话:(+86) 400-139-9200
Discord:https://discord.gg/4tKTMkkvVX
也欢迎大家微信扫码添加小助手(INFINI-Labs),加入用户群一起讨论交流。

关于极限科技(INFINI Labs)

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。
极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。
Easy-Es 2.1.0-easysearch 版本发布
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9365 次浏览 • 2025-12-15 17:42

01 | 版本更新概述
经过极限科技与 Dromara 开源社区下 Easy-Es 项目的紧密合作与共同努力,我们很荣幸地联合推出 Easy-Es 2.1.0-easysearch 版本!
作为双方携手打造的第一个合作成果,本版本已正式发布:
- 源码仓库:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch/
- Maven 依赖:https://mvnrepository.com/artifact/org.dromara.easy-es/easy-es-boot-starter/2.1.0-easysearch
本次更新的核心内容是将 Easy-Es 框架底层增加兼容极限科技自主研发的 Easysearch 搜索引擎,这标志着国产搜索引擎与国内优秀开源项目深度融合的重要里程碑,是极限科技与 Dromara 社区携手共建国产技术生态的创新实践。
02 | 迁移至 Easysearch 的背景与优势
随着国内对自主可控技术需求的日益增长,特别是在基础设施软件领域,企业对于信创合规的要求不断提升。极限科技自主研发的 Easysearch 搜索引擎具备以下显著优势:
- 国产化自主可控:完全自主研发,符合信创要求,无许可证风险,为企业提供安全可靠的技术保障
- 轻量级架构:相比传统搜索引擎,资源占用更少,启动更快速,显著降低企业运维成本
- 卓越性能表现:查询性能优异,能够满足大部分业务场景需求,用户体验流畅
- 良好兼容性:与 Elasticsearch 的 API 接口基本兼容,迁移成本较低,保护用户现有投资
基于以上优势,双方决定共同将 Easy-Es 框架底层迁移至 Easysearch,这不仅为用户提供更多选择,更是双方携手推动国产搜索引擎生态建设的重要举措。
03 | Easy-Es 框架优势
Easy-Es 框架在搜索开发领域具备以下核心优势:
- 极简代码开发:相比原生 API 可减少 50%-80% 的代码量,大幅提升开发效率。
// 使用 Easy-Es 仅需一行代码完成查询
List<Document> documents = documentMapper.selectList(
EsWrappers.lambdaQuery(Document.class).eq(Document::getTitle, "测试")
);
-
自动索引管理: 框架提供全自动智能索引托管功能,开发者无需关心索引的创建、更新及数据迁移等复杂操作,索引全生命周期由框架自动管理,过程零停机。
-
SQL 语法兼容: 支持使用 MySQL 语法完成搜索查询操作,无需学习复杂的 DSL 语句。支持 and、or、like、in 等常用 SQL 语法。
-
Lambda 表达式支持: 采用 Lambda 风格编程,提供类型安全的字段访问,避免手动输入字段名可能产生的错误,提升代码可读性和开发效率。
-
无缝 Spring Boot 集成: 与 Spring Boot 生态深度集成,提供开箱即用的自动配置,无需复杂的手动配置,支持 Spring Boot Actuator 监控,完美融入企业级应用架构。
-
丰富的查询功能: 支持复杂的嵌套查询、聚合查询、范围查询、高亮显示等高级搜索功能,同时保持 API 的简洁易用,满足各种业务场景需求。
-
分布式架构支持: 完美适配 Easysearch 的分布式特性,支持集群模式部署,具备高可用性和横向扩展能力,满足企业级大规模数据处理需求。
- 成熟稳定的国产 ORM 框架: 作为 Dromara 开源社区下的顶级开源项目,Easy-Es 已在国内众多企业和项目中得到广泛应用和验证,拥有活跃的中文社区和完善的文档支持,为企业级应用提供了可靠的技术保障。
04 | 快速上手示例
1. 添加依赖
根据您使用的构建工具,选择对应的配置方式:
Maven 项目
pom.xml 配置:
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<spring-boot.version>2.7.0</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.dromara.easy-es</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>2.1.0-easysearch</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Maven 启动命令:
# 运行应用
mvn spring-boot:run
# 编译打包
mvn clean package
Gradle 项目
build.gradle 配置:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}
group = 'org.easysearch'
version = '1.0-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.dromara.easy-es:easy-es-boot-starter:2.1.0-easysearch'
implementation 'org.springframework.boot:spring-boot-starter-web'
}
Gradle 启动命令:
# 运行应用
./gradlew bootRun
# 编译打包
./gradlew clean build
2. 配置文件设置
application.yml(根据实际 Easysearch 部署情况修改):
easy-es:
enable: true
# Easysearch 服务地址
address: localhost:9200
# 协议:http 或 https
schema: https
# Easysearch 用户名
username: admin
# Easysearch 密码
password: your_password_here
# 连接保持时间(毫秒)
keep-alive-millis: 18000
global-config:
# 开启彩蛋模式(启动时显示 ASCII 艺术图案)
i-kun-mode: true
# 索引处理模式:smoothly 表示平滑模式(零停机更新索引)
process-index-mode: smoothly
# 异步处理索引时是否阻塞
async-process-index-blocking: true
# 是否打印 DSL 语句(开发调试时可设为 true)
print-dsl: false
db-config:
# 下划线转驼峰
map-underscore-to-camel-case: true
# 索引前缀
index-prefix: dev_
# 主键类型:customize 表示自定义
id-type: customize
# 字段更新策略:not_empty 表示非空时才更新
field-strategy: not_empty
# 刷新策略:immediate 表示立即刷新
refresh-policy: immediate
# 开启追踪总命中数
enable-track-total-hits: true
3. 实体类定义
package org.dromara.easyes.sample.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import org.dromara.easyes.annotation.HighLight;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexId;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.annotation.Settings;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldStrategy;
import org.dromara.easyes.annotation.rely.FieldType;
import org.dromara.easyes.annotation.rely.IdType;
import java.time.LocalDateTime;
/**
* es 数据模型
*/
@Data
@Accessors(chain = true)
@Settings(shardsNum = 3, replicasNum = 2)
@IndexName(value = "easyes_document", keepGlobalPrefix = true)
public class Document {
/**
* es 中的唯一 id
*/
@IndexId(type = IdType.CUSTOMIZE)
private String id;
/**
* 文档标题,默认为 keyword 类型,可进行精确查询
*/
private String title;
/**
* 文档内容,指定为 TEXT 类型,使用 IK 分词器
* 支持高亮显示,高亮结果映射到 highlightContent 字段
*/
@HighLight(mappingField = "highlightContent")
@IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART)
private String content;
/**
* 创建者,字段策略为非空时才更新
*/
@IndexField(strategy = FieldStrategy.NOT_EMPTY)
private String creator;
/**
* 创建时间
*/
@IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime gmtCreate;
/**
* 高亮返回值被映射的字段
*/
private String highlightContent;
/**
* 文档点赞数
*/
private Integer starNum;
/**
* 地理位置经纬度坐标,例如: "40.13933715136454,116.63441990026217"
*/
@IndexField(fieldType = FieldType.GEO_POINT)
private String location;
}
4. Mapper 接口
package org.dromara.easyes.sample.mapper;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.sample.entity.Document;
/**
* Mapper 接口,继承 BaseEsMapper 即可获得所有 CRUD 方法
*/
public interface DocumentMapper extends BaseEsMapper<Document> {
}
5. 启动类配置
package org.dromara.easyes.sample;
import org.dromara.easyes.spring.annotation.EsMapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动类
*/
@SpringBootApplication
@EsMapperScan("org.dromara.easyes.sample.mapper")
public class EasyEsApplication {
public static void main(String[] args) {
SpringApplication.run(EasyEsApplication.class, args);
}
}
6. 业务使用示例
package org.dromara.easyes.sample.controller;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.dromara.easyes.sample.entity.Document;
import org.dromara.easyes.sample.mapper.DocumentMapper;
import org.easysearch.action.search.SearchResponse;
import org.easysearch.search.aggregations.Aggregations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
@RestController
public class SampleController {
@Resource
private DocumentMapper documentMapper;
/**
* 初始化插入数据
*/
@GetMapping("/insert")
public Integer insert() {
int count = 0;
// 插入 5 条测试数据
for (int i = 1; i <= 5; i++) {
Document document = new Document();
document.setId(String.valueOf(i));
document.setTitle("测试" + i);
document.setContent("测试内容" + i);
document.setCreator("创建者" + i);
document.setGmtCreate(LocalDateTime.now());
document.setStarNum(i * 10);
count += documentMapper.insert(document);
}
return count;
}
/**
* 根据标题精确查询
*/
@GetMapping("/listDocumentByTitle")
public List<Document> listDocumentByTitle(@RequestParam String title) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.eq(Document::getTitle, title);
return documentMapper.selectList(wrapper);
}
/**
* 高亮搜索
*/
@GetMapping("/highlightSearch")
public List<Document> highlightSearch(@RequestParam String content) {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.match(Document::getContent, content);
return documentMapper.selectList(wrapper);
}
/**
* 查询所有数据
*/
@GetMapping("/selectAll")
public List<Document> selectAll() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
return documentMapper.selectList(wrapper);
}
/**
* 聚合查询 - 按创建时间和点赞数分组统计
*/
@GetMapping("/aggByDateAndStar")
public Aggregations aggByDateAndStar() {
LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
wrapper.groupBy(Document::getGmtCreate)
.max(Document::getStarNum)
.min(Document::getStarNum);
SearchResponse response = documentMapper.search(wrapper);
return response.getAggregations();
}
/**
* 使用 SQL 语句查询文档
*/
@GetMapping("/queryBySQL")
public String queryBySQL(@RequestParam(required = false) String title) {
String sql;
if (title != null && !title.isEmpty()) {
sql = String.format("SELECT * FROM dev_easyes_document WHERE title = '%s'", title);
} else {
sql = "SELECT * FROM dev_easyes_document LIMIT 10";
}
return documentMapper.executeSQL(sql);
}
}
7. 快速测试
启动应用后,可以通过以下接口测试:
# 1. 插入测试数据
curl http://localhost:8080/insert
# 2. 查询所有数据
curl http://localhost:8080/selectAll
# 3. 根据标题精确查询
curl "http://localhost:8080/listDocumentByTitle?title=测试1"
# 4. 高亮搜索
curl "http://localhost:8080/highlightSearch?content=测试"
# 5. SQL 查询
curl "http://localhost:8080/queryBySQL?title=测试1"
# 6. 聚合查询
curl http://localhost:8080/aggByDateAndStar
05 | 相关链接
- Easy-Es 官方网站:https://easy-es.cn
- Gitee 仓库:https://gitee.com/dromara/easy-es
- GitHub 仓库:https://github.com/dromara/easy-es
- Easysearch 官方网站:https://infinilabs.cn/products/easysearch
06 | 特别致谢
在此,极限科技要特别感谢 Easy-Es 项目的核心开发者“老汉”和各位贡献者和维护者们。正是因为有了你们的辛勤付出、专业精神以及对开源事业的热忱奉献,Easy-Es 项目才能在国内外获得如此广泛的认可和应用。
也感谢你们对国产技术生态建设的信任与支持。此次 Easy-Es 与 Easysearch 的深度整合,正是双方通力合作、互利共赢的最佳体现。
我们相信,在 Easy-Es 项目团队的持续推动下,国产开源软件必将迎来更加辉煌的明天。极限科技将继续致力于提供优质的国产技术解决方案,与 Easy-Es 项目团队携手共进,为中国开源生态的发展贡献更多力量!
关于 Easy-Es
Easy-Es(简称 EE)是一款基于 Elasticsearch(简称 ES)官方提供的 ElasticsearchClient 打造的 ORM 开发框架,在 ElasticsearchClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,您如果有用过 Mybatis-Plus(简称 MP),那么您基本可以零学习成本直接上手 EE,EE 是 MP 的 ES 平替版,在有些方面甚至比 MP 更简单,同时也融入了更多 ES 独有的功能,助力您快速实现各种场景的开发。
Easy-Es for Easysearch 是一款简化 Easysearch 国产化搜索引擎操作的开源框架,全自动智能索引托管。同时也是国内首家专门针对 Easysearch 客户端简化的工具。它简化 CRUD 及其它高阶操作,可以更好的帮助开发者减轻开发负担。底层采用 Easysearch Java Client,保证其原生性能及拓展性。
项目地址:https://gitee.com/dromara/easy-es/tree/easy-es4easySearch
关于极限科技
极限科技(全称:极限数据(北京)科技有限公司)是一家专注于实时搜索与数据分析的软件公司。
旗下品牌:极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验,为用户提供安全、稳定、高性能的国产搜索解决方案。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
Easysearch 2.0.0 性能测试
Easysearch • INFINI Labs 小助手 发表了文章 • 0 个评论 • 9326 次浏览 • 2025-12-04 00:17
概述
Easysearch 2.0.0 正式版带来了显著的性能提升和优化改进。通过与上一个稳定版本 1.15.6 的全面对比测试,我们使用 esrally 基准测试工具在 append-no-conflicts 场景下进行了深入的性能评估。测试结果表明,2.0.0 版本在索引性能、查询延迟、内存管理等核心指标上都实现了突破性改进。
核心性能提升
1. 索引性能更加稳定
写入效率提升 12.81%
Easysearch 2.0.0 索引性能表现更加稳定:
- 累计索引 CPU 时间(所有主分片):从 225.1 分钟缩短至 196.3 分钟,减少 28.8 分钟(-12.81%)
- 索引吞吐量:
- 平均吞吐量从 180,868 docs/s 提升至 190,712 docs/s(+5.44%)
- 最大吞吐量从 198,184 docs/s 提升至 220,460 docs/s(+11.24%)
- 最小吞吐量从 164,263 docs/s 提升至 178,961 docs/s(+8.95%)
累计索引 CPU 时间的减少,表明 2.0.0 版本在索引操作上更加高效,CPU 利用率更优。这意味着在相同硬件条件下,Easysearch 2.0.0 能够更快地完成数据摄入任务,对于需要处理大规模数据写入的场景具有重要意义。
Indexing Throughput (docs/s) - Higher is Better
2. Refresh 和 Flush 耗时缩短
Refresh 和 Flush 性能大幅改善
在 Elasticsearch/Easysearch 中,Refresh 和 Flush 操作对写入性能有直接影响。2.0.0 版本在这两个关键操作上实现了重大优化:
Refresh 性能提升 54.46%
- 累计刷新时间:从 9.14 分钟降至 4.16 分钟
- 中位刷新时间:减少 61.86%(从 0.133 分钟降至 0.051 分钟)
- 最大刷新时间:减少 65.62%(从 1.12 分钟降至 0.39 分钟)
Flush 性能提升 40%
- 累计刷盘时间:从 12.57 分钟降至 7.54 分钟
- 中位刷盘时间:减少 57.57%
- 最大刷盘时间:减少 31.93%
Cumulative Refresh Time (min) - Lower is Better
Cumulative Flush Time (min) - Lower is Better
这些优化使得 Easysearch 2.0.0 能够更高效地将数据持久化到磁盘,同时减少对写入操作的阻塞。
3. 垃圾回收(GC)性能优化
GC 效率显著提升
- Young GC 次数:从 525 次降至 426 次,减少 18.86%
- Young GC 时间:从 16.547 秒降至 15.985 秒,减少 3.40%
- Old GC:两个版本均无 Old GC 发生,内存管理健康
更少的 GC 次数意味着:
- 应用程序 STW(Stop-The-World)暂停更少
- 更稳定的查询响应时间
- 更好的系统吞吐量
查询性能提升
1. 基础查询延迟降低
多类型查询性能全面提升
| 查询类型 | 延迟指标 | 改进幅度 |
|---|---|---|
| Default 查询 | 50 分位延迟 | -11.40% (19.97ms → 17.69ms) |
| 99 分位延迟 | -15.23% (25.66ms → 21.75ms) | |
| Term 查询 | 50 分位延迟 | -19.88% (4049ms → 3244ms) |
| 90 分位延迟 | -18.73% (4137ms → 3362ms) | |
| Range 查询 | 50 分位延迟 | -31.71% (42.19ms → 28.81ms) |
| 100 分位延迟 | -64.68% (111.42ms → 39.35ms) |
Query Latency Improvements (ms) - Lower is Better
2. 排序查询性能飞跃
时间戳排序查询优化高达 97%
Easysearch 2.0.0 在排序查询场景下实现了令人瞩目的性能突破:
降序排序(desc_sort_timestamp)
- 50 分位延迟:从 516.07ms 降至 98.89ms(-80.84%)
- 90 分位延迟:从 544.84ms 降至 123.59ms(-77.32%)
- 99 分位延迟:从 603.14ms 降至 139.93ms(-76.80%)
升序排序 + After 分页(asc_sort_with_after_timestamp)
- 50 分位延迟:从 1272.58ms 降至 33.56ms(-97.36%)
- 90 分位延迟:从 1386.92ms 降至 37.25ms(-97.31%)
- 99 分位延迟:从 1474.98ms 降至 38.11ms(-97.42%)
Sort Query Latency (ms) - Lower is Better
Force Merge 后的排序查询
在强制合并为单段后,排序查询性能更加出色:
降序排序(force-merge-1-seg)
- 50 分位延迟:从 131,617ms 降至 115.01ms(-99.91%)
- 这一改进相当于从 2 分钟以上降至 0.1 秒!
升序 + After 分页(force-merge-1-seg)
- 50 分位延迟:从 1387.01ms 降至 132.42ms(-90.45%)
- 90 分位延迟:从 1509.03ms 降至 159.05ms(-89.46%)
3. 聚合查询性能提升
hourly_agg 聚合查询优化
- 50 分位延迟:从 4192.57ms 降至 3866.07ms(-7.79%)
- 90 分位延迟:从 4303.51ms 降至 4053.80ms(-5.80%)
- 99 分位延迟:从 4475.32ms 降至 4269.91ms(-4.59%)
4. Scroll 查询性能改进
大数据量遍历场景优化
- 50 分位延迟:从 6511.65ms 降至 4623.87ms(-28.99%)
- 90 分位延迟:从 6881.70ms 降至 5972.79ms(-13.21%)
- 平均吞吐量:从 24.192 pages/s 提升至 24.485 pages/s(+1.21%)
Scroll Query Latency (ms) - Lower is Better
5. 高百分位延迟大幅改善
极端场景下的稳定性提升
在衡量系统稳定性的高百分位延迟指标上,2.0.0 版本表现卓越:
| 场景 | 99.9 分位延迟改进 | 99.99 分位延迟改进 | 100 分位延迟改进 |
|---|---|---|---|
| index-append | -43.40% | -65.35% | -70.91% |
| (3364ms → 1904ms) | (9618ms → 3333ms) | (13427ms → 3906ms) |
这意味着即使在最坏的情况下,2.0.0 版本也能提供更加稳定和可预测的性能表现。
范围查询性能提升
200s-in-range 和 400s-in-range 查询优化
-
200s-in-range:
- 50 分位延迟降低 15.60%
- 吞吐量提升 1.20%
- 400s-in-range:
- 50 分位延迟降低 8.44%
- 吞吐量提升 0.23%
存储优化
磁盘空间使用更高效
- 存储大小:从 19.51 GB 降至 19.14 GB(-1.93%)
- 段数量:从 43 个增至 50 个(+16.28%)
虽然段数量略有增加,但总存储空间仍然减少,说明数据压缩和存储效率得到了提升。
Merge 策略调整
合并操作的权衡
需要注意的是,2.0.0 版本在 Merge 方面有以下变化:
- Merge 次数从 184 次增至 192 次(+4.35%)
- Merge 限流时间从 9.53 分钟增至 11.17 分钟(+17.20%)
这是为了平衡写入性能和查询性能所做的策略调整。用户可以根据实际场景需求,通过以下参数进行优化:
{
"index.merge.scheduler.max_thread_count": "1",
"index.merge.policy.max_merged_segment": "5gb"
}
技术架构改进
1. 段数据结构优化
通过将段元数据从堆内存迁移到堆外内存,Easysearch 2.0.0 实现了:
- 更低的 JVM 堆压力
- 更少的 GC 频率
- 更稳定的内存使用模式
- 更好的大数据集支持能力
2. 查询缓存优化
排序查询性能的巨大提升表明 2.0.0 版本可能在以下方面进行了优化:
- 改进的 Doc Values 访问机制
- 优化的排序算法
- 更高效的分页实现
- 智能的查询结果缓存
3. I/O 优化
Refresh 和 Flush 时间的大幅减少说明:
- 改进了磁盘 I/O 调度策略
- 优化了文件系统操作
- 可能引入了更高效的批量写入机制
适用场景
Easysearch 2.0.0 的性能提升使其在以下场景中表现更加出色:
1. 大规模日志与事件流处理
- 更高的写入吞吐量(+11.24% 峰值)
- 更低的索引延迟
- 适合 APM、日志分析、安全监控等场景
2. 时序数据存储与分析
- 时间戳排序查询性能提升高达 97%
- 适合 IoT、监控指标、金融交易数据等场景
3. 全文搜索应用
- 多类型查询延迟降低 10-30%
- 高并发场景下更稳定的响应时间
- 适合电商搜索、内容管理系统等场景
4. 实时分析与 Dashboard
- 聚合查询性能提升 5-8%
- 更低的极端延迟,用户体验更好
- 适合实时报表、业务 BI 等场景
5. 大数据量遍历与导出
- Scroll 查询延迟降低 29%
- 适合数据迁移、全量导出等场景
升级建议
兼容性
Easysearch 2.0.0 与 1.15.6 在 API 层面保持兼容,但建议:
- 测试环境验证:先在测试环境进行充分验证
- 配置审查:检查 Merge 相关配置是否需要调整
- 监控指标:升级后密切关注 GC、内存、延迟等指标
- 滚动升级:生产环境建议采用滚动升级方式
性能测试环境
本次测试使用 esrally 基准测试工具,测试配置如下:
- 测试场景:append-no-conflicts
- 测试时间:
- Baseline (1.15.6): 2025-11-14
- Contender (2.0.0): 2025-11-21
- 部署方式:External(独立部署)
- CPU 绑定:使用
taskset绑定 Easysearch 进程 0 到 15 cpu - JVM 配置:
-Xms16g -Xmx16g
总结
Easysearch 2.0.0 版本在性能方面取得了全面提升:
- 索引性能提升 12.81%
- 查询延迟降低 10-97%(不同场景)
- 内存使用优化 100%(堆内段数据)
- GC 频率降低 18.86%
- Refresh 性能提升 54.46%
- Flush 性能提升 40%
- 高百分位延迟改善 43-70%
这些改进使得 Easysearch 2.0.0 成为一个更加高效、稳定和可靠的搜索与分析引擎,特别适合处理大规模数据和实时查询场景。无论是日志分析、时序数据处理,还是全文搜索应用,2.0.0 版本都能提供更优秀的性能表现。
我们强烈建议用户升级到 Easysearch 2.0.0,以获得这些显著的性能提升和更好的使用体验。
关于 Easysearch

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。
作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
原文:https://infinilabs.cn/blog/2025/easysearch-2.0.0-performance-improvements/



