1. 项目概述:为什么要在Ubuntu上部署Milvus及其可视化工具?
如果你正在处理海量的非结构化数据,比如图片、视频、音频或者长文本,并且需要从中快速、准确地找到相似的内容,那么向量数据库就是你绕不开的技术栈。Milvus,作为这个领域的明星开源项目,已经成为了构建AI应用(如推荐系统、图像检索、智能问答)的基石。它专门为存储和检索高维向量而设计,性能强悍,生态丰富。
然而,对于很多开发者,尤其是刚接触这个领域的朋友来说,从零开始部署Milvus并配上一个好用的可视化界面,可能会遇到不少“拦路虎”。官方文档虽然详尽,但面对不同的操作系统、不同的部署方式(Standalone单机版 vs. Cluster集群版),以及后续的运维管理,新手很容易感到迷茫。特别是在Ubuntu这样的Linux生产环境中,每一步操作的稳定性和可复现性都至关重要。
今天,我就结合自己多次在Ubuntu服务器上部署和运维Milvus的经验,带你走一遍最实用、最稳妥的路线:使用Docker Compose部署Milvus单机版,并集成Attu这个官方推荐的可视化管理工具。这个组合能让你在几分钟内就拥有一个功能完整的向量数据库开发环境,无论是用于本地学习、原型验证,还是小规模的生产部署,都非常合适。我们不仅会“跑通”流程,更会深入每个步骤背后的原理和可能遇到的坑,让你知其然,更知其所以然。
2. 环境准备与核心组件解析
在动手之前,我们先花点时间理清整个技术栈。理解每个组件的作用,能让你在遇到问题时快速定位,而不是盲目地复制粘贴命令。
2.1 系统与Docker环境确认
我们的部署基石是Ubuntu和Docker。为什么是Docker?因为它通过容器化技术,将Milvus及其依赖(如元数据存储Etcd、消息队列Pulsar)打包成一个个独立的、环境一致的镜像,完美解决了“在我机器上好好的”这类环境依赖问题。
首先,确保你的Ubuntu系统版本在18.04或以上,推荐使用20.04 LTS或22.04 LTS,以获得更好的长期支持。打开终端,我们进行一系列检查:
- 系统架构检查:Milvus官方提供了x86_64和ARM64的镜像。运行
uname -m,确认输出是x86_64(常见Intel/AMD CPU)或aarch64(ARM架构,如苹果M系列、树莓派)。 - Docker与Docker Compose安装:这是最关键的一步。很多安装失败都源于Docker环境不纯净或版本不匹配。
- 安装Docker Engine:建议通过官方仓库安装,避免使用过时的
docker.io包。
# 卸载旧版本(如果存在) sudo apt-get remove docker docker-engine docker.io containerd runc # 更新apt包索引并安装依赖 sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release # 添加Docker官方GPG密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置稳定版仓库 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装Docker Engine sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin- 验证安装:运行
sudo docker run hello-world,如果能看到欢迎信息,说明Docker安装成功。 - 关于Docker Compose:注意,我们安装的是
docker-compose-plugin,它提供了docker compose命令(注意中间没有横线)。这是新版本的标准,功能比旧的docker-compose脚本更强大。可以通过docker compose version来验证。
- 安装Docker Engine:建议通过官方仓库安装,避免使用过时的
注意:上述命令中涉及从网络下载密钥和软件源,请确保你的Ubuntu系统网络连接正常,且能访问相关域名。如果身处特殊网络环境,可能需要配置代理,但这属于基础网络配置范畴,请根据自身情况处理。
- 非root用户操作Docker(可选但推荐):每次执行docker命令都要加
sudo很麻烦,也不安全。可以将当前用户加入docker用户组。
操作后,必须完全退出当前终端会话并重新登录,这个改动才会生效。之后就可以直接使用sudo usermod -aG docker $USERdocker和docker compose命令了。
2.2 Milvus单机版架构浅析
当我们选择使用Docker Compose部署“单机版”时,我们启动的并不是一个单一的容器,而是一组协同工作的容器。理解这个架构,对排查问题至关重要。
- Etcd: 负责存储Milvus的元数据。什么是元数据?比如你创建的集合(Collection)叫什么名字、里面有哪些字段(Field)、每个字段是什么类型、集合的索引(Index)配置是什么等等。这些是描述数据的数据,至关重要。Etcd是一个高可用的键值存储,在这里以单节点模式运行。
- MinIO / Pulsar: 在Milvus 2.x版本中,单机版默认使用MinIO作为对象存储,用于保存插入的向量数据文件;使用Pulsar作为消息队列,管理数据插入、删除等操作的日志流。这两个组件共同承担了“存储引擎”的角色。而在集群部署中,通常会替换为更专业的存储系统如S3和 Kafka/Pulsar集群。
- Milvus Standalone: 这是核心服务本身。它接收来自客户端的GRPC/HTTP请求,协调Etcd、MinIO、Pulsar,执行具体的向量搜索、插入、删除等计算任务。
为什么选择单机版?因为它将所有组件打包,通过Docker Compose一键拉起,资源占用相对较小(建议至少4GB内存),非常适合开发、测试和学习。当你需要处理亿级数据或要求高可用时,再考虑迁移到分布式集群部署。
2.3 可视化工具选型:为什么是Attu?
部署好Milvus后,你当然可以通过Python/Java/Go等SDK用代码操作它。但有一个可视化工具,能让你直观地看到数据库状态、管理数据、测试查询,效率会高很多。这里我强烈推荐Attu。
Attu是Milvus官方的开源可视化运维管理工具,相当于Milvus的“phpMyAdmin”或“Redis Desktop Manager”。它的优势非常明显:
- 官方维护,兼容性最佳:与Milvus版本同步更新,API兼容性有保障,不用担心因版本升级而无法使用。
- 功能全面:支持集合管理(创建、删除)、数据插入/删除/查询、索引管理、系统监控(内存、磁盘、QPS等)。
- 开箱即用:同样提供Docker镜像,可以轻松集成到我们的Docker Compose环境中,与Milvus服务在同一个网络内通信,配置简单。
- 直观的向量搜索:可以直接在界面中输入向量或上传文件进行相似性搜索,并可视化展示结果,对于调试和演示非常友好。
市面上也有一些其他工具,但要么功能不全,要么更新不及时。Attu是目前最稳妥的选择。
3. 实战部署:一步步拉起Milvus与Attu
理论清晰了,我们开始动手。整个过程就像搭积木,我们只需要下载一个“说明书”(docker-compose.yml),然后一条命令让Docker按照说明书把各个“积木”(容器)组装起来。
3.1 获取部署配置文件
Milvus团队非常贴心地将所有依赖的配置都打包好了。我们只需要下载对应的YAML文件。
- 创建一个专属目录,用于存放所有相关文件,避免混乱。
mkdir -p ~/milvus-standalone && cd ~/milvus-standalone - 下载最新稳定版的Milvus单机版Docker Compose配置文件。以撰写本文时的最新稳定版
v2.4.0为例。wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml -O docker-compose.ymlwget是一个命令行下载工具。如果系统没有,可以用sudo apt install wget安装。-O docker-compose.yml参数指定下载的文件重命名为docker-compose.yml,这是docker compose命令默认寻找的文件名,方便后续操作。
重要检查:下载完成后,用编辑器(如nano docker-compose.yml)打开这个文件,快速浏览一下。你会看到它定义了etcd、minio、standalone等服务。确保文件内容完整,没有因网络问题下载残缺。
3.2 启动Milvus服务
万事俱备,只欠东风。在docker-compose.yml所在目录,执行启动命令:
sudo docker compose up -d或者,如果你使用的是老版本的docker-compose脚本(命令中间有横线):
sudo docker-compose up -dup: 创建并启动容器。-d: 让容器在“后台”(Detached)运行,这样终端不会被日志占满。
执行后,Docker会依次执行以下操作:
- 从Docker Hub拉取(Pull)配置文件中指定的镜像(如果本地没有)。
- 按照定义的顺序启动容器(
etcd->minio->standalone)。 - 为这些容器创建一个独立的网络,使它们能通过服务名互相访问。
第一次启动会花费一些时间下载镜像,请耐心等待。完成后,使用以下命令检查容器状态:
sudo docker compose ps你应该看到类似下面的输出,所有服务的状态(STATUS)都应该是Up:
NAME COMMAND SERVICE STATUS PORTS milvus-etcd "etcd -advertise-cli…" etcd Up (healthy) 2379-2380/tcp milvus-minio "/usr/bin/docker-ent…" minio Up (healthy) 9000/tcp, 9001/tcp milvus-standalone "/tini -- milvus run…" standalone Up (healthy) 19530/tcp, 9091/tcp看到所有服务都是Up (healthy),恭喜你,Milvus单机版已经成功运行!它现在正在监听19530端口(GRPC)和9091端口(HTTP),等待你的连接。
3.3 集成并启动Attu可视化界面
Milvus服务跑起来了,现在我们把“驾驶舱”Attu也装上。Attu的集成非常简单,我们不需要修改已有的docker-compose.yml,而是利用Docker Compose的“多文件配置”特性。
在同一个目录(
~/milvus-standalone)下,创建一个新的配置文件,专门用于Attu。我们叫它docker-compose.attu.yml。nano docker-compose.attu.yml将以下内容复制进去:
version: '3.5' services: attu: container_name: milvus-attu image: zilliz/attu:v2.4.0 environment: MILVUS_URL: milvus-standalone:19530 ports: - "8000:3000" depends_on: - standalone networks: - defaultimage: zilliz/attu:v2.4.0: 指定Attu的镜像,版本最好与Milvus保持一致(这里是v2.4.0)。MILVUS_URL: milvus-standalone:19530: 这是最关键的环境变量。它告诉Attu去哪里连接Milvus。milvus-standalone就是在主docker-compose.yml中定义的Milvus服务名,Docker网络内可以通过这个名字直接访问。端口是19530。ports: - "8000:3000": 将容器内的3000端口映射到宿主机的8000端口。这意味着你可以在浏览器通过http://你的服务器IP:8000访问Attu。depends_on: - standalone: 声明Attu容器依赖于standalone服务,确保Milvus先启动。networks: - default: 让Attu容器加入到Milvus服务的同一个默认网络中,这样它们才能互通。
启动Attu服务。使用
-f参数指定多个配置文件。sudo docker compose -f docker-compose.yml -f docker-compose.attu.yml up -d attu这个命令会基于两个配置文件定义的叠加服务,以后台模式启动
attu这个服务。再次检查所有容器状态:
sudo docker compose -f docker-compose.yml -f docker-compose.attu.yml ps现在你应该能看到四个容器在运行,包括新加入的
milvus-attu。
4. 连接验证与基础操作指南
服务都跑起来了,是时候验收成果了。我们从两个层面验证:命令行基础连通性测试,以及可视化界面的实际操作。
4.1 基础连通性测试
在进一步操作前,我们先确认Milvus服务本身是否健康。最简单的方法是使用netcat(nc) 命令检查端口是否开放。
# 检查19530端口(GRPC) nc -zv localhost 19530 # 如果成功,会显示 “Connection to localhost 19530 port [tcp/*] succeeded!” # 检查9091端口(HTTP) nc -zv localhost 9091如果端口不通,可能是Milvus容器启动失败。回头检查docker compose logs standalone查看日志排错。
更专业的验证是使用Milvus自带的milvus_cli工具,但它需要额外安装Python包。对于快速验证,用Attu界面更直观。
4.2 使用Attu进行可视化管理和操作
打开你的浏览器,访问http://<你的Ubuntu服务器IP地址>:8000。如果你是在Ubuntu本机操作,可以直接访问http://localhost:8000。
首次打开,你会看到Attu的连接界面。
- Address: 这里填写Milvus的服务地址。由于Attu和Milvus在同一个Docker网络内,我们直接使用服务名
milvus-standalone和端口19530。所以填写milvus-standalone:19530。 - Username/Password: 单机版默认没有启用身份验证,这两项留空即可。
- Database: 默认数据库名为
default,也留空或填写default。
点击 “Connect”,如果一切正常,几秒钟后你就会进入Attu的主仪表盘。
主界面导览:
- 左侧导航栏:
Overview: 系统总览,显示集合数量、实体总数、内存使用情况等。Collections:核心功能。在这里可以创建、查看、删除集合(Collection),以及进行数据操作。Query: 提供一个类似“命令行”的界面,可以执行类SQL的布尔表达式查询(仅限标量字段过滤)。System: 查看系统性能指标,如QPS、延迟、资源使用率。
- 中间工作区: 根据左侧选择显示相应内容。
我们来快速创建一个集合并插入数据,感受一下流程:
创建集合: 点击左侧
Collections-> 点击右上角Create Collection。Collection Name: 输入test_collection。Description: 可选,输入“测试用集合”。Schema: 定义集合的字段。点击Add Field。- 第一个字段:
Field Name填id,Data Type选Int64,勾选Primary Key和Auto ID(让系统自动生成ID)。 - 第二个字段:
Field Name填embedding,Data Type选FloatVector,Dimension填128(表示这是一个128维的浮点数向量)。 - 第三个字段(标量字段):
Field Name填title,Data Type选VarChar,Max Length填100。
- 第一个字段:
- 点击
Create。成功后,你会在集合列表中看到test_collection。
创建索引: 向量搜索之所以快,全靠索引。点击进入
test_collection-> 切换到Index标签页 -> 点击Create Index。Field Name: 选择embedding。Index Type: 对于浮点向量,常用的有IVF_FLAT(平衡精度与速度)、HNSW(高召回率,内存占用大)。我们选IVF_FLAT。Metric Type: 选择距离度量方式,L2(欧氏距离)或IP(内积)最常见。我们选L2。Params: 对于IVF_FLAT,需要指定nlist参数,它代表聚类中心数。可以先填128。这是一个性能调优参数,数据量越大,这个值可以适当调大。- 点击
Create。创建索引需要一点时间,状态会从InProgress变为Finished。
加载集合: 在Milvus中,只有被“加载”(Load)到内存的集合才能进行搜索。在集合详情页,点击右上角的
Load按钮。加载成功后,按钮会变为Release。插入数据: 切换到
Data标签页 -> 点击Insert。- 由于我们设置了
id字段为Auto ID,这里不需要填写。 - 在
embedding列,你需要输入一个128维的向量。可以手动输入JSON数组,例如[0.1, 0.2, ...](共128个数字)。更简单的方法是点击输入框旁的“随机生成”图标,Attu会帮你生成一个随机向量。 - 在
title列,输入一个字符串,如"First test data"。 - 点击
Insert。你可以在下方的数据表中看到新插入的数据。
- 由于我们设置了
向量搜索: 这是最激动人心的部分。在
Data标签页,找到Search区域。Vectors: 输入一个你想要搜索的128维向量(可以再次随机生成一个)。Metric Type: 选择L2,与索引一致。Limit: 返回最相似的K条结果,填10。- 点击
Search。下方会返回搜索结果,包含匹配的实体ID、距离分数(越小越相似)以及你定义的标量字段(如title)。
至此,你已经完成了从部署到第一次向量搜索的全流程!Attu的界面非常直观,多点点、多试试,很快就能掌握。
5. 部署运维中的常见问题与深度排查
即使按照步骤操作,也可能会遇到问题。这里我总结了一些高频问题和排查思路,帮你快速“排雷”。
5.1 容器启动失败或状态不健康
这是最常见的问题。永远记住,日志是你最好的朋友。
排查步骤:
- 查看所有容器日志:
sudo docker compose logs会显示所有服务的日志混合在一起,信息量大但可能杂乱。建议针对有问题的服务单独查看。 - 查看特定容器日志:例如Milvus服务启动失败,使用
sudo docker compose logs standalone。重点关注最后的ERROR或FATAL信息。 - 常见错误及解决:
- 端口冲突:Milvus的19530、9091端口,或者Attu的8000端口可能被其他程序占用。错误日志中会有
address already in use提示。解决方法:修改docker-compose.yml或docker-compose.attu.yml中ports映射的宿主机端口(如将"8000:3000"改为"8001:3000"),然后重启服务。 - 内存不足:Milvus单机版启动需要一定内存。如果系统内存不足,容器可能被OOM Killer终止。使用
free -h检查内存,确保至少有2-4GB可用空间。可以考虑增加系统交换空间(Swap)。 - 磁盘空间不足:镜像下载和数据持久化需要磁盘空间。使用
df -h检查。 - 镜像拉取失败:网络问题可能导致无法从Docker Hub拉取镜像。可以尝试配置国内镜像加速器(如阿里云、中科大镜像),或者手动
docker pull镜像后再启动。
- 端口冲突:Milvus的19530、9091端口,或者Attu的8000端口可能被其他程序占用。错误日志中会有
5.2 Attu无法连接Milvus
在Attu界面输入地址后连接超时或失败。
排查步骤:
- 确认Milvus服务地址:在Attu的配置中,我们填的是
milvus-standalone:19530。这个地址仅在Docker网络内部有效。如果你是在宿主机(Ubuntu)的浏览器访问Attu,而Attu容器内部通过这个地址去连接,这是正确的。如果Attu部署在其他机器,则需要填写Milvus宿主机的实际IP和映射的19530端口,并确保防火墙放行了该端口。 - 检查网络连通性:进入Attu容器内部执行命令测试。
如果# 进入attu容器 sudo docker exec -it milvus-attu /bin/sh # 在容器内测试网络连通性 nc -zv milvus-standalone 19530 ping milvus-standalonenc不通,说明两个容器不在同一个网络,或者Milvus服务没起来。检查docker-compose.attu.yml中的networks配置是否与主文件一致(都使用default网络)。 - 检查Milvus服务健康度:在宿主机上执行
curl http://localhost:9091/healthz。如果Milvus健康,会返回OK。如果不健康,回去检查Milvus容器的日志。
5.3 数据操作或搜索报错
在Attu中执行插入、搜索时遇到错误。
排查思路:
- “Collection not loaded”错误:执行搜索前,必须确保集合已经“加载”(Load)。在Attu的集合列表或详情页,确认集合状态是
Loaded。 - “Index not built”或参数错误:搜索前必须为向量字段创建索引,且搜索时指定的
Metric Type必须与创建索引时一致。检查索引是否创建成功(状态为Finished)。 - 向量维度不匹配:插入数据时,提供的向量数组长度必须严格等于创建集合时定义的
Dimension(如128)。仔细核对。 - 数据类型不匹配:确保插入的标量字段(如
title)的数据类型(VarChar)和值与定义相符。
5.4 性能调优与生产环境考量
对于学习和测试,默认配置足够。但如果数据量增大,你需要关注以下几点:
- 资源限制:在
docker-compose.yml中,可以为每个服务(如standalone)添加资源限制,防止某个容器吃光所有资源。services: standalone: ... deploy: resources: limits: cpus: '2.0' memory: 4G reservations: memory: 2G - 数据持久化:默认配置下,MinIO(存储数据)和Etcd(存储元数据)的数据都保存在容器内部。如果容器被删除,数据会丢失。在生产环境,你应该将容器内的数据目录通过
volumes映射到宿主机的持久化目录。仔细查看docker-compose.yml中的volumes配置部分,确保路径正确映射。 - 版本管理:记录下你使用的Milvus和Attu镜像版本(如
v2.4.0)。升级时,务必先查看官方Release Notes,了解不兼容的变更,并在测试环境充分验证。 - 备份与恢复:Milvus提供了
milvus-backup工具,用于定期备份集合数据。对于重要数据,制定备份策略是必须的。
6. 进阶配置与日常维护技巧
部署稳定运行后,还有一些实用的进阶操作和日常维护命令,能让你的体验更顺畅。
6.1 服务启停与清理
- 停止所有服务:在项目目录下,运行
sudo docker compose down。这会停止并移除所有容器,但默认不会移除数据卷,你的数据还在。 - 停止并彻底清理(删除数据卷):如果你想重新开始,清除所有数据,使用
sudo docker compose down -v。警告:此操作不可逆,所有数据丢失! - 重新启动服务:
sudo docker compose up -d。 - 查看实时日志:
sudo docker compose logs -f standalone(-f参数可以持续跟踪日志输出,类似tail -f)。 - 进入容器内部调试:例如,想查看MinIO里存了什么文件,可以
sudo docker exec -it milvus-minio /bin/sh,然后使用mc(MinIO Client) 命令。
6.2 修改配置与持久化
Milvus的配置主要通过环境变量和配置文件传递。在docker-compose.yml的standalone服务下,你可以看到environment和volumes部分。
- 常见可调参数:
QUOTA_ENABLED: 是否启用资源配额,生产环境建议开启。- 各种缓存大小(如
CACHE_SIZE):根据你的数据量和内存调整。
- 如何修改:直接在
docker-compose.yml的environment下添加或修改对应的环境变量,然后执行sudo docker compose up -d重启服务。Docker Compose会智能地重新创建有变化的容器。
关于数据持久化的最佳实践: 强烈建议将以下关键路径映射到宿主机,并在宿主机定期备份这些目录:
- Milvus数据文件:通过MinIO容器映射的卷(查看
volumes中minio服务的配置)。 - Milvus元数据:通过Etcd容器映射的卷(查看
volumes中etcd服务的配置)。 - Milvus日志:在
standalone服务中,可以添加卷映射将/var/lib/milvus/logs映射出来,方便查看日志。
6.3 监控与告警
对于生产环境,监控必不可少。除了Attu自带的简单监控面板,你可以:
- 使用Prometheus + Grafana:Milvus原生暴露Prometheus格式的指标(在
9091端口)。你可以部署一套Prometheus采集这些指标,并用Grafana制作丰富的监控看板。官方提供了Grafana仪表板模板。 - 日志收集:将Docker容器的日志收集到ELK(Elasticsearch, Logstash, Kibana)或Loki等日志系统中,便于集中查询和分析。
整个部署和初步使用的流程就是这样。从环境准备到可视化操作,再到问题排查和进阶维护,我希望这份指南能帮你绕过我当年踩过的那些坑。记住,遇到问题多查日志,善用docker compose logs和docker exec这两个利器。向量数据库的世界很大,Milvus只是一个开始,但有了这个稳定可靠的本地环境,你就可以尽情探索以图搜图、语义搜索、推荐系统等更多有趣的应用了。