ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows 10上通过Docker部署Milvus向量数据库完整指南

Windows 10上通过Docker部署Milvus向量数据库完整指南 作为常年折腾开发环境的过来人我越来越觉得向量数据库这块东西早晚是躲不掉的。不管是做RAG、语义搜索还是AI Agent的记忆管理你总得有个地方把文本、图片转出来的embedding向量存起来还得能按相似度快速捞回来。而在这么多向量数据库里面Milvus算是社区活跃度和工程成熟度都挺高的一款。问题在于很多人在Windows 10上想装Milvus时第一反应是去GitHub上看官方文档结果发现官方推荐的部署方式要么是Linux服务器、要么是K8s集群本地Windows直接装那叫一个费劲。其实Milvus官方早就准备好了一套Docker镜像你只要在Windows 10上把Docker环境跑起来用docker-compose拉起一套Standalone模式的Milvus也就是几分钟的事。这篇东西把我自己从Windows 10上装Docker到Milvus跑起来能存数据能查相似度的完整实操过程写清楚包括所有会踩的坑、必须做的配置和验证方法照着做一遍基本都能跑通。1. 为什么选Windows 10 Docker这条路方案选型背后的逻辑先掰扯一下为什么非要用Docker跑Milvus而不是直接在Windows 10上装个原生版。Milvus的架构不是单体应用它的核心组件包括存储元数据的etcd、负责数据持久化的对象存储MinIO以及真正干向量检索活的查询节点和索引节点。你在一台Windows机器上把这些组件全部手动装一遍光依赖关系就够你喝一壶的。算下来等你在Windows上把这些组件手动配明白我这边Docker环境可能都装完两遍了。1.1 Milvus到底是个什么东西向量数据库的核心定位很多第一次接触Milvus的朋友会懵这不就是个数据库吗跟MySQL能差多少差太远了。传统数据库处理的是精确匹配和范围查询比如找出年龄大于18岁的用户。但向量数据库处理的是相似度检索比如给我找出和这段文本语义最相近的10条记录它背后是向量之间距离计算像余弦相似度、欧氏距离这类算法。Milvus的典型使用场景包括图片以图搜图、文本语义检索、推荐系统的物品召回、AI对话中的知识库检索。举个例子你做一个客服机器人把历史工单全部转成向量存进Milvus用户问我的订单怎么还没发货系统先把这句话转成向量然后去Milvus里搜最相似的几条历史工单再把这些上下文丢给大模型去组织回答。没有向量数据库这一步要么慢得离谱要么就做不了。1.2 Standalone模式vs分布式模式个人开发选哪个Milvus官方提供了两种部署模式Standalone和Cluster。Standalone模式就是所有组件在一台机器上跑适合数据量在百万级以内、单机开发测试的场景。Cluster模式则是多个节点分布式部署适合海量数据和生产环境。咱们在Windows 10上用Docker跑选择的当然是Standalone模式。官方在GitHub上给出了现成的docker-compose.yml文件里面定义了etcd、minio和standalone三个服务。这里的standalone服务其实是个单机版的Milvus核心进程它内部通过嵌入的方式使用etcd和MinIO的连接信息而不需要你自己再去单独部署完整的etcd集群和MinIO集群。理解了这个逻辑你就知道为什么docker-compose启动之后会出现三个容器了。2. Docker Desktop安装全流程先把Windows 10的容器环境铺好Windows 10上装Docker正路是装Docker Desktop。有些教程为了省事让你用Docker Toolbox那是老掉牙的VirtualBox方案性能差且容易出幺蛾子直接跳过。Docker Desktop在Windows 10上用的是WSL2或Hyper-V作为后端我强烈建议走WSL2路线原因后面会讲。2.1 安装WSL2最容易翻车的前置步骤Docker Desktop在Windows 10上正常工作前置条件是系统支持虚拟化并且在BIOS中打开了对应开关。很多人的Docker Desktop启动时报virtualization support wasnt detected或者Docker Desktop failed to start because virtualisation support wasnt detected十有八九就是CPU虚拟化没开或者开错了地方。第一步先把虚拟化状态摸清楚。你可以打开任务管理器切到性能标签页看看底部有没有虚拟化: 已启用的标识。如果没有就得进BIOS一般是开机时按Del或F2找Intel Virtualization Technology或AMD SVM Mode的选项把它设为Enabled。这一步很多人容易忽视因为Windows本身跑得好好的不代表虚拟化就开着。确认虚拟化没问题后以管理员权限打开PowerShell执行以下命令启用WSL功能dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完这两条之后必须重启系统。重启完再执行wsl --set-default-version 2如果提示需要下载WSL内核就按提示操作或者直接用wsl --update然后你可以装一个Ubuntu发行版。其实Docker Desktop对WSL发行版本身的依赖不强但有个Ubuntu在里面后面如果你想直接在WSL里操作Docker命令会方便很多。安装方式很简单Microsoft Store里搜Ubuntu点安装就行。安装完首次启动会让你设置Linux用户名和密码走一遍就行。2.2 下载和安装Docker Desktop版本与安装选项的选择WSL2和虚拟化这两个地基打好之后去Docker官网下载Docker Desktop Installer.exe。下载页面会自动识别你的系统版本Win10一般对应x86_64版本。安装时一路Next即可但到Use WSL 2 instead of Hyper-V这一步一定要勾选。安装完成之后先别急着启动去设置里找到Resources → WSL Integration确保你要用的WSL发行版开关是打开的。然后在Windows Terminal里输入docker --version如果能看到版本号就说明Docker命令已经在PATH里生效了。再运行docker run hello-world这一步会从Docker Hub拉一个最小测试镜像并运行如果输出一堆Hello from Docker!的信息说明整个链路是通的。2.3 镜像加速配置国内网络环境的必经之路这是我在实机部署中遇到的第一个大坑。Docker Hub在国内的访问速度说多了都是泪拉一个几百MB的镜像经常会卡到超时。Milvus相关的几个镜像加起来有好几个GB如果不配加速器光拉镜像就能耗掉你半天的耐心。打开Docker Desktop的设置切到Docker Engine标签页找到配置文件中的registry-mirrors字段。按照如下格式填上可用的国内镜像源地址{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ] }填完点击Apply Restart让Docker Desktop重启生效。配置完之后可以用docker info命令验证一下输出信息里能看到Registry Mirrors部分列出了你填的地址那就算配好了。3. 拉取Milvus镜像之前理解etcd、MinIO和Standalone的容器分工很多人看到docker-compose.yml里一口气定义了etcd、minio和standalone三个服务心里就发怵觉得这是不是要把一个分布式集群跑在笔记本上。其实没那么吓人这三个容器在Standalone模式下各有各的分工配合关系很清晰。3.1 为什么需要etcd和MinIOMilvus的数据分层机制Milvus的存储设计是元数据与数据分离。etcd负责存元数据比如你创建了哪些collection、某个segment里有几条记录、索引的配置信息是什么。这种元数据的特点是量小、变化频繁、需要强一致性和高可用etcd本身就是为这种场景设计的分布式一致性键值存储。MinIO则负责存真正的数据文件包括向量数据文件、索引文件和删除日志。它提供的是S3兼容的对象存储接口Milvus通过这个接口读写数据文件。你可能要问为什么不在Milvus里直接读写本地文件系统呢原因在于Milvus从设计上就是要支持分布式部署的多个查询节点需要共享同一份数据文件所以它从一开始就把存储抽象成对象存储接口Standalone模式下用MinIO只是本地模拟这个抽象层。3.2 standalone容器之间到底谁依赖谁docker-compose的启动顺序它们的启动顺序是有讲究的。Milvus启动时要连etcd和MinIO如果这两个依赖还没就绪Milvus会连接失败。docker-compose提供了depends_on和healthcheck机制来解决这个问题。实际执行中你会发现即便你定义了depends_ondocker-compose默认也只会等容器启动而不是等容器内的服务真正可用。所以官方那个docker-compose.yml里为MinIO和etcd都加了healthcheck然后让standalone的depends_on以condition: service_healthy为准。这就保证了等Milvus容器启动时etcd和MinIO已经就绪了。理解这一层你就能明白为什么有时候直接docker run一个milvus镜像会报连接etcd超时的错误——因为没人帮你去等依赖就绪。用官方的docker-compose文件这些依赖关系都已经编排好了。4. Milvus Standalone模式实战部署从配置文件编写到容器跑通Docker环境搞定、镜像加速配好、依赖关系心里有数了现在开始正式部署Milvus。4.1 获取官方docker-compose文件并拉取镜像打开一个PowerShell窗口先建一个专门的工作目录比如mkdir D:\milvus-deploy cd D:\milvus-deploy然后从Milvus官方GitHub仓库把Standalone模式的compose文件下载下来。可以右键另存也可以用Invoke-WebRequestInvoke-WebRequest -Uri https://github.com/milvus-io/milvus/releases/download/v2.4.1/milvus-standalone-docker-compose.yml -OutFile docker-compose.yml注意这里我选的是v2.4.1的版本号你可以去Milvus的release页面看最新版本号替换到URL里就行。下载完成后打开这个YAML文件看一眼你会看到三个serviceetcd、minio、standalone以及它们各自的image地址。接下来做一步操作把镜像拉下来docker compose pull这一步会把etcd、minio和milvus的镜像一并拉取到本地。有了镜像加速配置这一步应该不会太痛苦。拉取期间你可以盯着终端看进度如果某个镜像反复超时多半是镜像源配置没生效回头再检查一下Registry Mirrors。4.2 启动Milvus并验证容器状态镜像拉取完成后直接执行docker compose up -d-d参数表示后台运行。第一次启动时Docker会创建默认的milvus网络并按compose文件里的配置启动容器。执行完后用docker compose ps查看状态正常情况下你会看到三个服务全部是running状态。之前有朋友跟我说他执行完docker compose up -d之后只看到两个容器起来了standalone容器过几秒就退出了。这种情况多半是etcd或MinIO还没就绪standalone启动时连接不上就直接放弃了。官方compose文件里已经做了健康检查如果你用的是最新版还没解决可以手动执行docker logs milvus-standalone看看输出日志里报的什么错。最常见的错误是连接etcd超时。这时候我建议先手动等十几秒再执行一次docker compose up -d让compose补充启动失败的服务。如果反复失败检查一下是不是端口被占用了Milvus默认用19530端口MinIO用9000和9001端口etcd用2379端口。4.3 容器都起来了不代表成功端口连通性测试容器状态是running但你的宿主机能不能访问到这是另一回事。Milvus的客户端要通过19530端口跟服务端通信所以在正式使用之前先用命令行验证一下端口通不通Test-NetConnection -ComputerName localhost -Port 19530如果返回的TcpTestSucceeded是True说明Milvus服务已经在192.168.x.x上监听了。如果你想在浏览器里看MinIO的管理界面可以访问http://localhost:9001登录账号和密码在compose文件里有定义默认是minioadmin/minioadmin。这个界面通常不需要你操作但能看到它打开说明整个对象存储链路是通的。到这里Milvus服务端就算部署完成了。5. 第一次写数据pymilvus连接Milvus并完成向量入库与检索服务端跑起来只是第一步真正让人安心的是把数据写进去再查出来。这一步我推荐直接用Python的pymilvus库因为Milvus官方对Python支持做得最完善而且你在做AI应用时十有八九也要用Python。5.1 环境准备与连接Milvus在Windows 10上装pymilvus很简单pip install pymilvus装完之后打开Python交互式环境或写一个.py脚本先建立连接from pymilvus import connections connections.connect(hostlocalhost, port19530)如果连接成功你没有看到任何报错。然后可以进一步确认服务端版本from pymilvus import utility print(utility.get_server_version())能打印出版本号比如2.4.1那就说明Python客户端和Milvus服务端的通信完全正常。5.2 创建Collection并插入带向量的数据Milvus里存储数据的基本单元是Collection你可以把它类比成MySQL里的表。但Collection的字段定义核心是向量的维度你必须提前知道你的embedding模型输出多少维。比如你用OpenAI的text-embedding-ada-002输出是1536维用一些开源的中文embedding模型常见是768维或1024维。这里我以8维为例演示逻辑from pymilvus import FieldSchema, CollectionSchema, DataType, Collection fields [ FieldSchema(nameid, dtypeDataType.INT64, is_primaryTrue, auto_idFalse), FieldSchema(nametext, dtypeDataType.VARCHAR, max_length500), FieldSchema(nameembedding, dtypeDataType.FLOAT_VECTOR, dim8) ] schema CollectionSchema(fieldsfields, descriptiondemo collection) collection Collection(namedemo_collection, schemaschema)这段代码创建了一个名为demo_collection的Collection它有三列id是主键text是原始文本embedding是8维浮点向量。Collection名重复创建会报错如果测试时需要重建可以用collection.drop()先删掉。插入数据的时候你得把文本对应的向量一起给进去。这里演示两条假数据import random data [ [1, 2], [今天天气真不错, 这家餐厅的菜很好吃], [[random.random() for _ in range(8)], [random.random() for _ in range(8)]] ] collection.insert(data)insert之后你可以用collection.num_entities查看当前数据量。注意刚插入的数据在未flush之前是存在于内存的调用flush之后才落盘collection.flush()5.3 创建索引并执行相似度检索Milvus的检索性能主要靠索引。不建索引也能做暴力搜索但数据量一大就废了。创建索引用以下方式index_params { metric_type: COSINE, index_type: IVF_FLAT, params: {nlist: 128} } collection.create_index(field_nameembedding, index_paramsindex_params)这里有个选择需要注意metric_type决定了向量之间距离怎么算。做语义搜索时我一般用COSINE余弦相似度语义越相近余弦值越接近1。index_type的IVF_FLAT是比较基础的索引类型适合入门和数据量不大时使用。如果你追求更高性能之后可以换成HNSW或IVF_SQ8。检索前需要先load把Collection加载到内存中collection.load()然后拿一条新的向量比如你的新用户输入转成的embedding去做搜索search_params { metric_type: COSINE, params: {nlist: 128} } results collection.search( data[[random.random() for _ in range(8)]], anns_fieldembedding, paramsearch_params, limit2, output_fields[text] ) for hit in results[0]: print(f命中ID: {hit.id}, 相似度: {hit.distance}, 文本: {hit.entity.get(text)})执行完你会看到Milvus返回了和查询向量最相似的两条记录同时带上了原始的text字段内容。这一步跑通就说明整个Milvus链路从存储到检索已经完整可用了。5.4 关于相似度的几个易混概念Milvus里的COSINE距离返回值越大表示相似度越高范围在-1到1之间。而欧氏距离L2是越小越相似这两种metric在查看结果时判读逻辑完全相反经常有人搞混。举个例子我拿今天心情很差这句话和库里今天天气真不错去算余弦值大概在0.3到0.5之间偏中性。但如果搜的是明天会下雨吗库里有明天下雨的概率大那余弦值就会到0.8以上。这也是Milvus在语义检索场景里表现不错的原因它捕捉到的是语义层面的相似而不是字面重复。6. Windows 10环境下Docker与Milvus的日常运维经验与排错Milvus跑起来不难难的是在Windows 10这种非原生Linux环境下出了状况能快速定位问题。这里把我在实际使用中反复踩过的坑和积累的习惯写下来每一个都是真金白银换来的经验。6.1 Docker Desktop资源占用与性能调优Milvus的standalone容器在接收大批量数据写入时内存占用会明显上升。如果感觉整个系统变卡去Docker Desktop的Settings → Resources里看默认情况下WSL2的内存上限可能是根据宿主机自动分配的。我建议手动设置上限比如8GB同时确认CPU分配不低于4核这样Milvus在构建索引时不会卡到假死状态。还有一个一看就懂的指标docker stats命令可以实时查看各容器的CPU和内存占用docker stats如果你发现minio容器内存吃掉几个GB这通常是正常的因为MinIO有缓存机制。但如果你发现standalone容器内存吃到包装不下就检查一下是不是检索操作太多或者collection没调优。6.2 常见错误与对应处理方案我整理了Windows 10上最容易碰到的几类问题前面没展开细说的在这里集中给出排查思路。第一个是Docker Desktop启动时报virtualization相关错误。这个前面已经提过根源是BIOS虚拟化开关或Hyper-V功能没启用。有些人的主机是AMD CPU就必须找SVM Mode选项。确认方法是在PowerShell里执行systeminfo看一下Hyper-V要求的四项是不是全部显示已启用有一项为否就说明虚拟化环境缺失。第二个是docker compose pull时卡在某个镜像一直不动。这个问题多数是网络原因对策是检查registry-mirrors配置是否生效也可以临时给Docker Desktop设置一个HTTP代理。另外不要一次性拉所有镜像可以单条执行docker pull milvusdb/milvus:xxx单独排查。第三个是Milvus容器运行后pymilvus连接提示超时。这种情况下先测宿主机到容器映射端口的连通性用Test-NetConnection然后再看容器内进程是否真的在监听19530。可以用docker exec -it milvus-standalone bash进容器命令行执行netstat -tlnp | grep 19530检查。如果端口没监听多半是etcd或MinIO的问题回头查这两个容器的日志。第四个是Windows重启之后docker compose的容器没有自动重启导致Milvus连不上。这个需要在docker-compose.yml里给各服务加上restart: unless-stopped的配置。如果已经在运行可以通过docker update命令补上docker update --restart unless-stopped milvus-standalone docker update --restart unless-stopped milvus-etcd docker update --restart unless-stopped milvus-minio6.3 数据持久化与备份千万别小看Volume映射很多人在Windows上跑Docker部署的数据库时有一个致命误区以为容器一直在跑数据就一直在。其实容器一旦被docker compose down命令删掉你写在容器可写层里的所有数据都会丢。Milvus官方compose文件里其实已经写好了volume映射把etcd的数据、MinIO的数据都映射到宿主机的一个命名卷里。你自己做备份时一种做法是直接备份Docker卷目录。在Windows上这些卷文件在\\wsl$\docker-desktop-data\data\docker\volumes路径下但直接操作这个目录不太方便。另一种做法是用docker命令导出比如在容器运行时把MinIO里的数据目录打成tar包docker exec milvus-minio tar -cvf /tmp/minio-data.tar /minio docker cp milvus-minio:/tmp/minio-data.tar D:\milvus-backup\备份频率就看你对数据的要求了。开发阶段我建议做完一次完整的入库和索引构建之后就导出一次避免重新向量化原始数据和重建索引的重复劳动。6.4 Docker Desktop版本升级带来的兼容性问题Docker Desktop是会自己更新的但新版不一定和已有容器完美兼容。有次我升级到某个新版本后发现Milvus容器启动变慢查询延迟变高查来查去发现问题出在容器网络驱动上。后来我直接把docker-compose down清掉旧容器再up -d重新创建容器问题就解决了。所以给个实诚建议如果Milvus跑得好好的别手贱去升级Docker Desktop。真要升级在升级之前先记录一下当前的docker-compose内容和Milvus版本升级出问题后能快速回滚到旧状态。7. 最后补充把Milvus嵌入到你的实际项目中当Milvus部署好、能用pymilvus完成数据的增删改查之后你可以把它当作一个标准服务接入自己的应用代码。很多人在这一步容易忽略一件事embedding模型的选择和向量维度规划。如果你的数据将来要不断追加那么一开始选的embedding模型最好固定下来因为不同模型输出的向量分布不一样半路换模型会导致旧数据和新数据的相似度计算失去意义。我自己踩过的一个实际教训是最初图省事用了一个快速的中文embedding模型768维数据和索引都建好了。后来想换成更高质量的另一款模型也是768维但向量空间已经变了结果线上查询的效果比原来还差。所以第一批数据入库前一定要想清楚embedding方案这个决策之后付出的迁移成本都不低。再一个切身感觉是Milvus适合存的是已经向量化之后的特征数据不要把原始大文本全丢进去。text字段虽然可以存最长到几MB的VARCHAR但检索时如果返回大量长文本网络和内存压力都会增大。更合理的做法是Milvus里存ID、向量、还有简短索引或摘要原始文档仍在你自己的业务库里查询时用ID去关联合并。这个架构在观察AI应用的最佳实践中是很常见的。最后再分享一个小技巧调试的时候不要总往本机写大批量数据先用小数据集把链路跑通确认相似度结果符合预期再全量灌入。毕竟在Windows的Docker环境里重建索引比在Linux服务器上慢不少耐心做完这些你会发现Milvus已经成了你手边趁手的工具了。
返回列表