Weaviate 与 Vespa 容器化实测:208MB 对 1.72GB,1.6G 的机器上只有前者起得来
两条 docker run 写在同一台机器上:Weaviate 八秒返回 200,Vespa 五秒后 exit 2。同一个下午,同样的 2 核 1.6GB,差别不在功能表上。
💡 你将学到
两条 docker run 写在同一台机器上:Weaviate 八秒返回 200,Vespa 五秒后 exit 2。同一个下午,同样的 2 核 1.6GB,差别不在功能表上。
两条命令写在同一个下午。Weaviate 那条八秒后返回 200,Vespa 那条五秒就 exit 2,Java 一行日志都没来得及打。选型榜单都在排混合检索和大规模排序,没人写这两个镜像对机器的要求差着三倍多。
结论放前面:2 核 1.6GB 的机器,Weaviate 能跑,Vespa 起不来,调参救不了。下面是我在这台机器上跑出来的全部数字,跑法都跟着给出。
一、镜像体积与进程模型
环境:2 核 Intel Xeon Platinum,1.6GB 内存,40GB 系统盘,Docker 24.0.9,内核 6.6.102。
| 项目 | Weaviate 1.40.3 | Vespa |
|---|---|---|
| 镜像体积(docker images) | 208MB | 1.72GB |
| 拉取耗时(同一条链路) | 不到一分钟 | 1 分 48 秒 |
| 容器内进程 | 单个 Go 二进制 | configserver 与 configproxy 两个 JVM,加内容节点与日志服务 |
| 对外端口 | 8080(HTTP) | 8080 查询、19071 配置 |
| 就绪判据 | /v1/.well-known/ready 返 200 | 19071/state/v1/health |
| 本机冷启动到 200 | 7.97 秒 | 5.4 秒后 exit 2 |
| 本机实测内存占用 | 空闲 10.9MB,写入一万条后 80.1MB | 未进入可服务状态 |
体积差不是打包偷懒。Weaviate 是单个 Go 进程,能力靠模块挂载,/v1/meta 里把 text2vec-、multi2vec-、reranker-、generative- 四类列得一清二楚,不用哪类就不用装哪类的后端。Vespa 是 JVM 体系:配置服务和配置代理各起一个 JVM,底下真正存数据的内容节点又是一套,每样都要占内存,谁省不下来。
二、Weaviate:600MB 限额下跑完全程
启动命令照下面这个来,600MB 是硬限额,超了直接 OOM 杀,等于把内存问题提前暴露而不是等半夜崩:
docker run -d --name wv --memory=600m -p 8080:8080 \ -e AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED=true \ -e DEFAULT_VECTORIZER_MODULE=none \ -e PERSISTENCE_DATA_PATH=/var/lib/weaviate \ -e CLUSTER_HOSTNAME=node1 \ semitechnologies/weaviate:latest
冷启动到 ready 返 200 用了 7.97 秒(200ms 轮询一次,误差不超过 200ms)。空闲时 docker stats 显示 10.9MB,同参数开的第二个容器 16.5MB,Go 进程的底子确实轻。
再建一个自备向量的类,写一万条 384 维随机向量,一批 100 条,共 100 次请求:32.12 秒写完,311 条每秒。写完容器内存 80.1MB。Aggregate 查回来 count=10000,一条没丢。这批向量是随机数,只为压写入和查询,没有语义,别拿去评判召回率。
紧接着做近邻查询,30 次 top10:p50 474ms,p90 1309ms,最慢一次 12.9 秒。慢的那一次不是玄学,写入刚结束,HNSW 还在后台建图,索引没搭完查询只能硬扫。生产上要么等索引建完再放流量,要么把批量写入放在低峰。同一台机器上还挂着 nginx 和统计服务在跑,这几个数偏保守。
| Weaviate 实测项 | 结果 |
|---|---|
| 冷启动到 ready | 7.97 秒 |
| 空闲内存 | 10.9MB |
| 10000 条 × 384 维写入 | 32.12 秒(311 条/秒) |
| top10 近邻查询(30 次) | p50 474ms / p90 1309ms |
| 写入后容器内存 | 80.1MB / 600MB 限额 |
三、Vespa:连 JVM 都没起来
同样一条 docker run,镜像换成 vespaengine/vespa:latest,容器 5.4 秒后退出,退出码 2。日志第一行原文:
panic: Running the Vespa container image requires at least 4GB available memory. See the relevant docs (https://docs.vespa.ai/en/operations/self-managed/docker-containers.html#memory) or set VESPA_IGNORE_NOT_ENOUGH_MEMORY=true
拦它的是镜像自己的入口脚本,不是内核 OOM,所以连 Java 都没开始起,镜像先数了一遍机器内存。
把 VESPA_IGNORE_NOT_ENOUGH_MEMORY=true 加上强开,容器切到 Up 状态。三分钟里 19071/state/v1/health 一直是 000,8080 查询端口同样 000,docker logs 读 25 秒吐不出一个字,宿主机 load average 从 0.3 一路顶到 24。容器活着,服务没活。
官方文档写的是单节点应用至少 4GB,同一页还有一句「内存不足是 Docker 里测 Vespa 最常见的问题」。这台机器总内存 1.6GB,不是差一点,是差一档设备规格。小机器上讨论 Vespa 的排序能力没有意义,它先要求一台能装下它的机器。
四、两份可以直接用的 compose
Weaviate 这份是我上面那台机器的等比版本,健康检查用镜像里自带的 wget(这个镜像有 wget 没有 curl,写成 curl 检查会一直 unhealthy):
services:
weaviate:
image: semitechnologies/weaviate:latest
restart: unless-stopped
ports: ["127.0.0.1:8080:8080"]
environment:
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
DEFAULT_VECTORIZER_MODULE: "none"
PERSISTENCE_DATA_PATH: "/var/lib/weaviate"
CLUSTER_HOSTNAME: "node1"
volumes: ["./wv-data:/var/lib/weaviate"]
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/v1/.well-known/ready"]
interval: 10s
timeout: 3s
retries: 5
Vespa 这份只在内存 4GB 以上用,跑之前先 docker info 看一眼 Total Memory:
services:
vespa:
image: vespaengine/vespa:latest
hostname: vespa-container
ports: ["8080:8080", "19071:19071"]
ulimits:
nofile: {soft: 65536, hard: 65536}
nproc: 4096
hostname 不是随手起的名字,官方启动示例固定写 vespa-container,配置服务按这个主机名登记节点,compose 里就用 hostname 字段给它,别改。ulimit 那段也不是可选项,文档要求 nofile 和 nproc 达到系统限值,不然容器里进程数撑不住。端口映射到公网前记得只放 8080,19071 是配置服务,暴露出去等于把集群配置交给所有人改。
五、怎么选,看内存先看功能
- 机器不到 4GB:这一档只有 Weaviate 能进,Vespa 直接从候选里划掉,功能表再强也白搭。
- 要多阶段排序、排序表达式、在线模型推理:Vespa 的主场,前提是先有 8GB 以上的机器,这不是小机器上的选项。
- 想开箱就有向量化和混合检索:Weaviate 的模块在 /v1/meta 里全列着,配一个 text2vec 后端就省掉自己算向量的那层服务。
- 运维人手少:Weaviate 一个进程,docker logs 就是全部日志;Vespa 得先弄清 configserver 和内容节点的关系,出事时信息量大得多。
我最后把 Weaviate 留在这台小机器上做检索,Vespa 等到有 8GB 的机器再试。功能对比表网上到处都有,但那张表不会告诉你,一半的候选在你的机器上根本起不来。
相关文章
本站文章由编辑人工撰写,收录的工具均经过实测或公开资料核验。文中链接指向工具官网或 GitHub 仓库,仅作信息参考,不构成付费推广。