ZincSearch — 单二进制 Go 写的 ES 替代
是什么
ZincSearch 是 Prabhat Sharma(前 AWS Solutions Architect)2021 年用 Go 写的轻量级搜索引擎,目标只有一个:把 elasticsearch 那 1-2GB JVM heap 压成几十 MB 的常驻内存。
日常类比:
- elasticsearch 像一栋装满消防、空调、配电的大楼——功能齐,启动慢,水电费贵
- ZincSearch 像一台路边咖啡车——功能少一截,但插电就能营业,整车还没大楼一间办公室大
ZincSearch 不重写搜索本身。底层用 Bluge(纯 Go 写的索引库,和 tantivy、Bleve 是同代竞品),上面套一层 ES 兼容的 REST API + Vue Web UI,打包成一个静态二进制。docker 一行起服务,curl 直接灌数据。
为什么重要
不理解 ZincSearch 的取舍,下面这些事会困惑:
- ES 太重在很多场景是真问题:边缘节点 / 树莓派 / 小 VPS / 个人项目,上 ES 等于整台机器只剩它一个进程能跑。ZincSearch 的卖点就是把 “搜索” 这件事的资源门槛拉回到 100 MB 级。
- 单二进制 = 运维成本骤降:不用 JVM、不用配
vm.max_map_count、不用看 GC、不用调 heap size。新人 docker pull 后 5 分钟就有可用搜索。 - ES API 兼容意味着迁移成本低:已有用
_bulk/_doc灌数据的代码可以改个 host 直接跑,不用重写客户端。 - 作者已转向 opensearch 之外的另一条路:2022-2023 同一个作者开了 OpenObserve 做日志可观测性。ZincSearch 现在是”搜索专用”,日志场景官方让你去用 OpenObserve。这个分流本身值得知道。
核心要点
ZincSearch 凭什么轻?拆三件事:
1. 用 Bluge 而不是 Lucene
elasticsearch 底层是 Lucene(Java 写的,跑在 JVM 上)。ZincSearch 底层是 Bluge——Marty Schoch 等人主导的 Bluge Labs 用 Go 重写的纯 Go 索引库,是 Bleve 的演进版(共用 Vellum 这个 FST 库)。
换语言带来的直接收益:
- 没有 JVM = 没有几百 MB heap 起步价
- 静态二进制 = 不用装运行时
- Goroutine 模型 = 并发开销低于 JVM 线程
2. 单机,不做集群
ES 的复杂度一半来自分布式(分片、副本、coordinator、gossip)。ZincSearch 直接砍掉这一层——只跑单机,不做 HA。这是它能做小的根本原因。
代价:单机性能就是天花板。但对”中小数据量 + 应用内搜索”的场景来说,这天花板足够高。
3. 兼容 ES API 而不是重新发明
REST 接口照搬 ES 的 _bulk、_doc、_search 路径。DSL 查询语法部分兼容(标记 work-in-progress)。这意味着:
# 原来打到 ES 的 curl,改个 host 就能打到 ZincSearchcurl -X POST 'http://localhost:4080/api/_bulk' \ -H 'Authorization: Basic <token>' --data-binary @data.ndjson迁移成本接近零,是 ZincSearch 拿用户的关键钩子。
实践案例
案例 1:docker 一行起服务
docker run -p 4080:4080 \ -e ZINC_FIRST_ADMIN_USER=admin \ -e ZINC_FIRST_ADMIN_PASSWORD=Pass123 \ public.ecr.aws/zinclabs/zincsearch:latest跑完访问 localhost:4080,自带 Vue Web UI 登录页。对比 elasticsearch 首次启动要改 vm.max_map_count、设密码、调 heap,差距明显。
案例 2:灌一批文档(ES 兼容 _bulk)
curl -X POST 'http://localhost:4080/api/_bulk' \ -u admin:Pass123 \ -H 'Content-Type: application/json' \ --data-binary $'{"index":{"_index":"movies"}}\n{"title":"Matrix","year":1999}\n{"index":{"_index":"movies"}}\n{"title":"Inception","year":2010}\n'不用先 PUT mapping。schema-less,字段类型自动推断。
案例 3:搜索
curl -X POST 'http://localhost:4080/api/movies/_search' \ -u admin:Pass123 \ -H 'Content-Type: application/json' \ --data '{"search_type":"match","query":{"term":"matrix","field":"title"}}'返回 JSON 结构和 ES 类似但不完全一样——native API 是 ZincSearch 自己的 schema,DSL 兼容层只覆盖常用查询。
案例 4:内存占用对比
同样灌 100 万条 1KB 文档:
| 引擎 | 常驻 RSS | 启动时间 |
|---|---|---|
| elasticsearch 8.x | 1.5-2 GB(默认 heap) | 30-60 秒 |
| ZincSearch v0.4 | 80-150 MB | < 2 秒 |
数字会随负载浮动,但量级差是稳定的。这就是”个人项目 / 边缘节点”选 ZincSearch 而不是 ES 的核心理由。
踩过的坑
-
DSL 兼容是 work-in-progress:复杂查询(nested、has_child、function_score、pipeline aggregation)大概率不工作。生产前用真实 query 跑一遍兼容性测试,别假设 ES 客户端原样能用。
-
没有集群 = 没有水平扩展:单机塞满就只能升配 / 拆 index / 上下游手动分流。数据涨到几百 GB 就该重新评估,回 elasticsearch / opensearch / meilisearch 集群版本。
-
作者重心已转 OpenObserve:v0.4.10(2024 年 1 月)后维护节奏变慢,issue 响应慢于早期。日志场景官方明说让你去用 OpenObserve,搜索场景社区维护。
-
磁盘存储无对象后端:默认本地磁盘,无内置 S3 / MinIO。要冷热分层、跨机共享需要自己在外面搭。OpenObserve 有 S3 后端,ZincSearch 没有。
-
聚合能力比 ES 弱一截:基础 terms / metric agg 可用;nested、pipeline、bucket script 这些 ES 高级聚合大概率不行。复杂 BI 场景别指望它。
适用 vs 不适用场景
适用:
- 应用内搜索 / 文档站搜索 / 博客搜索
- 资源受限节点(边缘、树莓派、低配 VPS、Serverless 容器)
- 中小数据量(< 100 GB)单机搜索
- 已有 ES
_bulk客户端代码,想低成本换底层
不适用:
- 大规模日志检索 → 用 elasticsearch / opensearch / OpenObserve
- 需要分布式 HA / 跨机分片 → 用 elasticsearch
- 重度复杂聚合 / nested DSL → 用 elasticsearch
- C 端搜索追求拼写容错出色 → 用 meilisearch
- 嵌入式搜索库(不要服务进程)→ 用 tantivy / minisearch
历史
- 2021 年:Prabhat Sharma 在
prabhatsharma/zinc起项目,瞄准 ES 资源占用过重的真实痛点(自己跑业务搜索时受不了 JVM 的内存) - 2022 年:项目改名 ZincSearch,组织搬到
zincsearch/zincsearch,社区聚拢 - 2022-2023 年:作者开 ZincObserve(后更名 OpenObserve)做日志可观测性,把”日志/指标/追踪”这条线从 ZincSearch 分出去
- 2024 年 1 月:v0.4.10 发布,pre-GA。重心转 OpenObserve 后社区接手 ZincSearch 维护
整个轨迹很典型:先做对资源敏感的”小 ES 替代” → 发现日志和搜索是两件事 → 拆出独立产品。和 meilisearch 不同,MeiliSearch 是”开发者体验优先”路线,ZincSearch 是”资源占用优先”路线。
学到什么
- 重写不一定要做得更全,可以做得更小——ZincSearch 砍掉 ES 的分布式层,换语言换底层索引库,目标只有一个:把内存压到 1/10
- API 兼容是迁移最强的钩子——不重新发明协议,直接复用 ES 的
_bulk/_doc,迁移成本归零 - 底层换语言(Java → Go)= 静态二进制 + 无 GC 暖机 + 资源占用骤降——这条路 caddy(Web 服务器)、meilisearch(用 Rust)也走过
- 作者注意力是开源项目的隐性资源——ZincSearch 慢下来不是技术问题,是作者把精力投到 OpenObserve。读 GitHub 项目要看这个
延伸阅读
- 官方文档:zincsearch-docs.zinc.dev
- elasticsearch —— 工业标准对照,理解砍掉了什么
- meilisearch —— 同代另一种”反 ES”路线(Rust + 开发者体验)
- tantivy —— Rust 版 Lucene,Bluge 在 Go 生态里的对手
关联
- elasticsearch —— 直接对标对象,理解砍了哪些功能
- meilisearch —— 同样轻量化路线,但侧重开发者体验而非资源占用
- opensearch —— ES 的 AWS fork,仍然重,与 ZincSearch 价值取向相反
- tantivy —— Rust 版 Lucene,Bluge(ZincSearch 底层)是它在 Go 生态的同位
- minisearch —— 浏览器内嵌入式搜索,比 ZincSearch 还小一截