https://milvus.io/cn/docs/v1.1.0/mishards.md
https://cloud.tencent.com/developer/article/1607480
https://aistudio.baidu.com/bdcpu2/user/271421/2031362/notebooks/2031362.ipynb
https://aistudio.baidu.com/aistudio/projectdetail/1816335?channel=0&channelType=0&shared=1
相似度对比的模型的输出一般是一组向量的,然后拿这个向量去对需要比对的向量去做余弦相似度或者欧式距离。从PaddleHub中拿到这个向量,然后放入向量搜索引擎,让搜索引擎去做余弦相似度或者欧式距离
深度学习模型只做文本到向量的过程,搜索部分自己写需要高度优化,这部分交给向量搜索引擎就快了
https://github.com/PaddlePaddle/PaddleNLP/tree/develop/examples/semantic_indexing 语义索引技术可以了解下
向量搜索引擎 Milvus 旨在帮助用户实现海量非结构化数据的近似检索和分析。单个 Milvus 实例可处理十亿级数据规模,而对于百亿或者千亿规模数据的需求,则需要一个 Milvus 集群实例,该实例对于上层应用可以像单机实例一样使用,同时满足海量数据低延迟、高并发业务需求。集群内部处理请求转发、读写分离、水平扩展、动态扩容,为用户提供内存和算力可以无限扩容的 Milvus 实例。Mishards 就是一个 Milvus 分布式解决方案。
本文将基于 Mishards 的分布式架构,集中介绍当中的各种组件。对于更细节的展示,将会在之后的系列文章中一一详解。
可扩展组件:
如图所示,Mishards 接受到向量 TopK 搜索请求后,首先将请求切分成一些子请求,再将子请求按照一定的逻辑分发到下游服务并等待响应,待所有子响应收集完成后,聚合各子响应结果并返回给上游。
Mishards 是无状态的服务,本身并不保存数据也不参与复杂的计算。因此节点对于配置的要求不是太高,主要的算力消耗在结果集的归并上。因此,可以通过扩容 Mishards 节点数来支持高并发。
Milvus 节点负责数据的增删查改相关的核心操作,因此节点对于机器的配置要求比较高。首先,要有足够大的内存避免磁盘 IO 开销,其次 CPU 的配置也直接影响到操作性能。通常随着集群的扩大,需要增加更多的 Milvus 节点来提高系统的吞吐量。
当处理的数据规模特别大,或者对于系统低延迟要求特别高,可以将只读节点作为有状态的节点横向扩展。假设有四台机器,每台配置: CPU Cores: 16, GPU: 1, Memory: 64G. 横向扩展有状态节点时的集群对外视图如下图,算力和内存都线性扩展。数据被分割成8个分片,每个节点只处理2个分片的请求。
关键字:MySQL
关于 Milvus 元数据的相关概念,参见大规模向量检索场景下的数据管理(下篇)一文。在分布式系统中,Milvus 可写节点是元数据唯一的生产者,而 Mishards 节点,Milvus 可写节点和 Milvus 可读节点都是元数据的消费者。目前版本的 Milvus 只支持 MySQL 和 SQLite 作为元数据的存储后端,在分布式系统中,该服务只能部署成高可用 MySQL 服务。
服务发现:
关键字:Apache Zookeeper、etcd、Consul、Kubernetes
服务发现提供所有 Milvus 节点的信息,Milvus 节点上线时注册自己的信息,下线时注销,并通过定期检查服务的健康状态,及时发现异常节点。
服务发现有很多框架,etcd, Consul,ZooKeeper 等。Mishards 定义了相关的服务发现接口,并通过插件模式提供了扩展的可能性。目前默认提供了两种插件,分别对应了基于 Kubernetes 集群和静态配置。用户可以仿照这两种插件的实现,定制化自己的服务发现实现。目前相关接口定义还比较临时,需要后期重新设计。我会在 Mishards 插件篇详细讲解如何写一个自己的插件。
关键字:NGINX、HAPROXY、Kubernetes
服务发现和负载均衡配合使用,负载均衡策略可以配置成轮询、哈希和一致性哈希等。
负载均衡器负责将用户请求转发至 Mishards 节点。
每个 Mishards 节点通过服务发现中心拿到所有下游 Milvus 节点的信息,通过元数据服务知晓整个数据相关元数据。Mishards 实现服务分片就是对于这些素材的一种消费。Mishards 定义了路由策略相关的接口,并通过插件提供扩展。目前 Mishards 默认提供了基于存储最底层 segment 级别的一致性哈希路由策略。如图有10个数据段 s1, s2, s3… s10, 现在选择基于数据段的一致性哈希路由策略,Mishards 会将涉及 s1, s4, s6, s9 数据段的请求路由到 Milvus 1 节点, s2, s3, s5 路由到 Milvus 2 节点, s7, s8, s10 路由到 Milvus 3 节点。
用户可以仿照默认的一致性哈希路由插件,根据自己的业务特点,定制个性化路由。
关键字:OpenTracing、YAEGER、ZIPKIN
分布式系统错综复杂,请求往往会分发给内部多个服务调用,为了方便问题的定位,我们需要跟踪内部的服务调用链。随着系统的复杂性越来越高,一个可行的链路追踪系统带来的好处就越显而易见。我们选择了已进入 CNCF 的 OpenTracing 分布式追踪标准,OpenTracing 通过提供平台无关,厂商无关的 API ,方便开发人员能够方便的实现链路跟踪系统。
上图是 Mishards 服务中调用搜索时链路跟踪的例子,Search 顺序调用 get_routing, do_search 和 do_merge。而 do_search 又调用了 search_127.0.0.1。
整个链路跟踪记录形成下面一个树:
下图是每个节点 request/response info 和 tags 的具体实例:
OpenTracing 已经集成到 Milvus 中,我将会在 Milvus 与 OpenTracing 一文中详细讲解相关的概念以及实现细节。
监控与报警:
关键字:Prometheus、Grafana
Milvus 已集成开源 Prometheus 采集指标数据, Grafana 实现指标的监控,Alertmanager 用于报警机制。Mishards 也会将 Prometheus 集成进去。
日志分析:
关键字:Elastic、Logstash、Kibana
集群服务日志文件分布在不同服务节点上,排查问题需要登录到相关服务器获取。分析排查问题时,往往需要结合多个日志文件协同分析。使用 ELK 日志分析组件是一个不错的选择。
Mishards 作为 Milvus 服务中间件,集合了服务发现,请求路由,结果聚合,链路跟踪等功能,同时也提供了基于插件的扩展机制。目前,基于 Mishards 的分布式方案还存在以下几点不足:
我们会在之后的版本中尽快解决这些已知的问题,让 Mishards 可以更加方便的应用生产环境。
本文分享自微信公众号 - ZILLIZ(Zilliztech) ,作者:徐鹏
原文出处及转载信息见文内详细说明,如有侵权,请联系 [email protected] 删除。
原始发表时间: 2020-03-11
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
✏️ 作者介绍:
黄伟,趋势科技(中国)资深研发工程师
趋势科技(TrendMicro)是一家全球领先的信息安全软件公司,专为全球软件厂商及个人用户提供安全解决方案。本文作者目前负责构建移动安全 APP 和开发基础设施。工作流程为爬取 Google play 等平台上的外部 APK (Android application package,即 Android 应用程序包),运用趋势科技的算法检测出携带病毒的 APK。使用 Milvus 在趋势科技 APK 库中对携带病毒的外部 APK 进行相似性检索。如发现外部携带病毒的 APK 与库中 APK 相似,需要及时通知企业与个人用户相关的病毒信息。
上述工作要求系统高效检索相似 APK。由于项目前期的 APK 样本数量不大,团队可以利用 SQL 语言在 MySQL 中进行 APK 相似性检索。但随着 APK 样本数量急剧增大,使用 MySQL 无法保证性能,因此团队开始探索新的解决方案。
Faiss
Facebook 于 2017 年发布了 Faiss 算法库。Faiss 能快速检索相似向量,还提供 IndexFlatL2、IndexFlatIP、HNSW、IVF 等多个索引,可以解决大部分相似性检索的问题。
但是 Faiss 只是一个基础算法库,存在如下问题:无法管理向量数据、不具备高可用性、缺乏监控手段、缺乏分布式方案、缺少各种语言版本的 SDK 等。
基于 Faiss 等近似最近邻搜索(Approximate Nearest Neighbor Search, ANN)算法库开发插件
行业内基于 Faiss、NMSLIB 等近似最邻近算法库开发了一些插件,例如以 Faiss、NMSLIB 作为底层库开发的 ES (Elasticsearch) 插件,如下图所示:
此类解决方案的优势在于无需额外写一套分布式代码。由于 ES 插件已经非常成熟,用户能够快速掌握提供 ES 的 DSL。一套 ES 能够同时检索文本和向量,而且支持标量字段过滤。
目前阿里、网易、亚马逊都采用此类解决方案。京东也基于 Faiss 开发了一套分布式系统 Vearch,但目前 Vearch 仍处于起步阶段且社区并不活跃。
此类解决方案的问题在于消耗内存大,且不易于性能调优。为获取最佳性能,需要进行 segment 合并。
Milvus
使用 C++ 语言开发的 Milvus 开源向量相似度搜索引擎在众多主流方案中脱颖而出。Milvus 与其他方案的对比情况如下图所示:
对比分析可知 Mlivus 性能好,具备以下优点:
趋势科技最终决定选择 Milvus 作为内部的向量检索组件。
目前趋势科技在 MySQL 中存储了千万级的 APK 样本数据,且每日增量达数十万。算法团队针对 APK 的不同部分抽取计算出其 Thash 特征值,用于相似性检索。团队还会利用不同的 Sha256 算法将 APK 视作二进制文件,根据字节流 hash 分别计算出多个 256 bit 长的 Sha256 哈希值,用于区分不同的 APK。不同 APK 的 Sha256 哈希值不同。每个 APK 的 Thash 特征值对应多个不同的 Sha256 哈希值。
简而言之,Sha256 哈希值仅用于区分不同 APK,而 Thash 特征值用于相似性检索。相似的 APK 可能会产生相同的 Thash 特征值,但 Sha256 哈希值不同。
目前,趋势科技需要开发一套系统,检索相似的 Thash 特征值,并返回此 Thash 特征值对应的多个 Sha256 哈希值,最终检索出相似的 APK。在此过程中,趋势科技需要开发存储和检索 Thash 特征值的功能。在 Milvus 的支持下,趋势科技团队只需将 Thash 特征值转化成二值型向量,并存储在 Milvus 中即可。
检索出相似向量后,团队还需要在 MySQL 中查询 Thash 特征值对应的多个 Sha256 哈希值。趋势科技在架构设计中增加了缓存 Redis 来存储 Thash 特征值和 Sha256 哈希值的映射,以减少查询时间。架构如下图所示:
Milvus 支持多种向量的距离计算方式和索引类型,如下图所示:
趋势科技将 Thash 转化成二值型向量存储在 Milvus 中。为配合业务方,趋势科技采用汉明距离计算不同向量的 ANN 距离。
据了解,Milvus 未来版本会增加 string 类型 ID。此功能的发布可以免去缓存 Redis,简化当前架构。
目前,趋势科技采用上云方案,很多任务都部署在 Kubernetes 上。为实现向量检索的高可用,我们选择了 Mishards——一个用 Python 开发的 Milvus 集群分片中间件,如下图所示:
趋势科技采用 AWS 提供 EFS (Elastic File System) 来存储实际的向量数据。这种存储和计算分离的的做法将成为趋势。此外,趋势科技可以借助 Kubernetes 启动多个读节点,并基于这些读节点创建 LoadBalancer 类型的服务,保证一个或多个节点无法使用时整个集群依旧可用。
最初,Milvus 的架构为单节点,而非贯穿始终的分布式系统。出于对一致性的考量,Milvus 目前只支持一个写节点。但在未来,分布式 Milvus 将改进这一问题。
Milvus 基于 Prometheus 搭建监控系统,使用开源的时序数据分析及可视化平台 Grafana 展示各项性能指标。
使用 Prometheus 监控、存储性能指标:
监控指标较全面,包括:
目前,趋势科技基于 Milvus 搭建的 ThashSearch 服务已上线数月。完整链路查询的平均延迟在 95 毫秒以内,具体表现如下图所示:
整体结果达到当初设计时制定的目标。数据导入速度也很快。导入300 万条192 维向量数据大约只需要 10 秒。
更多 Mlivus 用户案例
· 图形商标近似检索-知擎者的 Milvus 实践
· 基于语义向量的内容召回和短文本分类的错误查找-搜狐的 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
我来说两句