向量数据库入坑:入门向量数据库 Milvus 的 Docker 工具镜像

在之前的文章中,我们聊过了一些和 Faiss 相关的事情,包括如何将数据转换为向量、如何挑选索引类型、如何简单加速向量检索性能、以及如何实现简单的语义搜索功能。也曾提到会聊聊更多实际场景中向量数据库的用法,揭开所谓大厂里的核心服务的神秘面纱,比如:实现简单的搜索引擎、推荐系统、风控系统等等。

为了大家都能简单的上手,我做了一个 210MB 的 Docker 镜像,本篇文章就来讲讲这个镜像如何使用,以及我是如何制作这个镜像的。

写在前面

因为这个工具基于 Docker,所以我们需要先完成 Docker 运行环境的安装,如果你的本地环境中已经安装了 Docker,那么可以跳过这个小节,阅读后面的内容。

如果你是桌面运行环境,可以访问官网下载安装文件,如果你使用的是服务端环境,可以参考这篇文章中的“更简单的 Docker 安装”,来完成 Docker 环境的准备。

两步上手

这个镜像的使用方法比较简单,就两步。

我们先使用一条简单的命令,启动一个本地的 Milvus 服务容器,并给它起个名字叫做“milvus”:

docker run --rm -it --name=milvus soulteary/milvus:embed-2.1.0

在容器启动后,大概 1~2秒钟,我们将看到一条日志输出,告诉我们服务启动好了,就可以开始“第二步”啦。

---Milvus Proxy successfully initialized and ready to serve!---

在服务启动之后,我们就可以随心所欲的来上手体验了。

比如,我们可以打开一个新的“命令行终端窗口”,让我们刚刚起名为“milvus”的容器来运行下 Milvus SDK 中类似 “MySQL CRUD” 操作的 “Hello World”:

docker exec -it milvus python hello-world.py

我们将会得到类似下面的结果:

=== start connecting to Milvus     ===

Does collection hello_milvus exist in Milvus: False

=== Create collection `hello_milvus` ===


=== Start inserting entities       ===

Number of entities in Milvus: 3000

=== Start Creating index IVF_FLAT  ===


=== Start loading                  ===


=== Start searching based on vector similarity ===

hit: (distance: 0.0, id: 2998), random field: -13.0
hit: (distance: 0.16608965396881104, id: 1059), random field: -12.0
hit: (distance: 0.17376846075057983, id: 976), random field: -18.0
hit: (distance: 0.0, id: 2999), random field: -15.0
hit: (distance: 0.09368982911109924, id: 760), random field: -15.0
hit: (distance: 0.1466047316789627, id: 263), random field: -12.0
search latency = 0.2489s

=== Start querying with `random > -14` ===

query result:
-{'pk': 16, 'random': -11.0, 'embeddings': [0.73126, 0.492735, 0.017334, 0.219567, 0.872692, 0.050455, 0.072988, 0.322331]}
search latency = 0.2517s

=== Start hybrid searching with `random > -12` ===

hit: (distance: 0.2523949146270752, id: 2281), random field: -11.0
hit: (distance: 0.34272605180740356, id: 2146), random field: -11.0
hit: (distance: 0.34762364625930786, id: 467), random field: -11.0
hit: (distance: 0.249067485332489, id: 819), random field: -11.0
hit: (distance: 0.3513686954975128, id: 2786), random field: -11.0
hit: (distance: 0.4150209426879883, id: 1486), random field: -11.0
search latency = 0.3481s

=== Start deleting with expr `pk in [0, 1]` ===

query before delete by expr=`pk in [0, 1]` -> result: 
-{'pk': 0, 'random': -17.0, 'embeddings': [0.336848, 0.42659, 0.09273, 0.587923, 0.559363, 0.854384, 0.348711, 0.16934]}
-{'pk': 1, 'random': -20.0, 'embeddings': [0.273309, 0.255625, 0.597282, 0.181107, 0.198166, 0.758371, 0.186847, 0.120927]}

query after delete by expr=`pk in [0, 1]` -> result: []


=== Drop collection `hello_milvus` ===

当然,我们也可以直接启动一个交互式的 Python 终端,在里面干自己的事儿:

docker exec -it milvus python

镜像中的数据会保存在 /etc/milvus 目录中,如果你需要将本地调试或者试验时的数据进行持久化保存,可以在执行容器的时候,将数据目录映射到本地:

docker run --rm -it --name=milvus \
           -v `pwd`/data:/etc/milvus/data \
           -v `pwd`/logs:/etc/milvus/logs \
           -v `pwd`/etcd:/etc/milvus/etcd/data \
           -v `pwd`/rdbs:/etc/milvus/rdb/data \
           -v `pwd`/data:/etc/milvus/data \
           soulteary/milvus:embed-2.1.0

如果你有测试各种语言 SDK 的需求,也可以将容器的某些端口进行本地暴露,至于有哪些端口可用,可以参考 soulteary/portable-docker-app/milvus/config.yml 这个配置文件,再次就不多赘述啦。

对于有更高技术追求的同学,可以继续阅读我是如何优化这个镜像的,如果你只想愉快的在本地玩 Milvus,那么文章到此就可以结束啦。

工具镜像的制作

为了得到这个 200 MB 左右的镜像,属实费了“一番功夫”。在展开聊工具镜像的制作之前,我们需要先对制作素材有一定了解,先得来了解下 “Embed Milvus” 这个项目。

关于 Embed Milvus 项目

在 Milvus 2.1 版本中,推出了一个新的功能 Embedded Milvus,伴随这个新功能官方社区中也出现了一个新仓库:milvus-io/embd-milvus

这个项目是一个典型的“Golang 项目模块化”的例子,借助 Golang 能够使用buildmode=c-shared 构建出一个通用的 C-Style 的动态链接库(SO)。相比较其他的构建模式,这样构建出的“模块产物”,能够在各种语言中被低成本的调用,比如在开源项目 vladimirvivien/go-cshared-examples 中,你就能够找到至少十种主流编程语言对于 Go 构建模块产物的调用例子。

因为这个 Embeded 项目还在初期,所以在使用体验上并没有想象中的好用,如果想顺利玩起来这个项目,需要踩不少系统环境相关的坑,比如:

  • 你要能够完成一堆系统软件包的安装。
  • 你要能够正确折腾 Python 环境。
  • 你要能够正确安装和处理 Python 软件包的版本问题。
  • 你要能够正确配置系统环境变量,让动态链接库以正确顺序被程序引用。

这些事情折腾下来太麻烦了,而且会浪费很多的磁盘空间,如果使用传统方式安装,过程中各种缓存和不必要的文件将占用好几个 G 的空间。

为了解决这些问题,我决定花一些时间,制作一个体验更好的工具镜像

分析 Embedded Milvus 运行所需资源

Milvus 项目属于大型开源项目,构建过程还是比较复杂的,我在之前的博客里有提到过:(一)(二)(三)。为了能够在最短时间内得到 Milvus 构建出的 Embeded 的动态链接库,我选择直接“解包”官方项目中的产物。

先基于 Python 官方镜像创建一个只安装了 milvus 软件包的 Docker 镜像,来作为“资源镜像”:

FROM python:3.9-slim-buster AS Builder
RUN sed -i -E "s/\w+.debian.org/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
RUN apt-get update && \
    apt-get install -y libtbb-dev libboost-dev libtbb-dev libopenblas-dev && \
    apt-get remove --purge -y && \
    rm -rf /var/lib/apt/lists/*
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
    pip install milvus==2.1.0 --no-deps && \
    pip cache purge

在编写完 Dockerfile 之后,我们执行 docker build -t milvus-builder . 完成资源镜像的构建,这个镜像中就包含了我们所需要的一切“程序资源”:

Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM python:3.9-slim-buster AS Builder
 ---> 2f2210ecbb1c
Step 2/4 : RUN sed -i -E "s/\w+.debian.org/mirrors.tuna.tsinghua.edu.cn/g" /etc/apt/sources.list
 ---> Using cache
 ---> 89067599fc0b
Step 3/4 : RUN apt-get update &&     apt-get install -y libtbb-dev libboost-dev libtbb-dev libopenblas-dev &&     apt-get remove --purge -y &&     rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> c6401d21d519
Step 4/4 : RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple &&     pip install milvus==2.1.0 --no-deps &&     pip cache purge
 ---> Using cache
 ---> d6235e521ebb
Successfully built d6235e521ebb
Successfully tagged milvus-builder:latest

在完成镜像的构建后,我们使用 docker run --rm -it soulteary/milvus:embed-2.1.0 bash 进入资源容器,通过 find . | grep milvus 来寻找到关键的程序资源:

root@4bea421f5615:/# find . | grep milvus
./usr/local/lib/python3.9/site-packages/milvus
./usr/local/lib/python3.9/site-packages/milvus/bin
./usr/local/lib/python3.9/site-packages/milvus/bin/embd-milvus.so
./usr/local/lib/python3.9/site-packages/milvus/bin/embd-milvus.h
./usr/local/lib/python3.9/site-packages/milvus/lib
./usr/local/lib/python3.9/site-packages/milvus/lib/libmilvus_segcore.so
./usr/local/lib/python3.9/site-packages/milvus/lib/libknowhere.so
....

在确定资源都存放在/usr/local/lib/python3.9/site-packages/milvus/bin//usr/local/lib/python3.9/site-packages/milvus/lib/ 中之后。我们继续使用 ldd 命令,来依次分析这俩路径中各种 *.so 链接库的依赖关系,确定我们未来制作容器需要保留哪些程序文件。

使用 ldd 分析动态程序,将得到类似下面的结果:

root@4bea421f5615:/# ldd ./usr/local/lib/python3.9/site-packages/milvus/bin/embd-milvus.so
	linux-vdso.so.1 (0x00007ffc4a1f2000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f859265b000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f85924d8000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f85924b7000)
	libmilvus_indexbuilder.so => not found
	libmilvus_segcore.so => not found
	libmilvus_common.so => not found
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f85924b0000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f85924a6000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f859248c000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f85922cc000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f8598c2e000)

经过漫长的分析过程,我们最终能够确认一份简单的依赖清单。从而确定 “Embeded Milvus” 想要正常运行,需要哪些文件。

一切就绪之后,接下来就可以编写工具镜像的 Dockerfile 啦。

制作 All In One 的 Milvus工具镜像

为了避免跨操作系统引起的“动态链接库”的水土不服,这里我们选择和资源容器镜像相同的操作系统:

FROM python:3.9-slim-buster

在前文中,我们确认了两个资源集中的目录,通过简单的 COPY --from 指令将他们复制到新的容器中的 /usr/lib/ 目录里来:

COPY --from=builder /usr/local/lib/python3.9/site-packages/milvus/bin/*  /usr/lib/
COPY --from=builder /usr/local/lib/python3.9/site-packages/milvus/lib/*  /usr/lib/

除了 Milvus 项目本地的依赖程序之外,别忘记还需要复制我们分析排查出的系统依赖清单里的内容。

COPY --from=builder /usr/lib/x86_64-linux-gnu/libtbb.so.2 /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.5.so /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0 /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0 /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0 /usr/lib/x86_64-linux-gnu/
COPY --from=builder /usr/lib/x86_64-linux-gnu/libatomic.so.1.2.0 /usr/lib/x86_64-linux-gnu/

这里没有选择和一开始制作资源文件一样,使用 apt-get install 来完成系统依赖的安装,是因为通过 COPY --from 挑选复制必要文件,能够实现最大程度的容器镜像尺寸的瘦身。

除了对上面的文件进行复制之外,我们还需要根据之前收集的信息,使用 ln 命令,来根据之前 ldd 收集的信息,对这些系统依赖的路径创建一些“分身”,避免程序调用过程出现问题,同时也确保容器镜像中不会因为冗余内容造成体积膨胀问题。

RUN ln -s /usr/lib/x86_64-linux-gnu/libtbb.so.2              /usr/lib/x86_64-linux-gnu/libtbb.so            && \
    ln -s /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.5.so   /usr/lib/x86_64-linux-gnu/libopenblas.so.0     && \
    ln -s /usr/lib/x86_64-linux-gnu/libopenblasp-r0.3.5.so   /usr/lib/x86_64-linux-gnu/libopenblas.so       && \
    ln -s /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0         /usr/lib/x86_64-linux-gnu/libgomp.so.1         && \
    ln -s /usr/lib/x86_64-linux-gnu/libgfortran.so.5.0.0     /usr/lib/x86_64-linux-gnu/libgfortran.so.5     && \
    ln -s /usr/lib/x86_64-linux-gnu/libatomic.so.1.2.0       /usr/lib/x86_64-linux-gnu/libatomic.so.1       && \
    ln -s /usr/lib/x86_64-linux-gnu/libquadmath.so.0.0.0     /usr/lib/x86_64-linux-gnu/libquadmath.so.0

到这里为止,Embedded Milvus 的最小运行环境就就绪了。

因为我希望这是一个 All in One 的运行环境,所以我们还需要进一步安装 Python SDK:

RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple && \
    pip install pymilvus==2.1.0 protobuf==3.20.2 && \
    pip cache purge

简单的几行命令,容器就会从“清华源”下载两个固定版本的软件包,并且在下载完毕之后,清理掉下载过程中使用的缓存,确保容器体积没有因为“垃圾文件”而膨胀。

在一切就绪后,我们还需要创建一些目录,以及将上文提到的,准备好的配置文件复制到程序会读取的位置,确保程序在被调用的时候,不会报错:

RUN mkdir -p /etc/milvus/logs/          && \
    mkdir -p /etc/milvus/data/          && \
    mkdir -p /etc/milvus/etcd/data/     && \
    mkdir -p /etc/milvus/rdb/data       && \
    mkdir -p /var/bin/e-milvus/configs/ && \
    mkdir -p /var/bin/e-milvus/lib/     && \
    chmod 0700 /etc/milvus/etcd/data

COPY config.yml /var/bin/e-milvus/configs/embedded-milvus.yaml

为了简化官方 Embed 程序的执行环境,我们可以准备一个简单的“容器入口程序”:

#!/bin/bash
export LD_PRELOAD=/usr/lib/embd-milvus.so
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib:/usr/local/lib

python -c "import ctypes;library = ctypes.cdll.LoadLibrary('/usr/lib/embd-milvus.so');library.startEmbedded();"

将上面的内容保存为 entrypoint.sh 之后,我们将它复制到容器中:

COPY entrypoint.sh /
CMD ["/entrypoint.sh"]

当程序没有添加任何参数而被使用的时候,就会执行这个文件,按照官方项目中所要求的那样设置好系统环境变量,接着在 Python 中,调用 ctypes.cdll.LoadLibrary 函数加载动态链接库,然后启动 Milvus 程序。

最后,为了我们能够快速验证 Milvus 是否运行正常,我们还可以复制一个 Python 程序到容器的工作目录中,我这里选择的是官方 Python SDK 中的 Hello World 文件

WORKDIR /app
COPY hello-world.py ./

在上面的代码都就绪之后,我们执行 soulteary/milvus:embed-2.1.0 就能够完成这个相对小巧的工具镜像的构建啦。

最后

完整代码,我上传到了soulteary/portable-docker-app/milvus,有需要可以自取。

希望这个工具镜像能够帮到想进入向量世界的你。

–EOF


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2022年09月17日
统计字数: 10611字
阅读时间: 22分钟阅读
本文链接: https://soulteary.com/2022/09/17/the-docker-tool-image-of-the-entry-vector-database-milvus.html

### 回答1: 好的,让我来回答你的问题。首先,确保你已经在本地或者云上安装好了Docker。然后,按照以下步骤进行milvus部署: 1. 拉取milvus镜像 可以通过以下命令拉取milvus镜像: ``` docker pull milvusdb/milvus:latest ``` 2. 运行milvus容器 运行以下命令以启动milvus容器: ``` docker run -d --name milvus_cpu \ -p 19530:19530 \ -p 19121:19121 \ -v /data/milvus/db:/var/lib/milvus/db \ -v /data/milvus/conf:/var/lib/milvus/conf \ -v /data/milvus/logs:/var/lib/milvus/logs \ milvusdb/milvus:latest ``` 这里假设将milvus的数据存储在本地的`/data/milvus`目录下,如果没有该目录可以通过以下命令创建: ``` mkdir -p /data/milvus/{db,conf,logs} ``` 这里的`-p`参数表示递归地创建目录,如果目录已经存在则不会重复创建。 3. 验证milvus是否启动成功 运行以下命令来检查milvus是否启动成功: ``` docker logs milvus_cpu ``` 如果看到以下类似的日志,则说明milvus已经成功启动: ``` INFO:root:Milvus server started successfully! ``` 以上就是使用Docker部署milvus的步骤,如果你想使用GPU版本的milvus,只需要将`milvusdb/milvus:latest`替换成`milvusdb/milvus:cuda10.1-cudnn7-runtime-1.0.0`即可。 ### 回答2: Docker是一个开源的容器化平台,可以帮助开发者更简单、高效地部署和管理应用程序。而Milvus是一种基于向量相似度搜索引擎的开源软件,它可以快速地处理大规模的向量数据。接下来,我将介绍如何使用Docker部署和运行Milvus。 首先,你需要确保已经安装了DockerDocker Compose。然后,你可以通过以下步骤部署和运行Milvus: 1. 下载MilvusDocker Compose配置文件。 你可以从Milvus的官方GitHub仓库中找到Docker Compose配置文件。选择适合你的系统的版本,然后将其下载到你的本地计算机。 2. 配置Milvus的参数。 打开下载的Docker Compose配置文件,并根据系统需求进行参数配置。你可以指定Milvus的端口、存储路径和资源限制等。 3. 启动Milvus容器。 在终端中导航到存放下载的Docker Compose配置文件的文件夹,并执行以下命令启动Milvus容器: ``` docker-compose up -d ``` 这将在后台启动Milvus容器。 4. 检查Milvus容器的运行状态。 执行以下命令可以检查Milvus容器的运行状态: ``` docker ps ``` 如果Milvus容器正在运行,你应该能够看到一个包含Milvus镜像名称的容器。 现在,你已经成功地使用Docker部署和运行了Milvus。你可以通过访问配置文件中指定的端口,在浏览器中打开Milvus的Web界面来管理和使用Milvus。例如,如果你将Milvus配置为使用默认端口(例如,192.168.0.1:19530),则可以在浏览器中输入该地址以打开Milvus的Web界面。 总之,使用Docker可以简化Milvus部署和管理过程,节省了配置环境和依赖项的时间,提高了应用程序的可移植性。希望这个回答对你有所帮助! ### 回答3: Docker是一个开源的平台,可以用于自动化部署、扩展和管理应用程序。Milvus是一个高效的开源向量数据库,可以快速存储和查询大规模向量数据。下面将介绍如何使用Docker部署Milvus。 首先,确保您已经安装了Docker并启动了Docker服务。然后,打开终端并执行以下命令来拉取MilvusDocker镜像: ``` docker pull milvusdb/milvus ``` 拉取完成后,可以使用以下命令来启动Milvus容器: ``` docker run -d --name milvus \ -p 19530:19530 \ -p 8080:8080 \ -v ~/milvus/db:/var/lib/milvus/db \ -v ~/milvus/conf:/var/lib/milvus/conf \ milvusdb/milvus:latest ``` 这个命令会创建一个名为"milvus"的容器,并将Milvus的默认端口19530和8080映射到宿主机的对应端口。同时,将容器内的数据库和配置文件目录映射到宿主机的相应目录。 启动完成后,您可以使用Milvus的客户端工具或通过浏览器访问"http://localhost:8080"来管理和查询Milvus数据库。默认的用户名和密码分别为"root"和"123456"。 如果需要停止或删除Milvus容器,可以使用以下命令: 停止容器: ``` docker stop milvus ``` 删除容器: ``` docker rm milvus ``` 需要注意的是,以上命令中的路径"~/milvus/db"和"~/milvus/conf"可以根据实际情况修改为您想要存储数据库和配置文件的路径。 通过以上步骤,您就可以使用Docker来快速部署和管理Milvus向量数据库了。它提供了一个便捷的方式,可以在不同的环境中轻松复制和迁移Milvus实例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值