✏️  作者介绍:

周充,格像科技后端工程师

需求背景

根据格像科技公司的业务需求,我们需要搭建一个近似最近邻(Approximate Nearest Neighbor,即 ANN)搜索引擎,以便将在线向量相似搜索功能应用到公司其他业务中。我们搭建的 ANN 搜索引擎需要满足以下几个要求:

  • 具备高可用性。

  • 与公司现有的运维、监控和警报系统兼容。

  • 可以水平扩展,在流量高峰时保证性能。

  • 不同业务的索引资源相互隔离。

  • 只需要每日一次更新业务数据即可。

最终我们基于 Milvus 搭建了 ANN 搜索引擎,实现了上述需求。

基础系统

目前公司已有基础系统如下:

  • 面向服务的架构(SOA,Service-Oriented Architecture)框架——用于构建微服务架构。功能包括:服务注册,服务发现,访问路由,负载均衡,熔断限流等。主要支持 Java Web 应用,提供功能和 Dubbo 基本一致。

  • 运维平台——将 Docker 镜像部署在 k8s 集群中的唯一入口。

  • 监控和警报系统——收集各个服务应用中的调用链、日志、指标等信息,集中管理监控和警报。

上述系统环境便于部署无状态的 Java Web 应用,还拥有完整的监控报警覆盖。并且,通过增加 k8s Pod 扩容,能够保障系统的性能和可用性。

为了赋予 ANN 搜索引擎相同的向量相似搜索能力,我们选择在 Milvus 和现有的基础系统之间增加一个中间层,从而将 Milvus 强大的向量相似搜索功能移植到我们的系统之中。

实现方案

3.1 单个节点 

我们考虑通过如图所示方式来实现单个节点的功能。我们在一个 Docker 镜像中会启动两个进程——Milvus 进程和 Java SOA 进程。Java SOA 进程本身是一个 Java Web 应用,类似一个代理(proxy),会将相似搜索的请求转发给 Milvus 进程,并返回搜索结果。

虽然 Milvus 本身已经提供了一整套简单直观的 API 来支持线上服务,但是为了将 Milvus 更好地接入我们现有系统体系,我们仍然选择将 Java SOA 作为中间层,从而将成本降至最低。

除此之外,Java SOA 进程还具备管理数据更新的功能。我们业务中的各项数据均可离线更新,而 Java SOA 进程则会在收到数据更新的消息后,从阿里云对象存储(OSS,Object Storage Service) 上下载打包好的数据,并导入 Milvus。

我们选择用 SQLite 作为 Milvus 的元数据(Metadata)管理数据库。Java SOA 从阿里云 OSS 上下载的是一个完整的索引(Index)文件,放到指定目录之后会通过更新 SQLite 的方式将数据导入 Milvus。

3.2 复制节点 

为了实现 ANN 搜索引擎系统的高可用性,我们需要更多其他的副本节点来提供相同的向量搜索服务。实现方案如下图所示:

我们的实现方式与其他数据库(如 MySQL、Redis 等)有所不同。不同之处在于我们并非通过数据同步的方式提供多个“复制状态机”,而是仅需通过离线方式保证所有节点在同一时间更新全量数据即可。

写入数据的时间点有两个。首先是在一个新的节点启动时写入数据。这个新的节点会去 OSS 上下载最新打包好的数据,并导入 Milvus 向量相似搜索库中。另一个时间点是在离线任务生成数据后,各节点会收到“消息”通知,去 OSS 上下载最新的数据来进行更新。

根据 CAP 原则 ,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance),这三个特性中最多只能同时实现两个,不可能三者兼顾。为实现多个节点的数据一致性,我们采取了以下手段来确保每个客户端的访问在时间维度上是线性一致的。

首先,所有的数据更新并不会直接覆盖原来的数据表(Collection),而是写入一个新的分区(Partition)。客户端在发起向量搜索请求时,会带上最新的分区名称。如果某个节点上的新数据已经完成加载,会返回最新分区中的搜索结果。否则,就返回错误,让客户端重试其他节点,以此保证某一客户端在得知最新的分区名称后,只会访问到最新的数据。

为了系统性能可以在一定程度上牺牲数据一致性。比如,发现陈旧数据也不进行报错,或者客户端在成功访问到最新数据后才会对陈旧数据报错。上述情况都可以通过 Java SOA 进程根据业务配置选择对应的规则实现。

3.3 多个索引 

由于线上不同业务使用的索引不同,并且不同业务之间的资源也是相互隔离的,我们需要通过如图所示的多个索引方式来实现构建 ANN 搜索引擎。多个索引方式就是在每个节点上只维护一个数据表中的数据。客户端在访问索引时,会通过元数据服务找到索引名称的 SOA 地址和版本,然后访问对应的节点。

3.4 数据分片 

单个节点索引的性能和资源必然存在上限,对于更庞大的索引,我们应该将其分片存储,以分散计算和存储的压力。这一部分的思想和 Mishards 相同。如图所示,我们将数据存储在多个分片节点上,并行获取搜索结果后再聚合得到最终结果。不过这里我们将聚合的计算放在客户端实现,对于 ANN 节点来说不需要做特殊的处理。

总体架构

搭建的 ANN 搜索引擎中包含以下五个角色,我们一一详细介绍五个角色的作用以及角色之间的相互关系:

  • ANN Client 

ANN Client 是其他服务访问 ANN 搜索引擎的入口。ANN Client 会从元数据管理服务上获取对应的信息,并在搜索向量时路由到对应的节点。

  • 服务注册中心 

通过 SOA 框架实现。所有的 ANN 节点都会在注册中心上注册自己的版本,并可以通过 SOA 路由访问这些节点。

  • 元数据管理服务 

用于存储 ANN 集群的元数据,即 ANN 集群上的 SOA 版本和业务数据表名称、分片的对应关系。将此信息持久存储在数据库中,结构如下表所示:

  • ANN 集群 

ANN 集群由上文提到的节点组成,每个节点只维护一份数据表数据,也存在对应的副本或者其它数据分片。

  • 离线数据更新系统

我们使用阿里云的 ODPS 作为数据仓库和离线任务的运行系统,将对应的向量数据从数据仓库中提取出来写入一个离线的 Milvus 节点中,并在它上面构建索引(Index)文件。之后,再把索引文件和对应的元数据打包,上传至阿里云 OSS ,并通知元数据管理服务。之后,ANN 集群中的对应节点会从 OSS 上下载最新的索引文件并更新本地的数据。

五个角色之间的关系如下图所示:

在线部分中,ANN Client 从服务注册中心和元数据(Metadata)管理服务获取到服务和数据的对应关系后,根据业务需要,向对应的 ANN 服务节点发起请求。离线部分则由数据仓库产生每日更新的数据,然后写入一个离线的 Milvus 节点,生成索引文件,打包后上传到阿里云 OSS,并通知 ANN 节点更新数据。

数据的读写流程

5.1 读数据流程 

ANN Client 在进行搜索之前,会先从元数据管理服务获取对应分片数据所在的 SOA 地址,即元数据。之后会根据业务需要访问对应的 ANN 节点。如果这个索引是分片的,ANN Client 则会访问索引的全部分片(如下图中的Shard1,Shard2,Shard3),然后汇总结果并返回。

5.2 写数据流程 

离线和近实时写入,可以参考上文的离线数据更新系统。

公司的业务暂时没有实时写入数据的需求,而且实时写入数据的方案会面临一些问题。为了保证高可用性,每个分片(Shard)都有多个副本节点,并且可以接受读取请求。因此,写入数据的时候还需要确保实现这几个副本节点之间的数据同步。

Milvus 官方提供的方案是使用网络文件系统。这几个节点在操作系统层面上访问同一个文件,由文件系统保证数据的一致性。但是这个方案需要我们在 K8S 上做一些定制,成本较高。

在理想情况下,我们可能需要实现这些副本节点之间的异步数据同步,例如简单的异步复制或者组成一个 Raft 集群,但是这一方案同样需要大量的额外开发成本。

总结

我们通过开发一个 Java 中间层,将 Milvus 提供的向量相似搜索功能接入目前已有的 SOA 框架中,以实现服务发现、高可用性、水平扩展等功能。然后我们又通过元数据管理服务来组织数据的分片和离线数据更新,从而完成了搭建整个 ANN 搜索引擎所需的链路。

更多 Milvus 用户案例

我的机器人新同事

基于 Milvus 的钓鱼网站检测

相似问答检索——汽车之家的 Milvus 实践

蓝灯鱼 AI 专利检索在 Milvus 的实践

欢迎加入 Milvus 社区

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

milvus.io | 官网

milvusio.slack.com | Slack 社区

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

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili

基于 Milvus 构建的近似最近邻(ANN)搜索引擎相关推荐

  1. 基于Sphinx构建准实时更新的分布式通用搜索引擎平台

     亿级数据的高并发通用搜索引擎架构设计[原创]   大 |  中 |  小  [  2008-12-9 08:47 | by  张宴 ] [文章作者:张宴 本文版本:v1.0 最后修改:2008.12 ...

  2. 快速近似最近邻算法_数据科学家指南,以选择最佳近似最近邻算法

    快速近似最近邻算法 by Braden Riggs and George Williams (gwilliams@gsitechnology.com) Braden Riggs和George Will ...

  3. opencv图像配准_Milvus 实战 | 基于 Milvus 的图像查重系统

    背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部分. ...

  4. Milvus 实战 | 基于 Milvus 的图像查重系统

      背景介绍 由于巨大的利益,论文造假屡见不鲜,在部分国家或地区甚至形成了论文造假的产业链.目前大部分论文查重系统只能检查论文文字,不能检查图片.因此,论文图片查重已然成为了学术论文原创性检测的重要部 ...

  5. 海量数据索引与近似最近邻随记

    最近邻问题(NN) 将次数看成向量,然后我们就可以比对向量的距离(欧式距离,余弦距离).数据中会有一些异常点,这些异常点会导致结果的不稳定.这种思想非常的不稳定,因为他只基于一个样本来做最后类别的判定 ...

  6. 余弦相似度 高维数据_海量高维数据与近似最近邻

    在实际工程当中,我们常常会遇到海量的数据,那作为一个数据挖掘准从业人员,如何从海量的数据当中挖掘出他们数据之间的关系和规律就显得尤为重要了. 今天我要讲的时海量高维数据及其近似最近邻方案. K-近邻算 ...

  7. 极度快速的近似最近邻搜索算法(EFANNA)-学习笔记

    博客地址:www.mzwang.top 微信公众号:whenever5225 引言 极度快速的近似最近邻搜索算法(EFANNA)是NSG的作者之前的一篇论文,这篇论文主要介绍用更快的方法建立KNN图并 ...

  8. LSH 近似最近邻查找

    一.什么是近似最近邻查找 NN与ANN NN,Nearest Neighbor Search,最近邻查找问题 KNN,K-Nearest Neighbor,k最近邻,查找离目标数据最近的前k个数据项 ...

  9. 【论文笔记】基于范围的有障碍最近邻查询(RONN)

    本文是关于论文<Range-based Obstructed Nearest Neighbor Queries(RONN)>(基于范围的有障碍最近邻查询)的阅读笔记.没有完全读懂. 一.记 ...

最新文章

  1. 内核知识第八讲,PDE,PTE,页目录表,页表的内存管理
  2. Python flask出现jinja2.exceptions.TemplateNotFound错误(修复host就好了???)
  3. 神经网络 | DeepVO:Towards End-to-End Visual Odometry
  4. 哈佛终身教授刘军:生活在一个统计学的时代
  5. 直接在 CSS 中引用 FONTAWESOME 图标(附码表)
  6. SpringCloud+Redis
  7. python语言在命名上是什么敏感的_一文轻松掌握python语言命名规范规则
  8. Hadoop伪分布式搭建(本人新手,欢迎大家多多指导和关照)
  9. android classloader双亲托付模式
  10. idea springboot学习笔记
  11. java排序之选择排序
  12. 171025_matlab_imag函数
  13. ArcServer 9.3 ecp、 ArcSDE 9.3 ecp、 ArcIMS 9.3 ecp、 ArcEngine 9.3 ecp
  14. JVM00_面试官对类加载器子系统、运行时数据区、内存分布、执行引擎的灵虚拷问,你能坚持到第几问?
  15. 关于在固态硬盘(ssd)上的Win10系统是否需要优化驱动器选项的调查
  16. java_09.Linux:远程登录_可以用putty也可以用SecureCRT或者Xshell5【关闭防火墙,或者关闭一些必要的防火墙才能远程登录】Linux能ping通windows,window
  17. Eclipse将项目部署tomcat的webapps目录
  18. Solr JVM内存不足
  19. 如何提供ap服务器硬件,如何一步步配置无线网络项目AC+AP?
  20. 判断输入的整数是不是质数(素数)

热门文章

  1. 解决PTA题:找错误原因(3)6-6 删除字符
  2. 重庆大学考试计算机应用基础b卷,201803批次网上考试计算机应用基础B卷-重庆大学...
  3. linux环境下安装puphpeteer
  4. 大数据信息资料采集:58同城赶集网百姓网分类网站教育培训采集
  5. Mysql数据库(三):详细,对新手非常友好
  6. 北邮通信原理公开课 杨鸿文老师 课程学习笔记【第五课 许瓦兹不等式】
  7. 计算机应用简单的微课制作,《计算机应用基础》微课制作经验谈.doc
  8. 什么是高并发(java为例)
  9. 哈哈日语 | 超实用商务日语问题
  10. android中强行停止(forceStopPackage)对alarmManager、Receiver的影响