不要急,总有办法的

信创环境下部署 INFINI Gateway:为 Easysearch 构建高性能安全入口

INFINI Labs 小助手 发表了文章 • 0 个评论 • 2914 次浏览 • 5 天前 • 来自相关话题

引言


上一篇文章里,我们已经完成了 [Easysearch 在信创环境下的部署](https://infinilabs.cn/blog/202 ... tform/)。搜索服务能跑起来只是第一步,要让它真正用于生产,还需要补上“入口治理”这一环。

例如,下面这些问题在生产环境中非常常见:

  • 如何防止某个应用或用户发出超大查询请求,把 Easysearch 集群拖垮?
  • 如果 Easysearch 某个节点突然宕机,请求能不能自动切换到健康节点,让业务无感知?
  • 如何知道每天有多少次查询、哪些查询慢、哪些请求不合法,有没有办法对请求进行审计?

    这些正是 INFINI Gateway(极限网关) 擅长解决的问题。本文延续“小白友好”风格,带你完成 Gateway 的安装与验证,为 Easysearch 增加一层高性能、安全、可观测的入口防护。

    ![](https://infinilabs.cn/img/blog ... p1.png)

    一、INFINI Gateway 是什么?和 Easysearch 是什么关系?


    如果把 Easysearch 比作大型图书馆,那么 INFINI Gateway 就像门口的 “前台总台”。过去读者(应用程序)直接进入书库检索;现在所有请求先经过前台,再转发到书库。这样做的好处很直接:可以缓存热门请求,减少后端压力;可以限制流量,避免集群被突发请求冲垮;还可以记录访问日志,方便审计与分析。

    从技术层面讲,INFINI Gateway 的定位如下:

  • 高性能数据网关:面向搜索场景设计,请求先在网关完成处理,再转发到后端 Easysearch 集群。
  • 代理 + 增强:位于客户端与 Easysearch 之间,可在转发链路中叠加限流、缓存加速、请求审计、结果改写等能力。
  • 兼容原生 API:对外接口兼容 Elasticsearch / Easysearch 原生 API,应用只需把连接地址从直连 Easysearch 改为指向网关,无需改业务代码。
  • 轻量易部署:基于 Golang 开发,安装包约 10MB,无额外外部依赖。
  • 信创兼容认证:已通过华为鲲鹏 Kunpeng 920 兼容性认证,并获得 KUNPENG COMPATIBLE 证书。

    整个系列的组件关系如下:

    应用程序INFINI Gateway(流量入口)Easysearch(数据存储与检索)

    有了 Gateway,你就可以更放心地将搜索服务开放给更多应用和用户,而不必过度担心安全与性能失控问题。

    二、部署前置条件


    1. 信创环境


  • CPU :鲲鹏 Kunpeng-920、aarch64
  • 操作系统:统信服务器操作系统A版 V20

    2. 确保 Easysearch 已正常运行


    Gateway 本身不存储数据,核心职责是代理与增强 Easysearch。因此部署前请先确认 Easysearch 已启动,并且网络可达:

    bash<br /> curl -ku admin:你的密码 <a href="https://localhost:9200" rel="nofollow" target="_blank">https://localhost:9200</a><br />

    三、部署步骤


    步骤 1:下载 INFINI Gateway


    下面脚本会自动下载对应平台的 Gateway 最新版本,并解压到 /opt/gateway:

    ```bash

    一键下载并安装到 /opt/gateway

    curl -sSL http://get.infini.cloud | bash -s -- -p gateway -d /opt/gateway
    ```

    ![](https://infinilabs.cn/img/blog ... p2.png)

    步骤 2:编写 Gateway 配置文件


    Gateway 启动依赖 YAML 配置文件,用来声明监听端口、后端 Easysearch 地址和认证信息。进入安装目录后,找到 gateway.yml 并按实际环境修改:

    ```bash

    按实际情况填写可访问的 Easysearch 地址

    LOGGING_ES_ENDPOINT:https://localhost:9200/

    LOGGING_ES_USER:admin

    LOGGING_ES_PASS:"你的 Easysearch 密码"

    按实际情况填写可访问的 Easysearch 地址

    PROD_ES_ENDPOINT:https://localhost:9200/

    PROD_ES_USER:admin

    PROD_ES_PASS:"你的 Easysearch 密码"

    按需设置 Gateway 对外监听端口

    GW_BINDING:"0.0.0.0:8000"
    ```

    步骤 3:启动 Gateway


    进入 Gateway 安装目录,执行下面命令启动程序:

    ```bash

    进入安装目录

    cd /opt/gateway

    运行程序(gateway-linux-arm64 为可执行文件名)

    ./gateway-linux-arm64
    <br /> <br /> ![](<a href="https://infinilabs.cn/img/blog/2026/gateway-install-at-xc-platform/p3.pn" rel="nofollow" target="_blank">https://infinilabs.cn/img/blog ... p3.pn</a>g)<br /> ![](<a href="https://infinilabs.cn/img/blog/2026/gateway-install-at-xc-platform/p4.pn" rel="nofollow" target="_blank">https://infinilabs.cn/img/blog ... p4.pn</a>g)<br /> <br /> 程序启动后,即可通过配置端口访问 Easysearch 服务。<br /> <br /> ![](<a href="https://infinilabs.cn/img/blog/2026/gateway-install-at-xc-platform/p5.pn" rel="nofollow" target="_blank">https://infinilabs.cn/img/blog ... p5.pn</a>g)<br /> <br /> 在前台运行模式下,如需停止 Gateway,按 `Ctrl+C` 即可。<br /> <br /> ![](<a href="https://infinilabs.cn/img/blog/2026/gateway-install-at-xc-platform/p6.pn" rel="nofollow" target="_blank">https://infinilabs.cn/img/blog ... p6.pn</a>g)<br /> <br /> 如果希望将 Gateway 作为后台服务运行,可执行:<br /> <br /> bash

    命令中的 gateway-linux-arm64 为可执行文件名

    ./gateway-linux-arm64 -service install && ./gateway-linux-arm64 -service start
    <br /> <br /> 如需卸载服务,执行以下命令:<br /> <br /> bash
    ./gateway-linux-arm64 -service stop

    ./gateway-linux-arm64 -service uninstall
    ```

    步骤 4:验证 Gateway 是否正常工作


    通过 Gateway 间接访问 Easysearch,确认转发通路正常:

    ```bash

    通过 Gateway(8000 端口)访问 Easysearch

    curl http://0.0.0.0:8000

    对比直连 Easysearch 的结果

    curl -ku admin:你的密码 https://localhost:9200
    ```

    两条命令返回的 JSON 结果应基本一致。若都能正常响应,说明 Gateway 已成功接管 Easysearch 的访问入口。

    如果你的生产环境需要将搜索服务开放给大量应用和用户,建议将 Gateway 纳入标准部署方案。借助 Gateway,你可以更好地保护后端 Easysearch 集群,并获得限流限速、缓存加速、安全防护、审计日志等增强能力,让整体架构更健壮、更安全、更可观测。

    如果在部署过程中遇到问题,欢迎查阅[官方文档](https://docs.infinilabs.com/gateway/)。祝你部署顺利!

    ---

    作者:小袁
    原文:https://infinilabs.cn/blog/202 ... form/

国产统信 UOS 部署 Coco Server 全指南:从零搭建企业级 AI 搜索服务端

INFINI Labs 小助手 发表了文章 • 0 个评论 • 4142 次浏览 • 2026-06-09 14:19 • 来自相关话题


一、引言


在上一篇文章《[从零到跑起来:Easysearch 信创环境安装全流程](https://infinilabs.cn/blog/202 ... tform/)》中,我们成功在信创平台上安装并运行起了 Easysearch。但 Easysearch 是一个底层搜索引擎,直接操作有一定门槛。如果我们想让团队里的每个人都能方便地“搜文件、聊文档、问知识”,就需要一个更贴近日常使用、又能把 AI 能力融入进来的上层应用——这就是 Coco AI

本文将继续手把手带你从零开始,在国产统信 UOS 服务器操作系统上部署 Coco Server,并与已安装的 Easysearch 进行对接。全文依然零基础可读,跟着步骤一步步来即可。

二、Coco Server 是什么?它和 Easysearch 什么关系?


先对我们的产品进行一个简单的介绍:

  • Easysearch 是底层引擎,负责存储和检索数据,像汽车的发动机和底盘;
  • Coco Server 是基于 Easysearch 之上的服务端应用程序,提供 Web 管理界面、统一搜索、AI 聊天、知识库管理等高级功能,类似车身和智能驾驶系统;
  • Coco AI 桌面客户端则是连接 Coco Server 的终端软件,安装在个人电脑上使用。

    而在本文中部署的 Coco Server,是整个 Coco AI 体系的“大脑”:

  • 它负责连接各类数据源(飞书、语雀、GitHub、本地文件等);
  • 它管理大模型提供商(Deepseek、通义千问、OpenAI 等);
  • 它提供 Web 管理后台,让管理员可以可视化地完成所有配置。

    部署完成之后,团队成员只需通过客户端或浏览器,就能享受统一搜索与 AI 智能问答带来的便利。Coco AI 的整体架构图如下:

    ![](https://infinilabs.cn/img/blog ... p1.png)

    三、部署前置条件


    1. 进行服务器相关优化


    ```bash

    内核参数优化

    cat << SETTINGS | sudo tee /etc/sysctl.d/70-infini.conf
    fs.file-max = 10485760
    fs.nr_open = 10485760
    vm.max_map_count = 262145

    net.core.somaxconn = 65535
    net.core.netdev_max_backlog = 65535
    net.core.rmem_default = 262144
    net.core.wmem_default = 262144
    net.core.rmem_max = 4194304
    net.core.wmem_max = 4194304

    net.ipv4.ip_forward = 1
    net.ipv4.ip_nonlocal_bind = 1
    net.ipv4.ip_local_port_range = 1024 65535
    net.ipv4.conf.default.accept_redirects = 0
    net.ipv4.conf.default.rp_filter = 1
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_max_tw_buckets = 300000
    net.ipv4.tcp_timestamps = 1
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_max_syn_backlog = 65535
    net.ipv4.tcp_synack_retries = 0
    net.ipv4.tcp_keepalive_intvl = 30
    net.ipv4.tcp_keepalive_time = 900
    net.ipv4.tcp_keepalive_probes = 3
    net.ipv4.tcp_fin_timeout = 10
    net.ipv4.tcp_max_orphans = 131072
    net.ipv4.tcp_rmem = 4096 4096 16777216
    net.ipv4.tcp_wmem = 4096 4096 16777216
    net.ipv4.tcp_mem = 786432 3145728 4194304
    SETTINGS

    sysctl -p /etc/sysctl.d/70-infini.conf

    ```

    2. 环境前提:Easysearch 已经运行好


    Coco Server 运行强依赖 Easysearch,所以在继续之前,请确保你的信创服务器上已经安装并成功启动了 Easysearch。如果不确定,可以执行下面的命令验证:

    bash<br /> curl -k -u admin:你的密码 <a href="https://localhost:9200" rel="nofollow" target="_blank">https://localhost:9200</a><br />

    运行命令后,看到正常的 JSON 响应即可。

    如果还没有安装,可以参考上一篇文章《[从零到跑起来:Easysearch 信创环境安装全流程](https://infinilabs.cn/blog/202 ... tform/)》先行完成。

    3. 信创平台信息确认


    和 Easysearch 一样,你需要明确当前服务器的 CPU 架构和操作系统版本。在终端执行:

    ```bash

    查看 CPU 架构

    uname -m

    查看操作系统信息

    cat /etc/os-release
    ```

    根据输出,确认 CPU 架构和操作系统,后续下载时选择对应版本。

    部署环境如下表中所示:

    4. 软件环境


    | 名称 | 版本 | 备注 |
    | ----------------------- | ------ | ------------------ |
    | Coco AI 智能搜索软件 | V1.0.0 | Coco Server |
    | 统信服务器操作系统 A 版 | V20 | |
    | Easysearch 搜索型数据库 | V2.2.0 | 用于 Coco 数据存储 |
    | 360安全浏览器 | V13 | |

    5. Coco AI 大语言模型 推荐配置


    | 模型名称 | 上下文长度 | 最大输出长度 | 描述 |
    | ----------------------- | ---------- | ------------ | ---------------------------------------------------- |
    | deepseek-r1 | 128K | 16K | 数学、代码、自然语言推理等任务上,性能较高,能力较强 |
    | qwen3-max | 256K | 32K | 配场景复杂的智能体需求 |
    | tongyi-intent-detect-v3 | 8K | 8K | 用于意图识别和槽位填充,负责对话系统中的基础任务 |

    5. 网络端口配置


    | 服务名 | 端口 | 配置文件 | 说明 |
    | ----------------- | ------------ | --------------------- | ----------------------------------------------------------- |
    | Coco Server | 9000(默认) | coco.yml | |
    | INFINI Easysearch | 9200(默认) | config/easysearch.yml | 默认仅监控 127.0.0.0,可通过配置 network.host: 0.0.0.0 调整 |
    | | 9300(默认) | config/easysearch.yml | |

    四、部署步骤


    步骤 1:下载 Coco Server


    ```bash

    调整为 Coco 实际要安装的路径

    cd /opt

    下载Coco v1.0.0压缩包

    curl -O https://release.infinilabs.com ... 0.zip

    解压到当前文件夹

    unzip coco-1.0.0.zip

    选择对应的版本解压tar.gz文件

    tar -xzf coco-1.0.0-2002-linux-arm64.tar.gz

    解压后在对应文件夹下得到可执行程序coco-linux-arm64(arm64版本)和配置文件coco.yml

    ```

    步骤 2:配置 Easysearch 连接信息


    Coco Server 需要得到 Easysearch 的地址和登录凭证才能进行工作。

    在 安装路径的目录下,找到配置文件 进行配置,比如监听的端口地址 WEB_BINDING, 将 Easysearch 的服务地址环境变量 ES_ENDPOINT 和用户名 ES_USERNAME 设置为实际的,参考如下:

    ```plain
    env:

    调整为实际可以访问的 Easysearch 访问地址

    ES_ENDPOINT: https://localhost:9200

    调整为实际可以访问的 Easysearch 的用户

    ES_USERNAME: admin

    使用 keystore 存储的密码

    ES_PASSWORD: $[[keystore.ES_PASSWORD]]

    Coco Server 对外提供服务的端口(默认9000端口)

    WEB_BINDING: 0.0.0.0:9000
    ```

    步骤 3:使用keystore对密码进行加密处理


    Easysearch 的服务密码通过 Keystore 进行加密存放,避免明文存放到配置文件,减少数据泄露风险

    ```bash

    调整为 Coco 实际安装路径进行配置

    cd /opt

    创建 coco 软链接,可不区分 amd64/arm64 平台进行操作

    ln -s coco-linux-arch | grep -q "x86_64" && echo "amd64" || echo "arm64" coco

    根据之前拿到的 Easysearch 密码进行初始化 ES_PASSWORD 变量

    ES_PASSWORD=xxx

    将 ES_PASSWORD 变量的值存储到 keystore(./coco-linux-arm64替换为对应版本名,下同)

    echo "$ES_PASSWORD" | ./coco-linux-arm64 keystore add --stdin ES_PASSWORD

    检查 keystore 存储列表,确认 ES_PASSWORD 添加成功

    ./coco-linux-arm64 keystore list
    ```

    步骤 4:启动服务


    以上配置完成后,设置 Coco Server 以服务方式启动

    ```bash

    安装系统服务(./coco-linux-arm64替换为对应版本名,下同)

    ./coco-linux-arm64 -service install

    启动服务

    ./coco-linux-arm64 -service start
    ```

    ![](https://infinilabs.cn/img/blog ... p2.png)

    步骤 5:初始化设置


    服务启动后,在信创服务器的桌面环境下,打开浏览器,访问 UI 界面:

    http://localhost:9000/#/_guide/

    你将看到 Coco Server 的 Web 引导界面。因为是首次访问,所以需要创建管理员账号,按页面引导填写即可。

    ![](https://infinilabs.cn/img/blog ... p3.png)

    创建完管理员账户后,下一步

    设置一个模型提供商,Coco Server 支持:

  • Deepseek
  • Ollama
  • 任何和 OpenAI 格式兼容的模型提供商

    如果设置的模型是推理模型,需要打开“推理模式”。我们推荐使用参数较大的模型,来获得更好的使用体验。同时请注意:Endpoint 地址的配置要准确

    ![](https://infinilabs.cn/img/blog ... p4.png)

    Coco Server 默认配置了一些小助手,建议在初始化向导的时候直接配置一个可用的模型,这样进入系统之后就可以直接使用,避免一个个的手动配置。

    向导设置完成后,就会跳转到登录页面,输入刚才创建的账户和密码,就可以进行登录了,如下图:

    ![](https://infinilabs.cn/img/blog ... p5.png)

    管理员首次登录之后的第一件事是确认服务器的地址是否正确,如果 Coco server 前面增加了负载均衡或者配置了域名,需要在这里设置一下正确的 Coco Server 对外服务地址,如下图:

    ![](https://infinilabs.cn/img/blog ... p6.png)

    五、总结


    到这里,你已经完成了 Coco Server 在信创平台上的部署与初始化。我们回顾一下整个部署流程:

    1. 确认环境 — Easysearch 已部署成功,并明确 CPU 架构;
    2. 下载安装 — 下载 Coco Server 的压缩包进行解压;
    3. 配置连接 — 编辑 coco.yml,填入 Easysearch 端点和密码;
    4. 启动服务 — 将 Coco Server 以服务方式启动;
    5. 初始化 — 浏览器打开 http://localhost:9000/#/_guide/ 进行管理员账户的创建; 添加大模型、连接数据源、创建助手。

      Coco Server 部署完成后,你就拥有了一个完全私有化、自主可控的企业级统一搜索与 AI 智能助手服务端。下一步可以安装 [ Coco AI 桌面客户端](https://coco.rs/zh/download),让团队成员真正体验“一个搜索框搜遍全公司”的高效便捷。

      如果在部署过程中遇到任何困难,欢迎查阅[官方文档](https://docs.infinilabs.com/coco-server/main/ "官方文档"),祝你部署顺利!

Easysearch 信创环境安装实践

INFINI Labs 小助手 发表了文章 • 0 个评论 • 6454 次浏览 • 2026-06-05 18:10 • 来自相关话题

![](https://infinilabs.cn/img/blog ... er.png)

一、Easysearch 介绍


在动手安装之前,我们先花一点时间了解这个工具。
INFINI Easysearch (以下简称 Easysearch)是由极限科技(INFINI Labs)自主研发的一款分布式 AI 搜索型数据库。用通俗的话讲,它是一个“超级搜索引擎”,能帮你在海量数据中快速查找信息,支持结构化和非结构化的数据检索、全文检索、向量检索、空间地理位置信息检索、组合查询、多语种支持、语义分析和聚合分析等多种功能,被广泛应用于企业搜索、日志分析、知识库管理等场景。它的安装包仅50MB,非常轻量。

Easysearch 的“自主可控”特性十分突出:

  • 完全国产化:已适配龙芯、鲲鹏、飞腾、海光、兆芯、申威等主流国产 CPU;
  • 全面兼容国产操作系统:支持银河麒麟、统信 UOS、中标麒麟等国产操作系统;
  • 国密算法支持:全量支持 SM2/SM3/SM4 国密算法,满足等保三级及信创合规要求;
  • ES生态兼容:完全兼容 Elasticsearch 的 API 接口,可无缝平替。

    ![](https://infinilabs.cn/img/blog ... p1.png)

    二、安装前需知


    1.你的信创平台属于哪种?


    信创平台的组合通常是“国产 CPU + 国产操作系统”,你需要确认你的环境属于哪种:

    | 国产CPU | 架构 | 常见搭配操作系统 |
    | ---------------- | :-------: | -------------------- |
    | 鲲鹏(Kunpeng) | ARM64 | 银河麒麟V10、统信UOS |
    | 飞腾(Phytium) | ARM64 | 银河麒麟V10、统信UOS |
    | 海光(Hygon) | x86 | 统信UOS、银河麒麟V10 |
    | 龙芯(Loongson) | LoongArch | 银河麒麟V10、统信UOS |
    | 兆芯(Zhaoxin) | x86 | 银河麒麟V10、统信UOS |
    | 申威(Sunway) | SW64 | 统信UOS |

    不确定的话,可以在终端执行以下命令查看:

    ```bash

    查看操作系统信息

    cat /etc/os-release

    查看CPU架构

    uname -m
    ```

    2.在线部署or离线部署?


    Easysearch 提供了两种安装方式:

    联网环境:如果服务器能正常访问外网,推荐使用一键安装部署,简单快速;

    离线环境:如果服务器在内网、无法访问外网(常见信创环境),则下载 Bundle 包进行离线部署。

    在这篇文章中所使用的是在线部署方式。

    三、安装环境简介


    以统信 UOS 信创平台为例,以下表中为本机采用的安装环境

    1.硬件信息


    | 硬件 | 信息 |
    | ------ | :-----------------------------: |
    | 处理器 | 架构:aarch64 型号:Kunpeng-920 |
    | 内存 | 容量:8G 类型:RAM |
    | 硬盘 | 类型:QEMU HARDDISK 容量:100G |

    2.软件环境


    | 名称 | 版本 |
    | ----------------------- | :----: |
    | 统信服务器操作系统A版 | V20 |
    | Easysearch 搜索型数据库 | V2.2.0 |
    | 360安全浏览器 | V13 |

    3.网络端口设置


    | 服务名 | 端口 | 配置文件 | 说明 |
    | ----------------- | :----------: | --------------------- | :---------------------------------------------------------: |
    | INFINI Easysearch | 9200(默认) | config/easysearch.yml | 默认仅监控 127.0.0.0,可通过配置 network.host: 0.0.0.0 调整 |
    | | 9300(默认) | config/easysearch.yml | |

    四、部署流程


    具体细节详见[部署手册](https://docs.infinilabs.com/ea ... yment/)

    步骤1:系统初始化


    安装前需要完成两项系统准备工作:调整内核参数创建专用用户。无论在线还是离线安装,这两步都必须先做好,并且需要使用 root 账户或 sudo 权限执行。

    ```bash

    1. 调整内核参数(vm.max_map_count,Easysearch 运行的必要条件)

    echo "vm.max_map_count=262144" >> /etc/sysctl.conf && sysctl -p

    2. 创建 Easysearch 专用用户组和用户

    groupadd -r easysearch && useradd -r -g easysearch -d /home/easysearch -s /sbin/nologin -c "Easysearch Service Account" easysearch

    ```

    步骤2:安装 Easysearch


    如果服务器能正常访问外网,直接使用官方一键安装脚本:

    ```bash

    创建数据安装目录

    mkdir -p /opt/easysearch

    下载最新版本并安装

    curl -sSL http://get.infini.cloud | bash -s -- -p easysearch -d /opt/easysearch

    ``<br /> <br /> 脚本会自动检测系统架构(ARM64还是x86` ),并下载对应的安装包。

    ![](https://infinilabs.cn/img/blog ... p2.png)

    步骤3:初始化并启动 Easysearch


    ```bash

    进入 Easysearch 目录

    cd /opt/easysearch

    初始化 Easysearch (初始化过程中,日志将输出管理员访问密码,请妥善保存)

    bin/initialize.sh -s

    调整目录权限

    chown -R easysearch:easysearch /opt/easysearch

    启动 Easysearch

    runuser -u easysearch -- /opt/easysearch/bin/easysearch -d -p /opt/easysearch/easysearch.pid

    ```

    步骤4:验证服务运行


    启动后,可以使用 curl 命令快速测试服务是否正常运行:

    ```bash

    使用初始化时显示的 admin 密码测试连接

    curl -ku admin:你的密码 https://localhost:9200

    ```

    ![](https://infinilabs.cn/img/blog ... p3.png)

    步骤5:访问服务运行端口


    服务运行后,访问设置好的服务端点

    <https://localhost:9200/_ui/>(默认服务端点)

    输入之前保存的账号与密码进行登录

    ![](https://infinilabs.cn/img/blog ... p4.png)

    进入 ui 界面

    ![](https://infinilabs.cn/img/blog ... p5.png)

    之后就可以实现对 Easysearch 可视化管理了

    结语


    以上就是 Easyserach 在信创平台部署的全流程了,整个过程操作下来,应该能在 10-20 分钟左右完成 Easysearch 支持从单机测试到 PB 级生产集群的平滑扩展,无论是个人学习还是企业级业务,都能灵活适配。如果在操作过程中遇到任何问题,建议优先查阅[官方文档](https://docs.infinilabs.com/easysearch/)。预祝你在信创平台的探索之旅顺利!

Elasticsearch 6/7/8 到 Easysearch 2.x 迁移指南

INFINI Labs 小助手 发表了文章 • 0 个评论 • 7029 次浏览 • 2026-06-04 14:14 • 来自相关话题


![](https://infinilabs.cn/img/blog ... er.jpg)

最近在协助客户进行 Elasticsearch 到 Easysearch 的迁移时,发现大家最关心的问题是"当前版本能否直接使用快照迁移"。这个问题看似简单,但不同版本的答案差异较大。本文将基于实际测试经验,梳理各版本的迁移路径和注意事项。

迁移路径速览


根据源 ES 版本,可以直接对照下表选择迁移方案:

| 源 ES 版本 | 能否直接快照恢复 | 推荐方案 | 实施复杂度 |
| -------------- | :--------------: | ------------------------------------- | :--------: |
| ES 6.x | 否 | INFINI Gateway 迁移 或 ES 7.10.x 中转 | 较低 |
| ES 7.0 - 7.11 | 是 | 直接快照恢复 | 较低 |
| ES 7.12 - 7.17 | 否 | INFINI Gateway 迁移 | 较低 |
| ES 8.x | 否 | INFINI Gateway 迁移 | 较低 |

结论:ES 7.0-7.11 是迁移最顺畅的版本窗口,可直接快照恢复;其他版本也有成熟的迁移方案,只是路径不同。

版本差异的原因


迁移路径的差异主要源于两方面:Lucene 版本兼容性和快照元数据格式变化。

Lucene 兼容性:Easysearch 2.x 底层要求的最低 Lucene 版本对应 ES 7.0.0。ES 6.x 的索引文件使用老版本 Lucene,直接恢复会报错:

<br /> The index was created with version [6.8.23] but the minimum compatible version is [7.0.0].<br />

快照元数据格式:ES 7.12 开始在快照中引入 uuidcluster_id 字段,7.14 增加 writer_uuid,8.x 又引入 transport_version。这些字段与 Easysearch 2.x 的快照解析器不兼容。

因此,ES 7.0-7.11 成为迁移的"黄金窗口"——既满足 Lucene 兼容性要求,快照格式又足够简洁。

ES 7.0-7.11:直接快照恢复


这是测试最充分的迁移路径,已验证版本包括 ES 7.0.1、7.8.1、7.10.2 OSS、7.11.2。

已验证能力:

  • 单索引 / 多索引 / 通配符批量恢复
  • 常见字段类型与别名
  • 自定义 settings、多分片索引
  • ILM 托管索引、数据流后备索引、冻结索引

    操作步骤:

    ```bash

    1. 源 ES 创建快照

    PUT /_snapshot/my_backup/snapshot_1
    {
    "indices": "索引列表",
    "include_global_state": false
    }

    2. Easysearch 注册同一快照仓库

    PUT /_snapshot/my_backup
    {
    "type": "fs",
    "settings": {
    "location": "/path/to/snapshot/repo",
    "readonly": true
    }
    }

    3. 恢复快照

    POST /_snapshot/my_backup/snapshot_1/_restore
    {
    "indices": "索引列表",
    "include_global_state": false
    }
    ```

    ES 6.x:Gateway 迁移或中转方案


    ES 6.x 无法直接快照恢复到 Easysearch 2.x,有两种迁移方案可选:

    方案一:INFINI Gateway 迁移(推荐)

    直接使用 Gateway 从 ES 6.x 迁移数据到 Easysearch,无需中转集群。Gateway 已验证支持 ES 6.8.x 的数据迁移。

    方案二:ES 7.10.x 中转

    <br /> ES 6.8 -> 快照 -> ES 7.10.x -> 快照 -> Easysearch 2.x<br />

    ES 7.10.x 可以正常恢复 ES 6.x 的快照,恢复完成后再创建快照供 Easysearch 使用。该方案数据完整性有保障,但需要额外的中转存储和迁移窗口。

    ES 6.x 特有字段:ES 6.x 的 string 类型在 Easysearch 中需映射为 textkeyword(根据实际使用场景选择)。

    ES 7.12+ 和 8.x:INFINI Gateway 迁移


    这两个版本段的快照格式与 Easysearch 2.x 不兼容,推荐使用 INFINI Gateway 进行迁移。Gateway 是 INFINI Labs 提供的数据迁移工具,专门针对 Elasticsearch 到 Easysearch 的迁移场景进行了优化。

    架构示意


    <br /> ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐<br /> │ Elasticsearch │ ──── │ INFINI Gateway │ ──── │ Easysearch │<br /> │ (源集群) │ │ (迁移工具) │ │ (目标集群) │<br /> └─────────────────┘ └─────────────────┘ └─────────────────┘<br />

    Gateway 内部通过 Scroll API 从源集群分批拉取数据,再通过 Bulk API 写入目标集群,整个过程对业务透明。

    主要优势


  • 配置简单:只需配置源集群和目标集群地址、索引名称即可
  • 断点续传:支持从断点恢复,避免网络抖动导致重头再来
  • 进度可视:实时显示迁移进度和速率
  • 多索引并行:支持同时迁移多个索引

    基本步骤


    1. 在目标集群创建索引的 mapping 和 setting
    2. 准备 Gateway 配置文件,填写源集群和目标集群连接信息
    3. 运行 Gateway 执行迁移
    4. 迁移完成后进行数据校验

      详细的配置说明和操作示例,可参考 [ES 数据迁移之 INFINI Gateway](https://infinilabs.cn/blog/202 ... teway/)。

      备选方案


      如果需要更灵活的控制,也可以自行编写脚本,通过 Scroll API 读取源数据、Bulk API 写入目标。这种方式适合有定制化需求的场景,但需要自行处理断点续传、错误重试等逻辑。

      字段类型兼容性


      直接兼容类型textkeywordlongdoublebooleandateobjectnestedgeo_pointgeo_shapeipcompletionwildcardflattenedaliasjoinrank_featurerank_featuresinteger_rangelong_rangedate_rangematch_only_text 等。

      ES 7.x / 8.x 需替换类型

      | ES 类型 | Easysearch 替代方案 | 数据保留 | 说明 |
      | ------------------------- | ------------------------ | :------: | --------------------------------- |
      | dense_vector | knn_dense_float_vector | 是 | 需安装 knn 插件,向量数据格式兼容 |
      | knn_vector | knn_dense_float_vector | 是 | 需安装 knn 插件 |
      | sparse_vector | knn_sparse_bool_vector | 是 | 需安装 knn 插件 |
      | constant_keyword | keyword | 是 | 需手动维护常量值 |
      | runtime | 移除或转为普通字段 | 是 | Easysearch 不支持运行时字段 |
      | histogram | object | 是 | 聚合 histogram 功能丢失 |
      | aggregate_metric_double | object | 是 | 需手动计算聚合 |
      | unsigned_long | longkeyword | 是 | 注意数值范围 |
      | semantic | 暂不支持 | - | ES 专有 AI 功能 |

      向量迁移要点:ES 的 dense_vector 数据可直接迁移到 Easysearch 的 knn_dense_float_vector,数据格式 [0.1, 0.2, ...] 完全兼容。需预先在目标索引创建正确的 mapping。

      建议迁移前先用小索引测试,确认 mapping 无问题后再全量迁移。

      常见问题与避坑指南


      1. include_global_state 参数设置


      该参数控制是否恢复集群级配置(模板、ILM 策略等)。不同版本的情况:

      | ES 版本 | 发行版 | global_state | 说明 |
      | -------- | ------- | ------------ | -------------------------------- |
      | 7.0-7.7 | 任意 | 兼容 | 无 _index_template API |
      | 7.8-7.10 | OSS | 兼容 | 无内置 _index_template |
      | 7.8-7.10 | default | 可能不兼容 | 取决于是否使用 _index_template |
      | 7.11+ | 任意 | 不兼容 | 有 9 个内置 _index_template |

      建议:迁移时统一使用 include_global_state=false,先恢复数据再重建配置。

      2. ILM 和 data stream 迁移


  • ILM:索引的 lifecycle 设置保留,但 policy 需在 Easysearch 中重建
  • 数据流 (data stream):后备索引 (backing index) 数据完整恢复,语义需在目标侧重建
  • 冻结索引 (frozen index):自动恢复为普通可访问状态

    3. 迁移验收标准


    建议至少完成三项验证:

  • 文档量一致
  • 关键查询结果一致
  • 核心业务链路压测通过

    4. 迁移窗口规划


  • 快照方案通常需要短停机窗口完成切换
  • Gateway 迁移可实现近实时同步,仅在切换连接时短暂停服

    快照格式变化参考


    | 字段 | ES 7.0-7.11 | ES 7.12-7.17 | ES 8.x | Easysearch 2.x |
    | ------------------- | :---------: | :----------: | :----: | :------------: |
    | min_version | 7.9.0 或无 | 7.12.0 | 7.12.0 | 支持 |
    | uuid(仓库级) | 无 | 有 | 有 | 不支持 |
    | cluster_id | 无 | 有 | 有 | 不支持 |
    | writer_uuid | 无 | 有(7.14+) | 有 | 不支持 |
    | transport_version | 无 | 无 | 有 | 不支持 |

    总结


    本文梳理了 Easysearch 2.x 对 ES 6/7/8 的迁移路径:

  • ES 7.0-7.11:直接快照恢复,路径最短
  • ES 6.x:INFINI Gateway 迁移 或 ES 7.10.x 中转
  • ES 7.12+ / 8.x:使用 INFINI Gateway 迁移

    建议在正式迁移前,先选择非核心索引进行小规模验证,确认数据完整性和业务兼容性后再扩大迁移范围。

    如有迁移相关问题,欢迎联系我们。

Easysearch analysis-ik 多词典性能优化:从性能回退到分词性能提升 25%~30%

INFINI Labs 小助手 发表了文章 • 0 个评论 • 15504 次浏览 • 2026-05-08 14:34 • 来自相关话题


Easysearch 版 analysis-ik 相比开源 [IK](https://github.com/infinilabs/analysis-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 |

![](https://infinilabs.cn/img/blog ... ut.svg)

当时服务器上跑的就是早期多词典版本。后面修性能,追的就是这个版本和开源单词典 IK 基线之间的差距。

这一步还不能直接确定问题就在分词器。但差距摆在这儿了,得继续往下排。我们先排除了几个常见干扰因素:

  • refresh_interval
  • 动态同义词 HTTP 服务
  • mapping / settings 不一致
  • 网络层和 bulk 客户端本身

    采样结果很快把范围收窄了。Elasticsearch 那边热点比较分散,Easysearch 这边呢,分词链路里出现了异常集中的开销——分词过程中反复做词典选择和字典查找。

    瓶颈不在 Lucene 写入链路本身,就在 analysis-ik 的多词典实现上。

    根因分析


    第一类问题出在实现模型上。多词典想表达的是”这个字段最终用哪套词典”,这件事完全可以在分词前算好。但早期代码里,硬是把它变成了运行时的事:

  • “字段用哪个词典”变成了”运行时多轮扫描”——同一段文本对着多套词典各来一遍。
  • 全局字典切换的动作放进了每字符的热路径。
  • 结果就是同一段文本的扫描和查找成本翻了好几倍。

    所以问题不是多词典天然慢,是实现把本该提前算好的东西塞进了热路径反复做。

    第二类问题是后续优化过程中留下的额外开销。后面加的跨边界、停用词、长文本等测试本身不是性能问题的来源,它们的作用是把正确性边界补齐,确保每次优化不会改变分词结果。

    最后通过性能分析确认,残留开销主要来自两处:缓存命中前还在做不必要的数据复制;诊断逻辑在生产热路径上产生了额外开销。修完之后这两处热点都从火焰图上消失了,说明性能回退确实来自真实的代码路径成本,不是测试抖动。

    修复过程


    整个修复分四个阶段。

    第一阶段:把多词典从”运行时分发”收敛为”最终有效词典视图”


    多词典能力保留,但不再让分词器在热路径里反复切词典、重复扫文本。改成在分词前就把字段最终生效的词典算好,分词过程只面对一个已经收敛好的词典视图。

    说白了就是把模型拉回正确方向——多词典管表达能力,热路径只管分词。

    第二阶段:逐步打掉热路径上的常数开销


    留下来的每一项优化,都经过正式性能测试和采样分析验证。原则就一条:不改分词语义,只减少热路径上反复发生的查找、分配和判断。

    第三阶段:补齐正确性护栏


    正确性测试必须先到位,不然吞吐提升没有意义——万一分词结果变了,跑得再快也白搭。

    这一轮重点覆盖了这些容易出问题的场景:

  • 真跨边界场景
  • 数字和量词合并,如 1号
  • 自定义词典里的含符号词
  • 补充平面字符跨边界稳定性
  • 停用词过滤后的偏移量
  • 长文本样本的稳定性
  • 正式性能测试数据集的分词结果对齐

    后面所有的吞吐数字,前提都是分词结果一致,避免把分词行为的变化误当成性能提升。

    第四阶段:清理最后的残留开销


    到 4 月 28 号,最后一轮修复集中处理两个地方:

  • 词典视图命中缓存时直接返回,不再多做一次数据复制
  • 诊断逻辑默认关掉,不让线上请求为调试能力买单

    这两处修完,Easysearch 版 IK 就不只是恢复到单词典版本附近了,在正式测试里已经明显领先。

    用数据看恢复过程


    为了不把系统级写入压测和分词器性能测试混在一起,下面只看几个关键节点。2026-04-20docs/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。后面所有修复就是冲着这个差距去的。

    ![](https://infinilabs.cn/img/blog ... rt.svg)

    ![](https://infinilabs.cn/img/blog ... ry.svg)

    三张图分别对应问题暴露、分词复现和修复结果:第一张展示服务器 bulk 写入吞吐的系统级差距;第二张展示多词典版本和单词典版本的本地分词差距;第三张展示分词结果对齐后,Easysearch 版 IK 怎么一步步追上来,最终实现 25%~30% 的分词性能提升。

    为什么说 Easysearch 版 IK 现在更好


    这次修复的价值不只是消灭了几个热点,更重要的是把多词典能力、分词正确性和性能测试体系一起补齐了。

    1. 功能更强,性能代价可控


    开源单词典 IK 模型简单,但表达能力也弱。Easysearch 的多词典能力要解决的是字段级词库隔离、自定义词典叠加这些实际需求。

    关键问题是:能不能把这些能力的性能开销压到足够低。修复后的结果证明,可以。

    2. 正确性护栏更完整


    这轮补上的测试不只是几个短样例,覆盖了更容易翻车的边界条件:

  • 真跨边界场景
  • 长文本稳定性
  • 自定义词典和符号词
  • 数字量词合并
  • 停用词过滤后的偏移量

    这意味着以后再做性能优化,必须同时保证分词结果不变。想靠改分词行为换吞吐,测试会先拦住。

    3. 性能测试体系更严格


    这轮之后,Easysearch 对 analysis-ik 的正式性能结论统一按一套标准出:

  • 同一数据集
  • 同一测试方法
  • smartmax_word 双模式
  • 分词结果一致
  • 有性能分析结果支撑

    这套体系能避免两个常见坑:只看单轮吞吐波动就下结论,或者分词结果已经变了还在比性能。

    小结


    多词典能力在实现初期,主要精力放在功能补齐上——先把字段级词库隔离、自定义词典叠加这些能力跑通,性能优化是后面分阶段来的事,没办法一蹴而就。

    这轮优化下来,核心思路其实就一条:把词典选择从分词热路径里挪出去,提前收敛好,让分词过程只面对最终的词典视图。再配合热点清理和正确性护栏,增强功能和更高性能完全可以兼得。

    截至 2026 年 4 月 28 日,在本地 Mac 笔记本上的多轮 benchmark 中,Easysearch 版 IK 在 smart 模式大约领先开源单词典 IK 基线 25%~30%max_word 模式大约领先 20% 左右,分词结果完全一致。具体数字每次跑会有波动,但趋势是稳定的。

    这也是 Easysearch 版 IK 相对开源版更有价值的地方:不是多了几个配置项,而是在多词典能力、分词正确性和分词性能三个方面都给出了可验证的结果。

    关于 Easysearch


    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

    官网:<https://easysearch.cn>;

    作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

    ---

    相关文章:

  • [开源 IK 分词器](https://github.com/infinilabs/analysis-ik)
  • [IK 字段级别词典的升级之路](https://infinilabs.cn/blog/202 ... rys-3/)
  • [IK 字段级别词典升级:IK reload API](https://infinilabs.cn/blog/202 ... rys-2/)
  • [Easysearch 新功能: IK 字段级别词典](https://infinilabs.cn/blog/202 ... narys/)

Easysearch 正式支持插件开发:让你的搜索系统真正"为你所用"

INFINI Labs 小助手 发表了文章 • 0 个评论 • 17174 次浏览 • 2026-04-27 22:02 • 来自相关话题


从"用搜索"到"造搜索"


搜索系统的需求千差万别。标准功能覆盖不了所有场景——行业特定的分词规则、定制化的业务逻辑、与外部系统的深度集成……

以往,这类定制需求需要依赖厂商支持。从 Easysearch 2.1.2 开始,你可以自己动手了。

随着构建依赖库正式发布到 Maven 中央仓库,Easysearch 的插件开发能力正式对外开放。这意味着 Easysearch 不再是一个黑盒产品,而是一个可扩展、可定制的搜索平台。你可以基于官方接口开发自定义插件,像使用原生功能一样使用它们。

插件能做什么


Easysearch 提供三类核心扩展点,覆盖搜索系统的关键环节:

![](https://infinilabs.cn/img/blog ... /1.png)

1. 分析器插件(AnalysisPlugin)


自定义分词器、Token 过滤器、字符过滤器。适用于:

  • 电商 SKU 的型号规格解析
  • 医疗、法律等领域的专业术语分词
  • 特殊符号或空格的规范化处理

    注册后直接在索引设置中使用,与原生分析器完全等同。

    ![](https://infinilabs.cn/img/blog ... /2.png)

    2. REST/API 插件(ActionPlugin)


    新增自定义 HTTP 接口。适用于:

  • 封装业务查询逻辑,对外暴露简化 API
  • 对接企业内部权限中心或监控系统
  • 暴露插件自身的管理接口(如状态检查)

    ![](https://infinilabs.cn/img/blog ... /3.png)

    3. Ingest 插件(IngestPlugin)


    在文档写入前进行字段转换。适用于:

  • 自定义业务字段转换(如根据业务规则计算衍生字段)
  • 数据标准化(统一日期格式、大小写转换)
  • 富文本提取或元数据生成

    ![](https://infinilabs.cn/img/blog ... /4.png)

    5 分钟上手


    我们准备了[官方模板仓库](https://github.com/infinilabs/ ... mplate),让你从克隆到运行只需几条命令:

    ```bash

    克隆模板

    git clone https://github.com/infinilabs/ ... e.git my-plugin
    cd my-plugin

    修改包名和类名,编写你的逻辑

    ...

    <br /> <br /> **方式一:开发调试——直接运行**<br /> <br /> bash

    构建插件并运行

    ./gradlew run

    验证插件

    curl -s "<a href="http://localhost:9200/_cat/plugins?v"" rel="nofollow" target="_blank">http://localhost:9200/_cat/plugins?v" | grep my-plugin
    <br /> <br /> **方式二:构建后安装到外部集群**<br /> <br /> bash

    构建插件

    ./gradlew build

    安装到 Easysearch

    bin/easysearch-plugin install file:///$(pwd)/build/distributions/my-plugin-0.1.0.zip

    启动验证

    bin/easysearch
    curl -s "<a href="http://localhost:9200/_cat/plugins?v"" rel="nofollow" target="_blank">http://localhost:9200/_cat/plugins?v" | grep my-plugin
    ```

    完整的开发指南请参考[插件开发文档](https://docs.infinilabs.com/ea ... ugins/)。

    设计哲学


    Easysearch 插件系统的设计遵循三个原则:

    渐进式扩展——从最简单的 Plugin 类开始,按需实现 AnalysisPluginActionPlugin 等接口,不必一次性掌握全部 API。

    与原生同等——插件注册的分析器、处理器与系统原生组件在使用方式上完全一致,用户无需关心实现来源。

    版本安全——插件加载时校验 easysearch.version,版本不匹配会拒绝加载,避免运行时异常。

    从插件到生态


    插件开发不只是技术能力的开放,更是产品理念的转变。

    你可以将开发的插件发布到 GitHub Releases,通过 URL 直接安装:

    ![](https://infinilabs.cn/img/blog ... /5.png)

    bash<br /> bin/easysearch-plugin install <a href="https://github.com/yourname/my-plugin/releases/download/v0.1.0/my-plugin-0.1.0.zip" rel="nofollow" target="_blank">https://github.com/yourname/my ... 0.zip</a><br />

    我们也欢迎社区贡献。如果你有通用的插件想法,欢迎与我们交流。

    结语


    搜索系统的最后一公里,只有业务开发者最清楚该怎么走。

    Easysearch 2.1.2 的插件开发能力,让你能够自主掌控搜索系统的"最后一公里"。从"用搜索"到"造搜索",现在你可以让你的搜索系统真正"为你所用"。

    ---

    关于 Easysearch

    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

    官网:<https://easysearch.cn>;

INFINI Agent v1.31.0 发布 | 全新 Easysearch 向导:一站式集群拉起与精细化管理

INFINI Labs 小助手 发表了文章 • 0 个评论 • 17529 次浏览 • 2026-04-23 18:01 • 来自相关话题


![release](https://infinilabs.cn/img/blog/release/banner.png)

INFINI Agent v1.31.0 带来了本版本最重要的特性——Easysearch 安装向导。用户无需手动编辑任何配置文件,通过图形界面即可完成 Easysearch 集群的安装、配置和日常管理。

Easysearch 安装向导


一键拉起新集群


向导支持开发模式生产模式两种方式创建 Easysearch 节点。用户只需填写集群名称、节点名称、监听地址、端口、数据目录等基本信息,向导便会自动完成软件下载、JDK 配置、安全证书生成、参数配置、插件安装、节点启动等全部步骤,并实时展示每一步的进度,支持随时暂停和恢复。

![](https://infinilabs.cn/img/blog ... ev.png)

一键加入已有集群


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

![](https://infinilabs.cn/img/blog ... er.png)
![](https://infinilabs.cn/img/blog ... ss.png)

安装前环境预检


向导在开始安装前会对当前机器进行全面检测,帮助用户提前发现潜在问题:

  • 操作系统和 CPU 架构是否受支持
  • 内存是否满足推荐要求
  • 端口是否已被占用
  • 数据目录磁盘空间是否充足、路径是否可写
  • 系统参数(文件描述符限制、内核 max_map_count 等)是否满足 Easysearch 运行需求
  • TLS 证书填写后实时校验有效性,包括证书链完整性和过期时间

    ![](https://infinilabs.cn/img/blog ... ck.png)

    TLS 安全证书灵活配置


    支持三种证书配置方式,满足不同安全需求:

  • 自动生成:向导一键生成自签名证书,无需任何证书知识
  • 手动上传(共享):为 HTTP 和节点通信层提供同一套证书
  • 手动上传(分离):为 HTTP 层和节点通信层分别提供独立证书

    ![](https://infinilabs.cn/img/blog ... rt.png)

    完整的服务生命周期管理


    集群建好后,向导提供持续的管理能力:

  • 启动、停止、重启 Easysearch 节点

    ![](https://infinilabs.cn/img/blog ... st.png)

  • 在线安装和卸载插件

    ![](https://infinilabs.cn/img/blog ... in.png)

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

    ![](https://infinilabs.cn/img/blog ... ig.png)

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

    ![](https://infinilabs.cn/img/blog ... og.png)

    网络受限环境支持


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

    ![](https://infinilabs.cn/img/blog ... xy.png)

    获取新版本


    INFINI Agent v1.31.0 已正式发布,欢迎升级体验:

  • [下载地址](https://release.infinilabs.com/agent/stable/)
  • [用户手册](https://docs.infinilabs.com/ea ... ement/)

同样 15,000 条重规则,Percolate Query 比 Easysearch 慢 21.8 倍 —— Heavy-OR 场景实测

INFINI Labs 小助手 发表了文章 • 0 个评论 • 17284 次浏览 • 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 条文档


http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

Easysearch
11.68s
在线规则引擎全流程


Percolate Query
254.30s
只算搜索阶段




Percolate Query 比 Easysearch
慢了 21.8 倍
仅搜索阶段就多花 242.62 秒



具体指标:

- Easysearch 在线规则引擎全流程:`11.68s`
- Percolate Query 搜索阶段:`254.30s`
- 差值:`242.62s`
- 倍数:`21.76 倍`
- 每批(10,000 文档)平均耗时:Easysearch 约 `0.49s`,Percolate Query 约 `12.69s`

## 开启规则引擎的增量成本

规则匹配会对写入链路产生多少额外开销,是评估在线规则引擎可行性的重要指标之一。


开启规则引擎的写入增量


http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

纯写入
6.03s
plain_bulk 基线


开启规则引擎
11.68s
基线 6.03s + 新增 5.66s




规则引擎新增成本
仅 5.66s
Percolate 搜索阶段同期耗时 254.30s



与之对比,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` |


只比匹配本身


http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

Easysearch 纯匹配
5.05s
Java JNI 离线直调


Percolate Query
254.30s
搜索阶段


只看匹配引擎本体
慢了 50.4 倍
254.30 ÷ 5.05 = 50.39



这组数据说明两点:Easysearch 的性能优势并非来自写入链路的整合效率,即便剔除通用写入成本,规则匹配引擎本体与 Percolate Query 之间依然存在约 50 倍的差距。

## 为什么 Percolate Query 会慢

根因在执行模型,OR 条件多只是放大器。

每批文档到达时,Percolate Query 都要走完这套流程:

1. 把文档放进临时内存索引
2. 基于规则中的 terms 筛选候选规则
3. 对候选规则逐条验证

以本次测试为例,各阶段耗时分布如下:

- 规则翻译:`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

![](https://infinilabs.cn/img/blog ... er.png)

INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

官网文档:<https://docs.infinilabs.com/easysearch>

> 作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

---

相关文章:

- [Easysearch ZSTD 基准测试:高压缩率下实现近 5 倍查询吞吐](https://infinilabs.cn/blog/202 ... ntage/)
- [Easysearch 2.0.0 性能测试](https://infinilabs.cn/blog/202 ... ments/)
- [Easysearch 时序数据的基于时间范围的合并策略](https://infinilabs.cn/blog/202 ... earch/)
- [Easysearch Rollup 相比 OpenSearch Rollup 的优势分析](https://infinilabs.cn/blog/202 ... ollup/)
- [Easysearch Rollup 使用指南](https://infinilabs.cn/blog/202 ... ollup/)

Easysearch BKD Merge 异常排查实录:最终定位到旧版 GraalVM JIT 运行时

INFINI Labs 小助手 发表了文章 • 0 个评论 • 11291 次浏览 • 2026-04-10 17:51 • 来自相关话题

最近一次高并发写入压测中,我们遇到了一个非常诡异的 BKD merge 崩溃。从报错看,很像 Easysearch 2.1.2 在 merge 阶段把 segment 读成了错误状态。典型错误是这样的:

text<br /> java.lang.ArrayIndexOutOfBoundsException: Index -3 out of bounds for length 8<br /> java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8<br />

异常栈最终落在 Lucene BKD 相关路径上:

  • BKDReader.readNodeData()
  • BKDWriter.merge()
  • Lucene90PointsWriter.merge()

    如果只看栈,很容易把问题归到 Easysearch 的 BKD merge 逻辑。但排查到最后,结论恰恰相反。

    问题不在 Easysearch 的代码,而在 JDK 运行时。 更精确地说,是某个特定 Oracle GraalVM 21 构建中的 JVMCI/Graal JIT 路径,把 Lucene BKD 的热点代码执行错了。

    1、为什么这个问题难查


    它有几个特别迷惑人的特征:

  • 只在高并发写入压测下触发
  • 服务重启后的前几轮最容易复现
  • 同一进程里,删了索引重新压,后面复现率反而下降
  • 不是固定字段,多个数字类型字段都中过招
  • ZSTDbest_compression 两种 codec 下都能复现

    实际命中过的字段包括 @timestampsizestatus_seq_no。所以这不是某个字段、某种 codec 或某个 mapping 的偶发问题。

    2、第一层排除:merge reader 不是第一现场


    一开始我们确实怀疑 merge reader,毕竟异常直接出现在 merge 路径上。但日志顺序很快给出了相反的证据。在 merge 真正崩溃之前,source segment 已经先出现了这些异常信号:

    1. point-sort-restore-multiple-zero-ords
    2. source-write-point-doc-mismatch
    3. pointCount > docCount
    4. pack-index-negative-code
    5. reader-invalid-start-pos
    6. 最后才是 ArrayIndexOutOfBoundsException

      这意味着两件事:merge reader 不是第一现场,source segment 在写出阶段就已经坏了。merge reader 只是读到了已经损坏的 BKD index,并在那个阶段暴露了异常。

      3、第二层排除:Easysearch 自己的 BKD 写入逻辑也没有先出错


      继续往前追溯,我们发现问题比 OneDimensionBKDWriter.add() 还要早。真正的异常出现在排序/回填链路上:

  • PointValuesWriter
  • MutablePointTreeReaderUtils.sort()
  • StableMSBRadixSorter

    关键证据来自两个探针:

  • point-sort-restore-multiple-zero-ords
  • unwrittenSlotCount == 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=_x
  • field=status
  • k=7
  • expectedLoopCount=9800
  • actualIterationCount=8204
  • firstCoverageMismatchBucket=201
  • firstCoverageExpected=9788
  • firstCoverageActual=8192

    更关键的是,同一条日志里还带出了这个信息:

    text<br /> skippedSourceSamples=[201:[{ord=8192,bucket=201,docID=9090,byteAtK=200}, ...]]<br />

    这条信息非常重要,因为它说明:bucket 201 理论上应该处理 9788 条,实际只处理了前 8192 条,但从 ord=8192 往后的样本,读出来仍然还是 bucket=201。这直接推翻了“后半段数据被污染后改桶”的旧解释,指向了一个更直接的结论:reorder() 自己的 coverage 被截断了

    另一个样本中出现了同类边界:firstCoverageExpected=31822firstCoverageActual=16384

    到这里,一个很不自然的特征浮现出来:819216384——这些明显的 2 的幂边界,更像是运行时或 JIT 执行异常,而不是普通业务逻辑 bug。

    5、哪段代码最可疑


    此时怀疑对象已经不是泛泛的“BKD 整体有问题”,而是 Lucene 中的这段热点循环:

    java<br /> for (int i = 0; i < HISTOGRAM_SIZE; ++i) {<br /> final int limit = endOffsets[i];<br /> for (int h1 = fixedStartOffsets[i]; h1 < limit; h1++) {<br /> final int b = getBucket(from + h1, k);<br /> final int h2 = startOffsets[b]++;<br /> save(from + h1, from + h2);<br /> }<br /> }<br /> restore(from, to);<br />

    代码位于 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.1
  • 21+35-jvmci-23.1-b15
  • Linux aarch64 / ARM64
  • UseJVMCICompiler = true

    结果:很快复现,命中了 point-sort-reorder-coverage-mismatchpoint-sort-reorder-underfilledpoint-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 版本:

    text<br /> java version "21.0.9" 2025-10-21 LTS<br /> Java(TM) SE Runtime Environment Oracle GraalVM 21.0.9+7.1 (build 21.0.9+7-LTS-jvmci-23.1-b79)<br />

    在当前压测中,这个版本没有再出现 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/jdkOracle GraalVM 21 换成普通 Oracle HotSpot 21.0.10,恢复默认 JVM 参数,用同样的写入压测继续验证。

    其中一轮的结果很有说服力:

  • 索引:nginx_zstd3_40mt4
  • codec:ZSTD
  • threads=16
  • bulk_size=1000
  • target_docs=181463624

    最终 after_count=181463624delta_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 崩溃。

    关键异常完全一致:

    text<br /> java.lang.ArrayIndexOutOfBoundsException: Index -4 out of bounds for length 8<br />

    栈也一样落在 BKDReader.readNodeDataBKDWriter$MergeReader.collectNextLeafBKDWriter$MergeReader.next

    这条证据的力度很强:不是 Easysearch 独有的问题,不是当前这套 Lucene 代码路径独有的问题,Elasticsearch 8.19.5 + Lucene 9.12.2 在同类 GraalVM 21 环境下也会出现同类异常。到这一步,再把问题归因于 Easysearch 本身的代码逻辑,已经缺乏依据了。

    9、这次排查最终说明了什么


    把整条证据链串起来,当前阶段的结论已经比较清楚。

    已验证的事实:

  • 问题不是 merge reader 先制造坏数据,source segment 在更早阶段就已经进入错误状态
  • 不是单字段问题,也不是 ZSTDbest_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 热点路径被充分打热的场景下,需要特别警惕这类问题。

    现阶段比较明确的建议是:

    1. 避免继续使用已经验证可复现的旧版构建Oracle GraalVM 21+35.121+35-jvmci-23.1-b15
    2. 优先升级到当前测试中未复现的版本Oracle GraalVM 21.0.9+7.1(即 21.0.9+7-LTS-jvmci-23.1-b79
    3. 如果短期内不方便升级 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


    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

    官网文档:<https://docs.infinilabs.com/easysearch>;

    作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

    ---

    相关文章:

  • [Easysearch 国产替代 Elasticsearch:8 大核心问题解读](https://infinilabs.cn/blog/202 ... -8-qa/)
  • [Elasticsearch VS Easysearch 性能测试](https://infinilabs.cn/blog/202 ... sting/)
  • [从 Elastic 迁移到 Easysearch 指引](https://infinilabs.cn/blog/202 ... earch/)
  • [Elasticsearch 磁盘空间异常:一次成功的故障排除案例分享](https://infinilabs.cn/blog/202 ... ormal/)
  • [Easysearch、Elasticsearch、Amazon OpenSearch 快照兼容对比](https://infinilabs.cn/blog/202 ... earch/)

INFINI Labs 产品更新 | Easysearch 2.1.0 新增高性能 Rules 规则引擎插件,数据探索 Discover 等

INFINI Labs 小助手 发表了文章 • 0 个评论 • 9244 次浏览 • 2026-03-17 16:02 • 来自相关话题


![release](https://infinilabs.cn/img/blog/release/banner.png)

INFINI Easysearch v2.1.0 发布:新增 Rules 规则引擎(百万级规则、复杂表达式、自动同步恢复)与 形态学分析插件(俄语/英语词形还原,提升搜索召回率);审计日志支持动态用户审计,UI 新增日志查看、配置及数据探索页面,运维更高效。INFINI Console、Gateway、Agent、Loadgen v1.30.3 统一基于 [Framework](https://docs.infinilabs.com/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 插件新增如下能力
  • 将“结巴”分词插件日志迁移至 Log4J,并降低周期性任务的日志级别以减少冗余

    🐛 问题修复(Bug Fixes)


  • 修复少量 UI 界面操作问题
    ![](https://infinilabs.cn/img/blog ... /1.png)
    ![](https://infinilabs.cn/img/blog ... /2.png)
    ![](https://infinilabs.cn/img/blog ... /3.png)

    Console v1.30.3


    INFINI Console 是一款开源的非常轻量级的多集群、跨版本的搜索基础设施统一管控平台。通过对流行的搜索引擎基础设施进行跨版本、多集群的集中纳管,企业可以快速方便的统一管理企业内部的不同版本的多套搜索集群。

    Console 本次详细更新记录如下:

    ✈️ 改进优化 (Improvements)


  • 此版本包含了底层 [Framework](https://docs.infinilabs.com/framework/) 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Console 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Console 受益。

    🐛 问题修复(Bug Fixes)


  • 修复 Agent 关联不成功问题

    Gateway v1.30.3


    INFINI Gateway 是一个开源的面向搜索场景的高性能数据网关,所有请求都经过网关处理后再转发到后端的搜索业务集群。基于 INFINI Gateway 可以实现索引级别的限速限流、常见查询的缓存加速、查询请求的审计、查询结果的动态修改等等。

    Gateway 本次更新如下:

    ✈️ 改进优化 (Improvements)


  • 此版本包含了底层 [Framework](https://docs.infinilabs.com/framework/) 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Gateway 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Gateway 受益。

    Agent v1.30.3


    INFINI Agent 负责采集和上传 Elasticsearch, Easysearch, Opensearch 集群的日志和指标信息,通过 INFINI Console 管理,支持主流操作系统和平台,安装包轻量且无任何外部依赖,可以快速方便地安装。

    Agent 本次更新如下:

    🚀 功能特性 (Features)


  • 在 Kubernetes 环境下通过环境变量 http.port 探测 Easysearch 的 HTTP 端口

    ✈️ 改进优化 (Improvements)


  • 此版本包含了底层 [Framework](https://docs.infinilabs.com/framework/) 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Agent 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Agent 受益。

    Loadgen v1.30.3


    INFINI Loadgen 是一款开源的专为 Easysearch、Elasticsearch、OpenSearch 设计的轻量级性能测试工具。

    Loadgen 本次更新如下:

    ✈️ 改进优化 (Improvements)


  • 此版本包含了底层 [Framework](https://docs.infinilabs.com/framework/) 的更新,解决了一些常见问题,并增强了整体稳定性和性能。虽然 Loadgen 本身没有直接的变更,但从 Framework 中继承的改进间接地使 Loadgen 受益。

    更多详情请查看以下各产品的 Release Notes 或联系我们的技术支持团队!

  • [Coco AI App](https://docs.infinilabs.com/co ... notes/)
  • [Coco AI Server](https://docs.infinilabs.com/co ... notes/)
  • [INFINI Easysearch](https://docs.infinilabs.com/ea ... earch/)
  • [INFINI Gateway](https://docs.infinilabs.com/ga ... notes/)
  • [INFINI Console](https://docs.infinilabs.com/co ... notes/)
  • [INFINI Agent](https://docs.infinilabs.com/ag ... notes/)
  • [INFINI Loadgen](https://docs.infinilabs.com/lo ... notes/)
  • [INFINI Framework](https://docs.infinilabs.com/fr ... notes/)

    期待反馈


    欢迎下载体验使用,如果您在使用过程中遇到如何疑问或者问题,欢迎前往 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),加入用户群一起讨论交流。

    ![](https://infinilabs.cn/img/blog ... us.png)

    关于极限科技(INFINI Labs)


    ![INFINI Labs](https://infinilabs.cn/img/blog ... bs.png)

    极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。

    极限科技是一支年轻的团队,采用天然分布式的方式来进行远程协作,员工分布在全球各地,希望通过努力成为中国乃至全球企业大数据实时搜索分析产品的首选,为中国技术品牌输出添砖加瓦。

    官网:<https://infinilabs.cn>;

Easysearch ZSTD 基准测试:高压缩率下实现近 5 倍查询吞吐

INFINI Labs 小助手 发表了文章 • 0 个评论 • 4842 次浏览 • 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 映射到 Lucene BEST_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_namemethoderror_codeurl 四个字段,每次返回 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 对比(稳态均值)


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

    ES (DEFLATE)
    532.8

    Easysearch (ZSTD)
    2,518.0
    QPS(越高越好)



    ### 2. 响应时间:从近 1 秒降到 164 毫秒


    平均响应时间对比(ms,越低越好)


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

    ES (DEFLATE)
    779.0 ms

    Easysearch (ZSTD)
    164.3 ms
    响应时间(越低越好)



    用户体感上,这意味着:同样一个搜索请求,Elasticsearch 还在等解压,Easysearch 已经把结果送到了客户端。

    ### 3. 各轮次详细数据


    各轮次 QPS 趋势


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">






    0
    1500
    3000

    warmup
    steady_r1
    steady_r2
    steady_r3


    2087.9
    2533.2
    2491.7
    2529.0


    484.5
    521.8
    539.6
    537.1


    Easysearch (ZSTD)

    Elasticsearch (DEFLATE)




    各轮次平均响应时间趋势(ms)


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">






    0
    400
    800

    warmup
    steady_r1
    steady_r2
    steady_r3


    171
    795
    769
    773


    39
    163
    166
    164


    Easysearch (ZSTD)

    Elasticsearch (DEFLATE)



    ### 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


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

    ES (DEFLATE)
    5.76

    Easysearch (ZSTD)
    28.10
    QPS / 1% CPU(越高越好)── 效率差距 4.88 倍



    这意味着什么?

  • 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)


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

    ES (DEFLATE)
    1.8 GB

    Easysearch (ZSTD)
    1.9 GB
    按字节口径约 +2.5%,整体接近



    ---

    ## 为什么 ZSTD 能做到"又小又快"?

    传统认知中,压缩率和解压速度是一对矛盾。但 ZSTD 算法天然具备**非对称压缩**的特性:


    压缩算法特性对比


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">


    算法
    压缩率
    解压速度


    LZ4


    快但不紧凑


    DEFLATE


    紧凑但解压慢


    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 — 全维度对比


    http://www.w3.org/2000/svg" style="width:100%;font-family:system-ui,sans-serif;">

    查询吞吐

    +372.6% ↑

    响应时间

    -78.9% ↓

    CPU 效率
    (QPS/CPU%)

    +387.8% ↑

    磁盘占用

    +2.5% ≈

    CPU 占用

    -2.84pp ↓

    压缩率几乎相同,查询性能提升近 4 倍,CPU 效率提升近 5 倍



    ---

    ## 结论

    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


    bash<br /> curl -k -u 'admin:<password>' -X PUT 'https://127.0.0.1:9200/<index-name>' \<br /> -H 'Content-Type: application/json' -d '{<br /> "settings": {<br /> "index.codec": "ZSTD",<br /> "index.compression.zstd.jni": true<br /> }<br /> }'<br />

    可选参数:

  • index.compression.zstd.level(默认 3

    说明:

  • index.compression.zstd.dict 固定为 true,无需单独配置
  • index.compression.zstd.dict 不作为独立开关来调整

    2) 老索引切换到 ZSTD(推荐 reindex)


    index.codec 是静态设置(打开状态不可动态改;可在关闭索引后调整)。
    index.compression.zstd.jnifinal 设置(关闭索引后也不可修改)。
    如果老索引要启用 index.compression.zstd.jni=true,建议新建目标索引后 reindex 迁移:
    如果对已有索引执行 PUT /<index-name>/_settings 直接修改,会报错:final <index-name> setting [index.compression.zstd.jni], not updateable

    ```bash

    先创建目标索引(启用 ZSTD)

    curl -k -u 'admin:' -X PUT 'https://127.0.0.1:9200/' \
    -H 'Content-Type: application/json' -d '{
    "settings": {
    "index.codec": "ZSTD",
    "index.compression.zstd.jni": true
    }
    }'

    再迁移数据

    curl -k -u 'admin:' -X POST 'https://127.0.0.1:9200/_reindex' \
    -H 'Content-Type: application/json' -d '{
    "source": { "index": "" },
    "dest": { "index": "" }
    }'
    ```

    3) 校验是否生效


    bash<br /> curl -k -u 'admin:<password>' \<br /> 'https://127.0.0.1:9200/<index-name>/_settings?include_defaults=true&pretty'<br />

    重点确认:

  • index.codec = ZSTD
  • index.compression.zstd.jni = true

    ---

    关于 Easysearch


    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

    官网文档:<https://docs.infinilabs.com/easysearch>;

    作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

    ---

    相关文章:

  • [Easysearch 2.0.0 性能测试](https://infinilabs.cn/blog/202 ... ments/)
  • [Easysearch 压缩模式深度比较:ZSTD + source_reuse 的优势分析](https://infinilabs.cn/blog/202 ... modes/)
  • [Easysearch 压缩功能的显著提升:从 8.7GB 到 1.4GB](https://infinilabs.cn/blog/202 ... 1.4GB/)

APM(二):监控 Python 服务

INFINI Labs 小助手 发表了文章 • 0 个评论 • 15796 次浏览 • 2025-12-31 18:04 • 来自相关话题


[上一篇](https://infinilabs.cn/blog/202 ... earch/)我们已经安装好了 Skywalking 和 Easysearch,这次我们来写个简单的 Python 服务,并把它的服务调用信息发送给 Skywalking,通过 Skywalking 的 Web UI 进行展示。

启动后端服务


先启动好后端服务,包括 Skywalking 和 Easysearch。启动完成后能通过 Web UI 访问 Skywalking。

![](https://infinilabs.cn/img/blog ... /1.png)

构建 Python 服务


我们编写一个简单的 Flask 服务程序,只要访问 localhost:8081/a 就会返回 "Hello, I'm Service A!" 信息。

plain<br /> from flask import Flask<br /> <br /> app = Flask(__name__)<br /> <br /> @app.route('/a', methods=['GET'])<br /> <br /> def service_b():<br /> return "Hello, I'm Service A!"<br /> <br /> if __name__ == '__main__':<br /> app.run(host='0.0.0.0', port=8081)<br />

运行前,要安装好依赖。

plain<br /> pip3 install flask<br /> pip3 install apache-skywalking<br />

依赖关系展示如下:

![](https://infinilabs.cn/img/blog ... /2.png)

设置环境变量


为了让服务能成功把相关信息发送到 Skywalking 后端,启动前我们还要设置两个环境变量告诉服务程序该往哪里发送信息。

plain<br /> export SW_AGENT_COLLECTOR_BACKEND_SERVICES=localhost:11800<br /> export SW_AGENT_NAME=AService-python<br />

启动 Python 程序


一切准备妥当后,运行我们的服务程序。

plain<br /> sw-python run python3 AService.py<br />

程序启动后会监听 8081 端口。

![](https://infinilabs.cn/img/blog ... /3.png)

我们通过浏览器访问下。

![](https://infinilabs.cn/img/blog ... /4.png)

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

![](https://infinilabs.cn/img/blog ... /5.png)

![](https://infinilabs.cn/img/blog ... /6.png)

![](https://infinilabs.cn/img/blog ... /7.png)

![](https://infinilabs.cn/img/blog ... /8.png)

可以看到服务 A 的调用信息都已经被记录到 Skywalking 中了。

作者:杨帆,极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。

Easy-Es 2.1.0-easysearch 版本发布

INFINI Labs 小助手 发表了文章 • 0 个评论 • 9487 次浏览 • 2025-12-15 17:42 • 来自相关话题

![](https://infinilabs.cn/img/blog ... er.png)

01 | 版本更新概述


经过极限科技与 Dromara 开源社区下 Easy-Es 项目的紧密合作与共同努力,我们很荣幸地联合推出 Easy-Es 2.1.0-easysearch 版本!

作为双方携手打造的第一个合作成果,本版本已正式发布:

  • 源码仓库:<https://gitee.com/dromara/easy ... gt%3B
  • Maven 依赖:<https://mvnrepository.com/arti ... gt%3B

    本次更新的核心内容是将 Easy-Es 框架底层增加兼容极限科技自主研发的 Easysearch 搜索引擎,这标志着国产搜索引擎与国内优秀开源项目深度融合的重要里程碑,是极限科技与 Dromara 社区携手共建国产技术生态的创新实践。

    02 | 迁移至 Easysearch 的背景与优势


    随着国内对自主可控技术需求的日益增长,特别是在基础设施软件领域,企业对于信创合规的要求不断提升。极限科技自主研发的 Easysearch 搜索引擎具备以下显著优势:

  • 国产化自主可控:完全自主研发,符合信创要求,无许可证风险,为企业提供安全可靠的技术保障
  • 轻量级架构:相比传统搜索引擎,资源占用更少,启动更快速,显著降低企业运维成本
  • 卓越性能表现:查询性能优异,能够满足大部分业务场景需求,用户体验流畅
  • 良好兼容性:与 Elasticsearch 的 API 接口基本兼容,迁移成本较低,保护用户现有投资

    基于以上优势,双方决定共同将 Easy-Es 框架底层迁移至 Easysearch,这不仅为用户提供更多选择,更是双方携手推动国产搜索引擎生态建设的重要举措。

    03 | Easy-Es 框架优势


    Easy-Es 框架在搜索开发领域具备以下核心优势:

    1. 极简代码开发:相比原生 API 可减少 50%-80% 的代码量,大幅提升开发效率。

      java<br /> // 使用 Easy-Es 仅需一行代码完成查询<br /> List<Document> documents = documentMapper.selectList(<br /> EsWrappers.lambdaQuery(Document.class).eq(Document::getTitle, "测试")<br /> );<br />

    2. 自动索引管理
      框架提供全自动智能索引托管功能,开发者无需关心索引的创建、更新及数据迁移等复杂操作,索引全生命周期由框架自动管理,过程零停机。

    3. SQL 语法兼容
      支持使用 MySQL 语法完成搜索查询操作,无需学习复杂的 DSL 语句。支持 and、or、like、in 等常用 SQL 语法。

    4. Lambda 表达式支持
      采用 Lambda 风格编程,提供类型安全的字段访问,避免手动输入字段名可能产生的错误,提升代码可读性和开发效率。

    5. 无缝 Spring Boot 集成
      与 Spring Boot 生态深度集成,提供开箱即用的自动配置,无需复杂的手动配置,支持 Spring Boot Actuator 监控,完美融入企业级应用架构。

    6. 丰富的查询功能
      支持复杂的嵌套查询、聚合查询、范围查询、高亮显示等高级搜索功能,同时保持 API 的简洁易用,满足各种业务场景需求。

    7. 分布式架构支持
      完美适配 Easysearch 的分布式特性,支持集群模式部署,具备高可用性和横向扩展能力,满足企业级大规模数据处理需求。

    8. 成熟稳定的国产 ORM 框架
      作为 Dromara 开源社区下的顶级开源项目,Easy-Es 已在国内众多企业和项目中得到广泛应用和验证,拥有活跃的中文社区和完善的文档支持,为企业级应用提供了可靠的技术保障。

      04 | 快速上手示例


      1. 添加依赖


      根据您使用的构建工具,选择对应的配置方式:

      Maven 项目


      pom.xml 配置

      ```xml


      11
      11
      2.7.0
      UTF-8





      org.springframework.boot
      spring-boot-dependencies
      ${spring-boot.version}
      pom
      import






      org.dromara.easy-es
      easy-es-boot-starter
      2.1.0-easysearch


      org.springframework.boot
      spring-boot-starter-web






      org.springframework.boot
      spring-boot-maven-plugin
      ${spring-boot.version}



      repackage






      ```

      **Maven 启动命令**:

      ```bash
      # 运行应用
      mvn spring-boot:run

      # 编译打包
      mvn clean package
      ```

      #### Gradle 项目

      **build.gradle 配置**:

      ```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 启动命令**:

      ```bash
      # 运行应用
      ./gradlew bootRun

      # 编译打包
      ./gradlew clean build
      ```

      ### 2. 配置文件设置

      **application.yml**(根据实际 Easysearch 部署情况修改):

      ```yaml
      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. 实体类定义

      ```java
      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 接口

      ```java
      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 {
      }
      ```

      ### 5. 启动类配置

      ```java
      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. 业务使用示例

      ```java
      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 listDocumentByTitle(@RequestParam String title) {
      LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>();
      wrapper.eq(Document::getTitle, title);
      return documentMapper.selectList(wrapper);
      }

      /**
      * 高亮搜索
      */
      @GetMapping("/highlightSearch")
      public List highlightSearch(@RequestParam String content) {
      LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>();
      wrapper.match(Document::getContent, content);
      return documentMapper.selectList(wrapper);
      }

      /**
      * 查询所有数据
      */
      @GetMapping("/selectAll")
      public List selectAll() {
      LambdaEsQueryWrapper wrapper = new LambdaEsQueryWrapper<>();
      return documentMapper.selectList(wrapper);
      }

      /**
      * 聚合查询 - 按创建时间和点赞数分组统计
      */
      @GetMapping("/aggByDateAndStar")
      public Aggregations aggByDateAndStar() {
      LambdaEsQueryWrapper 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. 快速测试

      启动应用后,可以通过以下接口测试:

      ```bash
      # 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 独有的功能,助力您快速实现各种场景的开发。

    官网:<https://www.easy-es.cn>;

    Easy-Es for Easysearch 是一款简化 Easysearch 国产化搜索引擎操作的开源框架,全自动智能索引托管。同时也是国内首家专门针对 Easysearch 客户端简化的工具。它简化 CRUD 及其它高阶操作,可以更好的帮助开发者减轻开发负担。底层采用 Easysearch Java Client,保证其原生性能及拓展性。

    项目地址:<https://gitee.com/dromara/easy ... gt%3B

    关于极限科技


    极限科技(全称:极限数据(北京)科技有限公司)是一家专注于实时搜索与数据分析的软件公司。

    旗下品牌:极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验,为用户提供安全、稳定、高性能的国产搜索解决方案。

    官网:<https://infinilabs.cn>;

    作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。

APM(一): Skywalking 与 Easyearch 集成

INFINI Labs 小助手 发表了文章 • 0 个评论 • 8273 次浏览 • 2025-12-12 14:22 • 来自相关话题


概述


SkyWalking 是一个开源的可观测性平台,用于收集、分析、聚合和可视化服务和云原生基础设施的数据。SkyWalking 提供了一种简单的方法,即使在云之间也能保持对分布式系统的清晰视图。它是一个现代的 APM,专门为云原生、基于容器的分布式系统设计。

SkyWalking 涵盖了云原生世界中所有的可观测性需求,包括:

  • Tracing: SkyWalking 原生数据格式,以及 v1 和 v2 格式的 Zipkin 跟踪都得到支持。
  • Metrics: SkyWalking 支持成熟的指标格式,包括原生计量格式、OTEL 指标格式和 Telegraf 格式。SkyWalking 与服务网格平台(通常为 Istio 和 Envoy)集成,将可观测性构建到数据平面或控制平面。此外,SkyWalking 原生代理可以在指标模式下运行,从而显著提升性能。
  • Logging: 包括从磁盘收集或通过网络收集的日志。原生代理可以自动将追踪上下文与日志绑定,或使用 SkyWalking 通过文本内容绑定追踪和日志。
  • Profiling: Profiling 是一种强大的工具,帮助开发者从代码行角度理解应用程序的性能。SkyWalking 提供了内置于原生语言代理和独立的 eBPF 代理的剖析功能。
  • Event: 事件是一种特殊类型的数据,用于记录系统中的重要时刻,例如版本升级、配置变更等。将事件与指标关联有助于解释指标中的峰值或谷值,将事件与追踪和日志关联有助于排查根本原因。

    更详细的信息请大家移步 [Skywalking](https://skywalking.apache.org/) 官方网站。

    测试环境


    本篇使用的 Skywalking 版本是 10.2.0 ,需要 Java 11/17/21。

    [Easyearch](https://easysearch.cn) 使用的版本是 1.14.1,需要开启 Elastic 兼容模式,具体操作参考[文档](https://infinilabs.cn/blog/202 ... earch/) 。

    生成 Java 密钥库文件


    使用如下命令将 Easysearch 的 CA 证书(ca.crt)导入到一个新的 Java 密钥库文件(es_keystore.jks)中,以便 SkyWalking 能够信任由该 CA 颁发的所有证书。生产环境中使用请替换命令中的密码。

    plain<br /> keytool -import -v -trustcacerts -file ca.crt -keystore es_keystore.jks -keypass changeit -storepass changeit<br />

    修改配置文件


    SkyWalking 后端服务配置文件为 config/application.yml,这也是与 Easyearch 集成时需要修改的文件。Skywalking 与 Easyearch 集成有两种通信方式:http 或 https。http 方式非常简单,留给大家自行探索。本篇采用 https 方式,这也是 Easysearch 初始化后默认对外服务的协议。

    拷贝上面生成的密钥库文件到 Skywalking 的 home 目录下,修改 application.yml 的 storage 部分

    ```plain
    storage:
    selector: ${SW_STORAGE:elasticsearch}
    banyandb:

    Since 10.2.0, the banyandb configuration is separated to an independent configuration file: bydb.yaml.

    elasticsearch:
    namespace: ${SW_NAMESPACE:""}
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:es1.infini.cloud:9200}
    protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"https"}
    connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:3000}
    socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30000}
    responseTimeout: ${SW_STORAGE_ES_RESPONSE_TIMEOUT:15000}
    numHttpClientThread: ${SW_STORAGE_ES_NUM_HTTP_CLIENT_THREAD:0}
    user: ${SW_ES_USER:"admin"}
    password: ${SW_ES_PASSWORD:"infiniyyds@2025"}
    trustStorePath: ${SW_STORAGE_ES_SSL_JKS_PATH:"../es_keystore.jks"}
    trustStorePass: ${SW_STORAGE_ES_SSL_JKS_PASS:"changeit"}
    ```

    注意 clusterNodes 配置的是域名,需要在 Skywalking 的主机上用 /etc/hosts 解析成具体的地址,如果有多个 Easysearch 节点,可以用逗号分隔。

    启动


    确保 Easysearch 启动完毕后,再启动 Skywalking。正常启动完成后,可访问 Skywalking 服务页面,默认端口 8080。

    ![](https://infinilabs.cn/img/blog ... /1.png)

    正常连接后,Skywalking 会在 Easysearch 中创建很多 sw 开头的索引。

    ![](https://infinilabs.cn/img/blog ... /2.png)

    OK,服务集成就到此完毕,后续我们将探索更多的 APM 内容。

    关于 Easysearch


    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

    官网文档:<https://docs.infinilabs.com/easysearch>;

    作者:杨帆,极限科技(INFINI Labs)高级解决方案架构师、《老杨玩搜索》栏目 B 站 UP 主,拥有十余年金融行业服务工作经验,熟悉 Linux、数据库、网络等领域。目前主要从事 Easysearch、Elasticsearch 等搜索引擎的技术支持工作,服务国内私有化部署的客户。

Easysearch 2.0.0 性能测试

INFINI Labs 小助手 发表了文章 • 0 个评论 • 9421 次浏览 • 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



      v1.15.6


      180,868




      v2.0.0


      190,712





      ### 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



    v1.15.6


    9.14 min




    v2.0.0


    4.16 min






    Cumulative Flush Time (min) - Lower is Better



    v1.15.6


    12.57 min




    v2.0.0


    7.54 min





    这些优化使得 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




    Default Query (50th percentile)


    v1.15.6


    19.97ms




    v2.0.0


    17.69ms






    Term Query (50th percentile)


    v1.15.6


    4049ms




    v2.0.0


    3244ms






    Range Query (50th percentile)


    v1.15.6


    42.19ms




    v2.0.0


    28.81ms






    ### 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




    Desc Sort


    v1.15.6


    516ms




    v2.0.0


    99ms






    Asc Sort + After


    v1.15.6


    1272ms




    v2.0.0


     33ms






    #### 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




    50th Percentile


    v1.15.6


    6511.65ms




    v2.0.0


    4623.87ms






    90th Percentile


    v1.15.6


    6881.70ms




    v2.0.0


    5972.79ms






    ### 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%

    这是为了平衡写入性能和查询性能所做的策略调整。用户可以根据实际场景需求,通过以下参数进行优化:

    json<br /> {<br /> "index.merge.scheduler.max_thread_count": "1",<br /> "index.merge.policy.max_merged_segment": "5gb"<br /> }<br />

    技术架构改进


    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 层面保持兼容,但建议:

    1. 测试环境验证:先在测试环境进行充分验证
    2. 配置审查:检查 Merge 相关配置是否需要调整
    3. 监控指标:升级后密切关注 GC、内存、延迟等指标
    4. 滚动升级:生产环境建议采用滚动升级方式

      性能测试环境


      本次测试使用 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

    ![](https://infinilabs.cn/img/blog ... er.png)

    INFINI Easysearch 是一个分布式的搜索型数据库,实现非结构化数据检索、全文检索、向量检索、地理位置信息查询、组合索引查询、多语种支持、聚合分析等。Easysearch 可以完美替代 Elasticsearch,同时添加和完善多项企业级功能。Easysearch 助您拥有简洁、高效、易用的搜索体验。

  • 官网: https://easysearch.cn
  • 文档: https://docs.infinilabs.com/easysearch/main

    作者:张磊,极限科技(INFINI Labs)搜索引擎研发负责人,对 Elasticsearch 和 Lucene 源码比较熟悉,目前主要负责公司的 Easysearch 产品的研发以及客户服务工作。
    原文:https://infinilabs.cn/blog/202 ... ents/