专栏首页Reinvent Data ScienceMilvus 实战 | 基于 Kubernetes 的分布式集群部署方案

Milvus 实战 | 基于 Kubernetes 的分布式集群部署方案

Milvus 作为一款针对海量特征向量的相似度搜索引擎,在单台服务器上就可以处理十亿级数据规模。而对于百亿或者千亿级数据,则需要具有水平扩展能力的 Milvus 集群来满足对海量向量数据的高性能检索需求。

我们使用了 Mishards 中间件来搭建 Milvus 集群。Mishards 是一个用 Python 开发的 Milvus 集群分片中间件,其内部处理请求转发、读写分离和水平扩展,为用户提供内存和算力可以扩容的 Milvus 实例。详情请参阅 Mishards

https://milvus.io/cn/docs/v0.10.0/mishards.md

本文将主要介绍如何在集群内部配置 StorageClass 实现共享存储,如何使用 Helm 或 kubectl 部署 Milvus 集群,最后通过在集群外部访问 Milvus 服务测试集群。本集群包含 2 个 Milvus 实例(1 个可读实例,1 个可写实例)、1 个 MySQL 实例和 1 个 Mishards。本示例将使用两台服务器部署一个 Milvus 集群:服务器 A 配置为 Kubernetes Master 节点;服务器 B 配置为 Kubernetes Worker 节点。

以下是 Kubernetes 示例架构图:

| 实现共享存储

1

为什么需要共享存储

容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题。首先,当容器崩溃时,kubectl 将重新启动容器,容器中的文件将会丢失。其次,当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件。Kubernetes 抽象出 Volume 对象来解决这两个问题。

但是,当一个 Pod 不再存在时,Volume 也将不再存在。因此,Kubernetes 引入了 Persistent Volumes (PV)。PV 是集群中一块已经由管理员配置或使用 StorageClass 动态配置的存储。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的共享存储系统。Kubernetes 通过网络访问的共享文件系统,不仅可以更加可靠地存储来保存应用产生的重要数据,还可以实现 Pod 之间数据共享。

2

部署 StorageClass

1. 为了共享数据,PV 访问模式必须被设置为 ReadOnlyMany 或 ReadWriteMany。

2. 文件存储系统的选择:

如果集群部署在 AWS,可以使用 Elastic File System (EFS)

https://aws.amazon.com/cn/efs/

如果集群部署在 Azure,可以使用 Azure File Storage (AFS)

https://docs.microsoft.com/en-us/azure/aks/azure-files-dynamic-pv

部署流程

1. 拉取源码:

$ git clone https://github.com/helm/charts.git
$ cd charts/stable/nfs-client-provisioner

配置文件下载完成后,需要将 values.yaml 文件中的 server 参数改为共享存储服务器的 IP 地址,将 path 参数改为共享存储目录。此外,由 StorageClass 动态创建的 PersistentVolume 将使用 mountOptions 字段指定的挂载选项。

2. 安装 NFS client chart:

$ helm install nfs-client .

NFS Client Provisioner 是用于自动创建 Kubernetes PV 的自动化插件。它可以根据已配置好的 NFS Server,自动创建 Kubernetes PV。

3. 检查部署状态:

$ helm list

4. 通过 watch 指令检查是否部署成功:

$ watch kubectl get po -l app=nfs-client-provisioner
5. 查看当前 StorageClass:
$ kubectl get storageclass
NAME                   PROVISIONER                                       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client (default)   cluster.local/nfs-client-nfs-client-provisioner   Delete          Immediate           true                   5d23h

| 部署 Milvus 集群

这里将展示两种部署 Milvus 集群的方式。

1

利用 Helm 部署 Milvus

下面将演示如何利用 Milvus chart 和 Helm 包管理器在 Kubernetes 集群上部署 Milvus。

https://github.com/milvus-io/milvus-helm/tree/0.10.0

1. 拉取源码:

$ git clone -b 0.10.0 https://github.com/milvus-io/milvus-helm.git
$ cd milvus-helm

2. 部署 Milvus:

$ git clone https://github.com/milvus-io/milvus-helm.git$ cd milvus-helm$ helm install --set cluster.enabled=true --set persistence.enabled=true --set mysql.enabled=true my-release  .

关于 Milvus Server 的详细参数,可参考Milvus Server Configuration

https://github.com/milvus-io/milvus-helm/tree/0.10.0#configuration

3. 查看 Milvus 部署状态:

$ helm list

4. 查看 Pods 是否启动成功:

$ kubectl get pods
# You are expected to see the following output.
NAME                                                READY   STATUS    RESTARTS   AGE
my-release-milvus-mishards-8f97db7fb-qxxgn          1/1     Running   0          12m
my-release-milvus-readonly-66784bccd6-67wcr         1/1     Running   0          12m
my-release-milvus-writable-55d7ff788b-n4zc6         1/1     Running   1          12m
my-release-mysql-8688668cd-2rj7k                    1/1     Running   1          12m
nfs-client-nfs-client-provisioner-86cf7c4bc-hd7bq   1/1     Running   3          32m

如果有 Pods 未启动成功,请使用以下命令进行错误排查:

$ kubectl logs <NAME>
or
$ kubectl describe pod <NAME>

2

利用 kubectl 部署 Milvus

利用 kubectl 部署应用的实质是部署 YAML 或 JSON 文件中定义的内容。因此需要利用 Go 安装 schelm 插件。通过 schelm 插件获得 manifest 文件,它们即为 Kubernetes 可以识别的 YAML 格式的资源描述。

1. 拉取源码:

$ git clone -b 0.10.0 https://github.com/milvus-io/milvus-helm.git
$ cd milvus-helm

2. 下载并解压 Go:

$ wget https://dl.google.com/go/go1.14.6.linux-amd64.tar.gz
$ sudo tar -C /usr/local -xzf go1.14.6.linux-amd64.tar.gz

3. 在 /etc/profile 或者 HOME/.profile 添加环境变量:

export PATH=$PATH:/usr/local/go/bin

以上为在 Ubuntu 安装 Go 的方法,其他系统请参考 Install the Go tools

https://golang.org/doc/install

4. 安装 schelm 插件:

$ go get -u github.com/databus23/schelm
$ sh
sh               sha224sum        sha384sum        shadowconfig     sh.distrib       shopt            showconsolefont  showrgb          shuf             
sha1sum          sha256sum        sha512sum        shasum           shift            shotwell         showkey          shred            shutdown

5. 获取 Milvus 的 manifest 文件:

$ helm install --dry-run --debug --set cluster.enabled=true --set persistence.enabled=true --set mysql.enabled=true my-release  . | ~/go/bin/schelm output/

6. 将配置文件应用到 Pod:

$ cd output/milvus/$ kubectl apply -f templates/$ cd /charts/mysql/$ kubectl apply -f templates/
如果出现格式转换错误,请修改对应的 YAML 文件。

7. 查看 Pods 是否启动成功:

$ kubectl get pods



| 测试

此时,Milvus 服务已成功部署到 Kubernetes 上。但是,Kubernetes 的默认服务为ClusterIP,集群内的其它应用可以访问该服务,而集群外部无法进行访问。所以,如果想在 Internet 或者生产环境中使用集群,需要更换 Service 以暴露应用。Kubernetes 的两种可以暴露服务的 Service 类型为:NodePort 和 LoadBalancer。此外可以通过 Ingress 公开从集群外部到集群内 services 的 HTTP 和 HTTPS 路由。下面将介绍如何使用 NodePort 服务在外部访问集群。

1. 修改服务方式:

$ vim values.yaml
参数修改:

将 Milvus Server Configuration 部分的 service.type 修改为 NodePort。

更多关于暴露应用的方法,请参考 Expose Your App Publicly

https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/

2. 更新 Milvus release:

$ helm upgrade --set cluster.enabled=true --set persistence.enabled=true --set mysql.enabled=true my-release  .

3. 查看端口状态:

$ kubectl get service
# You are expected to see the following output.
NAME                         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)               AGE
kubernetes                   ClusterIP   10.96.0.1      <none>        443/TCP               24h
my-release-milvus            NodePort    10.99.64.80    <none>        19530:32227/TCP       30m
my-release-milvus-readonly   ClusterIP   10.99.29.32    <none>        19530/TCP,19121/TCP   30m
my-release-milvus-writable   ClusterIP   10.98.84.247   <none>        19530/TCP,19121/TCP   30m
my-release-mysql             ClusterIP   10.97.182.37   <none>        3306/TCP              30m

4. 在集群外的服务器安装 Milvus Python SDK:

$ pip3 install pymilvus==0.2.14

5. 下载 Python 示例代码:

$ wget https://raw.githubusercontent.com/milvus-io/pymilvus/0.2.14/examples/example.py

修改其 _HOST 为集群中任意一台服务器 IP 地址,_PORT 为暴露服务的静态端口。

6. 运行示例代码:

$ python3 example.py
# You are expected to see the following output.
CollectionSchema(collection_name='example_collection_', dimension=8, index_file
......
{'partitions': [{'row_count': 10, 'segments': [{'data_size': 400, 'index_name':
Creating index: {'nlist': 2048}
(collection_name='example_collection_', index_type=<IndexType: IVFLAT>, params=
Searching ...
Query result is correct
......

| 结语

本文利用两种方法轻松将 Milvus 部署到 Kubernetes 中,并通过在数据集外部访问 Milvus Server 进行了相关测试。当需要使用 Milvus 处理海量特征向量时,可以使用该分布式集群方案增强横向扩容能力,以获得更好的体验。也可自行尝试将该系统从物理机环境中无缝迁移到公有云中。

基于 Mishards 的分布式方案请参考 Mishards

? https://github.com/milvus-io/bootcamp/tree/master/solutions/Mishards

基于 Kubernetes 的分布式搭建方案请参考 Milvus HelmK8s Bootcamp

? https://github.com/milvus-io/milvus-helm
? https://github.com/milvus-io/bootcamp/tree/0.10.0/solutions/Kubernetes

| 欢迎加入 Milvus 社区

github.com/milvus-io/milvus | 源码

milvus.io | 官网

milvusio.slack.com | Slack 社区

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili

本文分享自微信公众号 - ZILLIZ(Zilliztech),作者:李晴

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 利用Doc2Vec和Milvus搭建相似文章召回服务

    上星期六很高兴请到了我们 Milvus 用户-松鼠,来与我们做了一期直播。想知道如何用 Doc2vec 和 Milvus 做相似文章推荐吗?欢迎点击视频看回放~

    ZILLIZ
  • Milvus 实战|利用 Milvus 搭建基于图的推荐系统

    推荐系统[1](Recommender System,RS)能够根据用户的偏好主动为用户推荐商品或项目。它通过用户的历史数据来发掘用户兴趣偏好,从而将用户可能感...

    ZILLIZ
  • 视频|5分钟轻松上手Milvus Admin

    Milvus 作为一个开源的基础软件,让用户可以轻松地上手使用也是至关重要的。作为 Milvus 产品化重要的一环,Milvus Admin 就是这样一款面向企...

    ZILLIZ
  • 从零开始学C++之友元:友元函数和友元类

    一、友元介绍 我们知道,类的成员函数可以访问同类的其他成员函数,包括公有、私有和保护成员。而类的外部函数只能访问类的公有成员。 友元是一种允许非类成员函数访问类...

    s1mba
  • 非易失性内存技术及数据库

    “2013年开始这个项目的研究,当时不确定非易失性内存技术是否可商用。2019年Intel商用了NVM产品,NVM对下一代数据库系统的影响吸引了广大研究者”--...

    yzsDBA
  • 随谈10年的技术生涯和技术成长

    先简单分享自己这10年在技术上曾经感觉到明显迷茫的阶段: 阶段1:只会增删改查: 时间:大学期间(2005年-2006年) 学习的方式:看视频、看书。(学会了使...

    李海彬
  • 盒模型和box-sizing

    根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的。不幸的是,IE5.X 和 ...

    FinGet
  • 如何将Markdown文章轻松地搬运到微信公众号并完美地呈现代码内容

    相信有很多童鞋跟我一样,热衷于用Markdown来编写文章。由于其简单的语法和清晰的渲染效果,受到广大码农朋友们的推崇。但是,当我们想维护起自己的公众号时,公众...

    程序猿DD
  • 云开发新能力,支持HTTP调用API

    今天来上班打开电脑,总感觉微信开发文档哪里有点不太一样,研究了半天原来是云开发又多了神级功能——HTTP API!

    腾讯云开发TCB
  • Michael Stonebraker:数据科学替代商务分析尚存挑战

    用户1737318

扫码关注云+社区

领取腾讯云代金券