目录
架构

- 观察下上面的整体架构图,整体遵循数据平面和控制平面分解的原则,由访问代理层、维护集群拓扑和任务调度的协调器、存算分离的工作节点、存储这四个层组成。
- 访问层。由一组无状态代理组成(nginx、k8s ingress、nodePort和LVS等负载组件提供统一的服务地址),是系统的前端层,也是用户的终端,它验证客户端请求并减少返回结果(采用大规模并行处理[mpp]架构,代理对中间结果进行聚合和后处理,然后再将最终结果返回给客户端)
- 协调器。是Milvus的大脑。在任何时刻,整个集群都有一个协调器在工作,负责维护集群拓扑结构,调度所有任务类型并保证集群级一致性
- 工作节点。由于存算分离,工作节点是无状态的,包括流节点、查询节点和数据节点
- 存储。负责数据持久化,包括元存储、日志代理和对象存储
- 左侧是客户端的各种
sdk(go, python等),当执行搜索操作的时候,会进行下面的步骤
- 客户端的请求通过SDK/Restful API发送搜索请求
- 负载均衡器将请求路由到访问层的可用代理
- 代理使用路由缓存确定目标节点,只有缓存不可用的时候才联系协调器
- 代理将请求转发到适当的流节点,然后与查询节点协调进行密封数据搜索,同时在本地执行增长数据搜索
- 查询节点根据需要从对象存储中加载密封分段,并执行分段级搜索
- 对搜索结果进行多级缩减:查询节点还原多个分段的结果,流节点还原查询节点的结果,代理还原所有流节点的结果,然后返回客户端
- 当执行数据插入的时候,会执行下面的步骤
- 客户端发送带有向量数据的插入请求
- 访问层验证请求并转发给流节点
- 流节点将操作符记录到WAL存储,以确保持久性
- 实时处理数据并提供查询
- 当分段达到容量时,流节点触发转换为密封分段
- 数据节点处理压缩,并在密封分段上建立索引,讲解过存储在对象存储中
- 查询节点加载新建索引并替换相应的增长数据
容器化部署
目前docker.io被禁了,其他的几个知名源也不太好获取镜像,导致国内获取镜像困难,可以用下面这个平台,它提供了一些相关镜像的获取地址
https://docker.aityp.com/image/docker.io/milvusdb/milvus:v2.5.5
- 下面是一个使用podman部署(换成docker也行)镜像到本地的脚本。可以使用
./start-milvus.sh up来部署,./start-milvus.sh down来清理资源
sh
#!/bin/bash
# -----------------------------------------------------------------------------
# Milvus 一键 Docker 启动脚本
# 默认使用 standalone 模式(嵌入式 etcd + MinIO),开发/测试够用
# 使用前确保已安装 Docker & Docker Compose
# -----------------------------------------------------------------------------
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
COMPOSE_FILE="${SCRIPT_DIR}/docker-compose.milvus.yml"
MILVUS_VERSION=${MILVUS_VERSION:-"v2.5.5"} # 2.5 系列最新稳定版
NETWORK_NAME="milvus-net"
CONTAINER_NAME="milvus-standalone"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
# 检查 Podman 环境
check_env() {
if ! command -v podman &> /dev/null; then
log_error "Podman 未安装,请先安装 Podman"
exit 1
fi
if command -v podman-compose &> /dev/null; then
COMPOSE_CMD="podman-compose"
else
log_warn "podman-compose 未找到,将尝试使用 podman compose 子命令"
COMPOSE_CMD="podman compose"
fi
}
# 生成 compose 文件(带代理透传与重试)
gen_compose() {
log_info "生成 compose 文件:${COMPOSE_FILE}"
# 若宿主机配置了代理,透传给 compose
export PODMAN_USERNS=keep-id
[ -n "${http_proxy:-}" ] && export PODMAN_ENV_HTTP_PROXY="${http_proxy}"
[ -n "${https_proxy:-}" ] && export PODMAN_ENV_HTTPS_PROXY="${https_proxy}"
[ -n "${no_proxy:-}" ] && export PODMAN_ENV_NO_PROXY="${no_proxy}"
cat > "${COMPOSE_FILE}" <<EOF
version: '3.5'
services:
etcd:
container_name: milvus-etcd
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/etcd:3.6.5-0-linuxarm64
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
- ETCD_SNAPSHOT_COUNT=50000
volumes:
- ${SCRIPT_DIR}/volumes/etcd:/etcd
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls=http://0.0.0.0:2379 -data-dir=/etcd
minio:
container_name: milvus-minio
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/minio/minio:RELEASE.2025-07-23T15-54-02Z-linuxarm64
environment:
MINIO_ROOT_USER: minioadmin
MINIO_ROOT_PASSWORD: minioadmin
volumes:
- ${SCRIPT_DIR}/volumes/minio:/minio_data
command: minio server /minio_data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
standalone:
container_name: ${CONTAINER_NAME}
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/milvusdb/milvus:v2.5.5-linuxarm64
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
volumes:
- ${SCRIPT_DIR}/volumes/milvus:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- etcd
- minio
restart: unless-stopped
networks:
default:
name: ${NETWORK_NAME}
EOF
}
# 启动容器(带重试)
start_milvus() {
log_info "正在启动 Milvus(版本:${MILVUS_VERSION})..."
local attempt=1
while ! ${COMPOSE_CMD} -f "${COMPOSE_FILE}" up -d; do
if [ $attempt -ge 3 ]; then
log_error "连续 3 次拉取/启动失败,请检查:"
log_error " 1. 宿主机能否解析 auth.docker.io"
log_error " 2. 是否需要配置代理:export https_proxy=http://ip:port"
log_error " 3. 执行:podman system reset -f (谨慎)"
exit 1
fi
log_warn "第 $attempt 次启动失败,5 秒后重试..."
sleep 5
((attempt++))
done
log_info "等待 Milvus 初始化(约 10 秒)..."
sleep 10
if ${COMPOSE_CMD} -f "${COMPOSE_FILE}" ps | grep -q "Up.*healthy"; then
log_info "✅ Milvus standalone 已就绪!"
log_info " gRPC 端口:19530"
log_info " Web UI :http://localhost:9091"
else
log_warn "容器状态未 healthy,可手动检查:podman logs ${CONTAINER_NAME}"
fi
}
# 停止并清理
stop_milvus() {
log_info "正在停止 Milvus..."
${COMPOSE_CMD} -f "${COMPOSE_FILE}" down -v --remove-orphans
log_info "已停止并清理卷(如需保留数据请去掉 -v)"
}
# 主流程
main() {
check_env
case "${1:-up}" in
up|start)
gen_compose
start_milvus
;;
down|stop)
stop_milvus
;;
restart)
stop_milvus
sleep 2
gen_compose
start_milvus
;;
*)
echo "Usage: $0 {up|down|restart}"
echo " up - 启动 Milvus(默认)"
echo " down - 停止并清理"
echo " restart - 重启"
exit 1
;;
esac
}
main "$@"
- 查看当前容器列表,观察这几个服务都正常即可
