---
title: "Milvus 向量数据库快速入门（人话版）"
description: "Milvus 到底是干嘛的？它是“给向量找对象”的超高速数据库——存向量、比相似、返回前 K 名。"
date: 2025-06-01T04:03:27Z
canonical: https://xiaobox.github.io/p/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/
author: 小盒子
categories: ["数据库"]
tags: ["Python", "Milvus", "Docker", "LLM", "RAG", "LangChain", "Embedding", "多线程"]
source: https://mp.weixin.qq.com/s/lMMO4P7ujbc4JRky3PqQqg
license: CC BY-NC-SA 4.0
license_url: https://creativecommons.org/licenses/by-nc-sa/4.0/
---

# Milvus 向量数据库快速入门（人话版）

## Milvus 到底是干嘛的？

它是“给向量找对象”的超高速数据库——存向量、比相似、返回前 K 名。

Milvus 就是给「向量」找对象的数据库——它能帮你把一堆高维向量存好、管好、飞快地按“相似度”把最像的几条挑出来。

1.  和普通数据库比，Milvus天生会“模糊配对”，不是 exact match 而是“谁更像”。
2.  内核走的是“先分桶/建图，再局部暴力”，所以大规模也能搜得飞快。
3.  2.x 版本把「数据落盘」「分布式容灾」都外包给 RocksDB + MinIO + etcd——省了你很多心。

## 先认几个关键词

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/001-c2fdff5a.png)

## 部署使用

五步跑通「单机体验」+ 三步升级「小集群」

### 单机 5 步

1.  拉镜像 docker run milvusdb/milvus:v2.4.3
2.  建楼 create\_collection()——确定字段维度、主键、向量字段。
3.  搬人 insert() → flush()。
4.  装电梯 create\_index()；小数据直接 FLAT，大数据先 IVF，再视情况换 HNSW。
5.  开门找人 load() → search()/query()；用完可 release().

### 变成 3 节点小集群

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/002-c0911d8c.png)

## 最常用的 5 步操作

1.  建楼：create collection，把字段都定义好
2.  搬人：insert，把向量和元信息塞进去；记得 flush() 真正落盘
3.  装电梯：create index，选对索引类型，未来搜索才快
4.  请保安开门：load，没 load 就像门锁着，啥也搜不到
5.  找人：search（可加条件 expr），或者只按字段 query

## 索引怎么挑？

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/003-0a75133a.png)

## 索引调优口诀

1.  小样本先 FLAT 做 baseline——它慢但最准，方便肉眼看 Recall。
2.  百 万级优先 IVF\_FLAT：调 nlist=√N 起步；提高 nprobe 越准越慢。
3.  千万级冲 HNSW：关键参 M (边数) 和 efConstruction (建图宽度)，调高两倍能大幅增 Recall。
4.  超高并发记得“机＋内存”一起扩——索引放内存，多副本才分摊 QPS。

## 别踩这些坑 💡

1.  向量维度要统一：128 就全 128，别混着来。
2.  插完别忘 flush：不 flush 就像东西放购物车没结账，搜索不到。
3.  没 load 就搜索：会报错，先 load()。
4.  内存不够全加载：用 Partition，分批 load()。
5.  精度不满意：调 nprobe（IVF）或换 HNSW 试试。

### 十大踩坑 + 急救方案

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/004-d5e81d65.png)

## 再进阶一点点

-   Hybrid Search：边比向量相似度，边过滤价格 < 500 这种条件，SQL 味道更浓。
-   一致性模式：默认够用；真要跨机房强一致性就选 Strong。
-   持久化：Milvus 本身用 RocksDB ＋ MinIO 存数据，你不用操心怎么落盘。
-   与 RAG 的关系：大模型把文本→向量，Milvus 负责“最近邻检索”，再把查到的文档喂回模型。

## 跟其它工具怎么配？

-   LangChain / LlamaIndex：把 Milvus VectorStore 接进去即可，RAG 极速上线。
-   Spark / Flink：批量离线写入 Milvus；确保分批 1 万条以内避免 RPC 超时。
-   Airflow：定时 ETL → Embedding → Milvus；flush、compact 都能写成 task。

## “到底需要多大机器？”——粗算公式

-   内存 ≈ （向量维度 × 4 bytes × 向量条数 × 1.4 倍索引系数）﹢ 元数据大小

-   例：1 亿条 768 维 → 768×4×1e8×1.4 ≈ 430 GB（得至少 512 GB 机器，或分区加载）。

-   硬盘 ≈ 内存 × 1.2（索引 + RocksDB + 日志）。

512G 内存看起来有点儿夸张，所以如果内存吃紧，可以参考以下方法进行优化：

![Image](https://pub-f29bf2b53160470c9a85250116509a24.r2.dev/post/2025-06-01-milvus-xiang-liang-shu-ju-ku-kuai-su-ru-men-ren-hua-ban/005-35ceb743.png)

## Python 端到端 Demo （含增删改查）

```python
from pymilvus import connections, Collection, utility, DataType, FieldSchema, CollectionSchema
import numpy as np

connections.connect(host="localhost", port="19530")

# 1. 建楼（如果已存在就删掉重建）
if utility.has_collection("demo"): utility.drop_collection("demo")

schema = CollectionSchema([
    FieldSchema("id", DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema("title", DataType.VARCHAR, max_length=200),
    FieldSchema("price", DataType.FLOAT),
    FieldSchema("emb", DataType.FLOAT_VECTOR, dim=128)
])
col = Collection("demo", schema)

# 2. 插 10 条数据
titles = [f"商品{i}"for i in range(10)]
prices = [i * 10.0for i in range(10)]
vecs   = np.random.random((10, 128)).tolist()
col.insert([titles, prices, vecs]); col.flush()

# 3. 建 IVF 索引 & 加载
col.create_index("emb", {"index_type":"IVF_FLAT","metric_type":"L2","params":{"nlist":64}})
col.load()

# 4. 搜索 + 过滤价格 < 50
qv = [np.random.random(128).tolist()]
hits = col.search(qv, "emb", {"metric_type":"L2","params":{"nprobe":8}}, limit=5, expr="price < 50")
print([(h.entity.get('title'), h.distance) for h in hits[0]])

# 5. 删除一条，再查
del_id = hits[0][0].id
col.delete(f"id in [{del_id}]"); col.flush()

```

