【数据库】 - ES 检索数据库
2025-01-07 09:27:24 0 举报
AI智能生成
【数据库】 - ES 检索数据库
作者其他创作
大纲/内容
ElasticSearch
es的场景
Elasticsearch(简称ES)是一个开源的分布式搜索和分析引擎,它提供了强大的全文搜索功能,可以快速地对大规模数据进行搜索、分析和可视化。
Elasticsearch中,查询是非常重要的操作,通过ES基于倒排索引可以从索引中检索出符合条件的文档数据。
检索核心逻辑
1.1 数据存储和索引构建
Elasticsearch中的每个文档都有一个ID以及与其相关的字段,字段值会通过索引进行存储。
在索引过程中,ES会将每个字段拆分成多个“词条”(terms),并存储这些词条与文档ID之间的映射。
倒排索引就是根据每个词条(term)反向查找包含该词条的文档ID集合。
Elasticsearch中的每个文档都有一个ID以及与其相关的字段,字段值会通过索引进行存储。
在索引过程中,ES会将每个字段拆分成多个“词条”(terms),并存储这些词条与文档ID之间的映射。
倒排索引就是根据每个词条(term)反向查找包含该词条的文档ID集合。
1.2 查询解析与执行
用户提交查询时,ES会解析查询并通过倒排索引查找相关的文档。
查询的执行通常分为两个阶段:
评分阶段:根据评分算法(如TF-IDF或BM25)计算每个文档的相关性得分,返回得分最高的文档。
用户提交查询时,ES会解析查询并通过倒排索引查找相关的文档。
查询的执行通常分为两个阶段:
评分阶段:根据评分算法(如TF-IDF或BM25)计算每个文档的相关性得分,返回得分最高的文档。
1.3 查询类型
标准查询:如match、term查询等,直接针对某些字段进行匹配。
复合查询:如bool查询,允许用户组合多个查询条件。
聚合查询:用于分析数据,如terms聚合、range聚合等。
标准查询:如match、term查询等,直接针对某些字段进行匹配。
复合查询:如bool查询,允许用户组合多个查询条件。
聚合查询:用于分析数据,如terms聚合、range聚合等。
1.4 查询优化
查询缓存:ES会缓存常见查询的结果,以提高查询性能。
分片和副本:数据被分为多个分片,查询时会并行在各个分片上执行,以加速查询过程。
查询缓存:ES会缓存常见查询的结果,以提高查询性能。
分片和副本:数据被分为多个分片,查询时会并行在各个分片上执行,以加速查询过程。
倒排索引
ES中 存储数据的基本单位是 index 索引,相当于mysql里的一张表。
ES中 数据以 docs 文档 的形式存储在index中,相当于一行数据。
每个文档docs包含多个字段,字段是文档的基本单位。
传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。
倒排索引 是通过分词策略,形成了词-文章的映射关系表,这种 词典+映射表 即为倒排索引。
倒排索引 是通过分词策略,形成了词-文章的映射关系表,这种 词典+映射表 即为倒排索引。
有了倒排索引,就能实现 O(1) 时间复杂度的效率检索文章了,极大的提高了检索效率。
es接收到一个文档后,进行字符 过滤->分词->归一化(停用词,大小写,单数和复数,相近词(相似词))
BKD树(K-D数和B+树)
es的分布式架构原理
1.核心思想就是在多个机器上启动多个es进程实例,组成一个集群。
2.创建一个索引,这个索引可以被分成多个shard(分片),每个shard存储一部分数据
3.shared分片也会有主分片primary副分片replica
4.shared主副分片均匀分布在各个机器上
5.数据都是写入到主分片,然后主分片同步写入到副分片上。读数据则可读取主分片或者副分片的数据。
6.如果某台机器进程宕机,master进程宕机,选举其他进程作为master,并且将宕机的进程里的主分片的副分片转为主分片。
7.宕机的进程好了以后,便不再是master 节点,里面的主分片parimary shard转为副分片 replica shard。
2.创建一个索引,这个索引可以被分成多个shard(分片),每个shard存储一部分数据
3.shared分片也会有主分片primary副分片replica
4.shared主副分片均匀分布在各个机器上
5.数据都是写入到主分片,然后主分片同步写入到副分片上。读数据则可读取主分片或者副分片的数据。
6.如果某台机器进程宕机,master进程宕机,选举其他进程作为master,并且将宕机的进程里的主分片的副分片转为主分片。
7.宕机的进程好了以后,便不再是master 节点,里面的主分片parimary shard转为副分片 replica shard。
es如何实现master选举
ZenDiscover模块负责
对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道的节点排一次序,然后选出第一个节点,暂且认为它是master节点。
如果对某个节点的投票数达到一定值并且该节点自己也选举自己,那这个节点就是master
写数据过程
基本写入流程
1.首先客户端随便选择一个节点node去写,此时这个节点称为协调节点
2.协调节点对写的数据进行hash,确定这个数据属于哪个shard(分片)
3.协调节点对数据进行路由,把请求发到所属主分片 pimary shard 的node上去
4.主节点同步数据到从节点,primary, replicate sharding 都写完了,那么协调节点会返回写成功的响应给客户端。
1.首先客户端随便选择一个节点node去写,此时这个节点称为协调节点
2.协调节点对写的数据进行hash,确定这个数据属于哪个shard(分片)
3.协调节点对数据进行路由,把请求发到所属主分片 pimary shard 的node上去
4.主节点同步数据到从节点,primary, replicate sharding 都写完了,那么协调节点会返回写成功的响应给客户端。
primary shard存储底层原理
(refresh,flush,translog,merge)
(refresh,flush,translog,merge)
1.数据写入shard的时候,先写入内存buffer里,同时它会写入到translog日志文件里。
(此时如果客户端要查询数据是查不到的)
(此时如果客户端要查询数据是查不到的)
2.如果buffer快满了或者每隔一段(默认1s)时间,es会把内存buffer中的数据 refresh刷到到一个新的segment file,每隔1秒产生一个新的segment文件
但是如果buffer里面此时没有数据,就不会执行refresh。
数据在写入segment file之后,便存储好了这1s的数据,同时就建立好倒排索引了。
但是如果buffer里面此时没有数据,就不会执行refresh。
数据在写入segment file之后,便存储好了这1s的数据,同时就建立好倒排索引了。
3.操作系统中,磁盘文件其实都有一个东西,叫os cache,操作系统缓存。
就是说数据写入磁盘文件之前,会先进入os cache。
只要buffer里的数据写入到了os cache里面,客户端就能搜索到这部分数据了。
就是说数据写入磁盘文件之前,会先进入os cache。
只要buffer里的数据写入到了os cache里面,客户端就能搜索到这部分数据了。
为什么es是准实时的?
因为写入1s后才会刷到os cache里。写入到os cache里之后,buffer里的数据就会清空,translog会保留。
translog也是磁盘文件,所以也是先写入os cache里的,默认5秒刷新数据到磁盘中
4.当translog不断变大,大到一定阈值,或者30分钟 就会触发commit(flush)操作。
(默认30分钟会自动执行)整个commit过程叫flush,手动根据es api也可以执行flush。
commit操作: 1.写commit point 2.将os cache fsync强刷到磁盘上去 3.清空translog日志文件
(默认30分钟会自动执行)整个commit过程叫flush,手动根据es api也可以执行flush。
commit操作: 1.写commit point 2.将os cache fsync强刷到磁盘上去 3.清空translog日志文件
- 1.将buffer里的数据都写入os cache里面去,然后清空buffer。
- 2.将一个commit point文件写入到磁盘,里面标示着之前写入的所有segment file,但是数据还是在os cache中。
- 3.把os cache缓冲的所有的数据都fsync到磁盘上面的每个segment file中去。
- 4.刷完以后会删除并新建translog
translog日志作用:
数据一般都是存储在buffer或者os cache内存里,一旦服务器宕机重启,内存中的数据就会丢失。
所以将es操作日志存储在translog里,es重启时通过translog将数据恢复到buffer及os cache中。
数据一般都是存储在buffer或者os cache内存里,一旦服务器宕机重启,内存中的数据就会丢失。
所以将es操作日志存储在translog里,es重启时通过translog将数据恢复到buffer及os cache中。
删除数据写入.del文件中标识一下这个数据被删除了,里面某个doc标识为deleted状态
客户端搜索某条数据,一旦发现这条数据在.del文件中找到这条数据被标识成删除状态了,就不会搜索出来。
客户端搜索某条数据,一旦发现这条数据在.del文件中找到这条数据被标识成删除状态了,就不会搜索出来。
在新的文档被创建时,Elasticsearch会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。
由于每隔1s生成一个segment file,当文件多到一定程度的时候,es会merge成一个大的segment file,然后删除旧的文件
在merge的时候,会看一下如果某条数据在.del文件中标识为删除,那么merge后的新文件里这条数据就没了(物理删除)
在merge的时候,会看一下如果某条数据在.del文件中标识为删除,那么merge后的新文件里这条数据就没了(物理删除)
丢失数据情况
默认5s才会将 translog 从os cache写入到磁盘文件中,所以会有5s数据丢失的可能
解决:可以设置个参数,官方文档。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog。
但是会导致写性能,写入吞吐量下降一个数量级。本来1s可以写入2000条,现在1s钟可能只能写200条。
但是会导致写性能,写入吞吐量下降一个数量级。本来1s可以写入2000条,现在1s钟可能只能写200条。
读数据过程
查询流程原理:
客户端发送一个请求到任意一个node,node成为协调节点。
请求转发到对应相关的所有shards,此时会使用随机轮询算法,在primary shard及所有replica shard中实现请求负载均衡。
请求节点 query phase 每个 shard 将自己的搜索结果(其实就是一些 doc id)返回给协调节点(coordinate node)
协调节点 fetch phase 进行数据的合并,排序,分页等操作。根据doc id去各个节点上拉取实际的document数据,返回 document 给客户端。
客户端发送一个请求到任意一个node,node成为协调节点。
请求转发到对应相关的所有shards,此时会使用随机轮询算法,在primary shard及所有replica shard中实现请求负载均衡。
请求节点 query phase 每个 shard 将自己的搜索结果(其实就是一些 doc id)返回给协调节点(coordinate node)
协调节点 fetch phase 进行数据的合并,排序,分页等操作。根据doc id去各个节点上拉取实际的document数据,返回 document 给客户端。
一条数据精准查询
数据写入了某个document,这个document会自动给你分配一个全局唯一的id (doc id)
同时也是根据doc id进行hash路由到对应的primary shard上去的。也可以手动指定doc id,比如用户id,订单id。
同时也是根据doc id进行hash路由到对应的primary shard上去的。也可以手动指定doc id,比如用户id,订单id。
Match Query:匹配查询
用于在指定字段中搜索包含指定关键词的文档。
{
"query": {
"match": {
"content": "Elasticsearch"
}
}
}
"query": {
"match": {
"content": "Elasticsearch"
}
}
}
Match Phrase Query:短语匹配查询
用于匹配包含指定短语的文档。
{
"query": {
"match_phrase": {
"content": "Elasticsearch tutorial"
}
}
}
"query": {
"match_phrase": {
"content": "Elasticsearch tutorial"
}
}
}
Term Query:精确匹配
用于精确匹配指定字段中的值。
{
"query": {
"term": {
"category": "Technology"
}
}
}
"query": {
"term": {
"category": "Technology"
}
}
}
Bool Query:布尔查询
用于组合多个查询条件,支持must、should、must_not等逻辑操作符。
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" } },
{ "term": { "category": "Technology" } }
]
}
}
}
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" } },
{ "term": { "category": "Technology" } }
]
}
}
}
案例
Range Query:范围查询
用于匹配指定字段中符合范围条件的值。
{
"query": {
"range": {
"price": {
"gte": 100,
"lte": 500
}
}
}
}
"query": {
"range": {
"price": {
"gte": 100,
"lte": 500
}
}
}
}
案例
es查询(url方式)
目标 Index
/_search 在所有索引上检索
/search1/_search 在search1当前索引上检索
/search1,search2/_search 在search1,search2索引上检索
/search*/_search 在search开头的索引上检索
/g*,user*/_search 在g和user开头的索引上检索
查询所有文档:
GET http://localhost:9200/_search
查询 指定索引 指定类型 的文档:
GET http://localhost:9200/index/type/_search
http://es_ip_address:9200/doc-202403/docs/_search
这个URL将返回doc-202403索引中所有docs文档类型的搜索结果。
泛查询 所有字段 值为"SZ000001"的文档:
http://es_ip_address:9200/doc-202403/docs/_search?q=SZ000001
这个URL将返回 doc-202403 索引中特定字段的值为"SZ000001"的文档的搜索结果。
查询多字段字段的值为"XXX"的文档:
这个URL将返回doc-202403索引中特定字段的值为"SZ000001" | "2022-01-01"的文档的搜索结果。
http://es_ip_address:9200/doc-202403/docs/_search?q=field1:(SZ000001 and 2024-03-01)
这个URL将返回doc-202403索引中特定字段的值为"SZ000001" | "2022-01-01"的文档的搜索结果。
查询特定字段的值包含"SZ"的文档:
这个URL将返回doc-202403索引中特定字段的值包含"SZ"的文档的搜索结果。通配符"*"表示匹配任意字符。
http://es_ip_address:9200/doc-202403/docs/_search?q=field1:*SZ
{ "query": { "bool": { "must": { "match": { "field1": "SZ" } } } } }
这个URL将返回doc-202403索引中特定字段的值包含"SZ"的文档的搜索结果。通配符"*"表示匹配任意字符。
查询后排序
&sort=pubdate:desc
召回最大数量
http://10.15.108.88:9200/doc-202404/docs/_search?q=category:(%E6%9C%8B%E5%8F%8B%E5%9C%88%20and%20%E5%85%AC%E5%8F%B8%E5%85%AC%E5%91%8A)&sort=pubdate:desc&size=100
es调优
es生产集群的部署架构是什么?
es生产集群我们部署了5台机器,每台机器是6核64G的,集群总内存是320G
es集群的日增量数据大概3000万条,每天日增量数据大概是1G
每个索引的数据量大概有多少?分片情况?
目前线上有5个索引(结合业务来),每个索引的数据量大概是20G。我们每个索引分配的是8个shard,比默认的5个shard多了3个shard。
每个月份有1个索引对应大智慧APP。每个索引在测试中3个shard,在生成中8给shard。
十亿数据,第一次5~10s,第二次就快了
es性能优化是没有什么银弹的。不要期待随手调一个参数,就可以万能的应对所有性能慢的场景。
有些场景换个参数,或者调整个语法就能搞定,但是绝对不是所有场景都是这样的。
有些场景换个参数,或者调整个语法就能搞定,但是绝对不是所有场景都是这样的。
1.性能优化杀手锏 filesystem cache
第一次从磁盘查出数据会存到内存的fileSystem Cache,es搜索引擎严重依赖底层的os cache。
如果走磁盘一般肯定上秒, 但是如果走filesystem cache,走纯内存,那么基本上就是毫秒级的。从几毫秒到几百毫秒不等。
1.如果要es性能好,最佳情况下,机器的内存要容纳你总数据量的一半。
比如es中要存储1T数据,那么你多台机器留给filesystem cache的内存要加起来综合到512g。
2.往es里存少量的数据,比如30个字段只用到了三个就存三个。让内存留给filesystem cache的大小跟数据量一致。性能就会非常高,一般可以在1s以内
3.其他字段的数据可以存在mysql里面,建议采用es+hbase
hbase的特点就是适用于海量数据的在线存储,就是可以对hbase写入海量数据,不要做复杂的搜索,就是做很简单的一些根据id或者范围查询的操作
hbase的特点就是适用于海量数据的在线存储,就是可以对hbase写入海量数据,不要做复杂的搜索,就是做很简单的一些根据id或者范围查询的操作
总结:最好写入es数据小于 fileSystem cache内存大小
2.缓存预热
假如说,按照上面的方案去做了,es集群中每个机器写入的数据量还是超过了filesystem cache的一倍,60g数据,filesystem cache就30g,还有30g在磁盘中
可以自己后台搞个系统,每隔一会就去搜索一下热数据,刷到filesystem cache中。后面用户搜索热数据就是直接去内存里查了
3.冷热分离
1.将大量不搜索的字段,拆分到别的存储引擎里去,这个类似于mysql分库分表的垂直拆分。
2.可以做类似mysql水平拆分,就是说将大量的访问很少,频率很低的数据,单独写一个索引,然后将访问很频繁的热数据单独写一个索引。
比如:6台机器,2个索引,一个放冷数据,一个放热数据,每个索引3个shard
3台放热数据index;3台放冷数据index;
这样的话,大量的时候是在访问热数据,热数据可能就占总数据的10%,此时数据量很少,几乎能确保数据全部保留在filesystem cache
对于冷数据而言,是在别的index里面,跟热数据都不在同一个index机器上,如果有人访问冷数据,在磁盘上,此时性能差点就差点了。
3台放热数据index;3台放冷数据index;
这样的话,大量的时候是在访问热数据,热数据可能就占总数据的10%,此时数据量很少,几乎能确保数据全部保留在filesystem cache
对于冷数据而言,是在别的index里面,跟热数据都不在同一个index机器上,如果有人访问冷数据,在磁盘上,此时性能差点就差点了。
子主题
4.document模型设计
es里的复杂的关联查询,复杂的查询语法,尽量别用,一旦用了性能一般都不太好。
所以要好好设计es里的数据模型。
所以要好好设计es里的数据模型。
写入es的java系统里,就完成关联,将关联好的数据直接写入es中,搜索的时候就不需要利用es的搜索语法
比如 mysql两个表需要join
在写入es的时候java直接将join好的数据写入es,不用es的join语法查询
在写入es的时候java直接将join好的数据写入es,不用es的join语法查询
5.分页性能优化
es分页性能比较坑
假设每页10条数据,现在要查询第100页,实际上是会把每个shard上存储前1000条数据都查到一个协调节点上,如果你有5个shard,那么就有5000条数据,接着协调节点对这5000条数据进行一些合并,处理。再获取到最终第100页的10条数据。
翻页的时候,翻的越深,每个shard返回的数据就越多,协调节点处理数据时间越长,非常坑爹。
假设每页10条数据,现在要查询第100页,实际上是会把每个shard上存储前1000条数据都查到一个协调节点上,如果你有5个shard,那么就有5000条数据,接着协调节点对这5000条数据进行一些合并,处理。再获取到最终第100页的10条数据。
翻页的时候,翻的越深,每个shard返回的数据就越多,协调节点处理数据时间越长,非常坑爹。
1.不允许深度分页/默认深度分页性能很差。
系统不允许翻那么深的页,或者告诉产品默认翻的越深性能越差
2.类似于app里的推荐商品或者微博,不断下拉出现一页一页的。
可以用scroll api来进行处理
scroll会一次性给你生成所有数据的快照,每次翻页通过游标移动,获取下一页这样子,性能会比上面说的那种分页性能高很多。
无论分多少页,性能基本上都是毫秒级的。
因为scroll api 只能一页一页往后翻,不允许先第十页再120页。
可以用scroll api来进行处理
scroll会一次性给你生成所有数据的快照,每次翻页通过游标移动,获取下一页这样子,性能会比上面说的那种分页性能高很多。
无论分多少页,性能基本上都是毫秒级的。
因为scroll api 只能一页一页往后翻,不允许先第十页再120页。
es高维数据检索
高维信息(如文本嵌入、图像或其他结构化高维数据),Elasticsearch 通过结合: 向量相似度搜索, 分布式索引, 缓存
向量相似度搜索:利用 L2 距离、余弦相似性等算法计算对象在向量空间中的距离,从而评估数据点的相似度。
分布式索引:数据和查询任务可以通过自动路由分配到多个节点,这不仅可以并行执行操作,还提高了容错能力。
二级存储索引:为优化高维向量的搜索速度和内存消耗,Esper 提供了使用预计算或近似数据结构(如树状聚类)的二级索引来加速查询的过程。
es的Scoll设计
Scroll API 是一个用于高效分页遍历大量数据的机制,,它的核心设计理念是通过保持一个查询上下文
查询上下文保持: Scroll API 的核心设计是通过持久化一个“scroll上下文”,这个上下文在进行滚动查询时被不断复用。查询结果会被保留在该上下文中,直到你显式地终止滚动,或者滚动超时。
时间限定: 每次滚动查询都会给定一个滚动的时间(scroll)。在指定的时间内,查询会保持有效,查询上下文不会被清除。比如,scroll=1m 表示上下文会在1分钟内有效。
滚动查询返回的ID: 每次查询结果中,ES会返回一个“scroll ID”,这个ID用于下一次滚动查询,以便保持查询状态。每次执行滚动查询时,都会返回新的结果和新的scroll ID,继续查询直到获取完所有数据。
非分页处理: 滚动查询并不通过传统的from和size进行分页,而是通过scroll ID来维持游标状态并批量返回固定数量的文档(由size指定),不需要进行复杂的分页计算,因此能避免分页时的性能瓶颈。
helpers.scan python的使用
# 使用helpers.scan进行扫描
for doc in helpers.scan(es, query=query, index="your_index"):
print(doc["_source"])
query: 查询条件,通常是一个简单的查询,如match_all。
index: 要查询的索引。
scroll: 设置滚动的时间长度,默认为10s。
size: 每次返回文档的数量。
for doc in helpers.scan(es, query=query, index="your_index"):
print(doc["_source"])
query: 查询条件,通常是一个简单的查询,如match_all。
index: 要查询的索引。
scroll: 设置滚动的时间长度,默认为10s。
size: 每次返回文档的数量。
helpers.scan与传统查询的对比
传统分页:常见的分页方式是通过from和size来分页。当数据量大时,因为随着from的增大,ES需要跳过更多的文档,导致查询效率下降。
helpers.scan(滚动查询):滚动查询不依赖from和size,而是返回一个游标(scroll id)来维持查询的上下文。遍历大量文档时非常高效。
es中scoll查询问题
Scroll API 主要用于需要遍历整个数据集的场景,例如批量导出数据、ETL处理等。它并不像普通的查询那样每次都重新计算结果。
Scroll API 在查询过程中,数据集保持一致,不会因为其他操作(如写入、删除等)导致查询结果变化。
Scroll API是有超时限制的。每次滚动查询都需要指定一个scroll参数来定义滚动的持续时间(如scroll=1m,表示1分钟内滚动查询有效)。如果在指定的时间窗口内没有进行滚动请求,查询上下文将会被自动清除,导致scroll ID失效,从而发生超时。
Milvus
基本介绍
Milvus 是一个开源的向量数据库,针对机器学习和人工智能应用场景中的大规模向量数据(如图像、文本和视频特征向量)的高效存储和检索。
Milvus 是一款高性能的向量数据库系统,旨在为 AI 应用提供大规模数据存储、实时查询和近似查找服务。
Milvus 是一个开源的向量数据库,针对机器学习和人工智能应用场景中的大规模向量数据(如图像、文本和视频特征向量)的高效存储和检索。
应用场景与案例
大规模数据检索
图像检索
商品图片搜索
人脸识别
文本检索
文档搜索
新闻推荐
智能推荐系统
商品推荐
个性化推荐
关联推荐
内容推荐
新闻推送
视频推荐
整体架构设计
系统层次结构
计算层设计
向量索引构建
查询优化算法
实时计算能力
存储层设计
元数据管理
数据分片策略
分布式存储机制
协调层设计
集群管理
负载均衡策略
故障恢复机制
数据流动路径
数据写入流程
客户端请求接收
数据预处理
存储与索引构建
数据查询流程
查询请求解析
索引匹配与筛选
结果聚合与返回
数据删除流程
删除标记设置
垃圾数据清理
索引更新
Milvus架构
1. 客户端接口层(API 层)
提供多种编程语言的 SDK,例如 Python、Java、C++ 等,用于应用程序与 Milvus 交互。
支持常见的操作,如插入向量、删除向量、向量搜索和集合管理。
支持 SQL 和 Milvus 自定义的查询语言。
支持常见的操作,如插入向量、删除向量、向量搜索和集合管理。
支持 SQL 和 Milvus 自定义的查询语言。
2. 计算引擎(Query Node 和 Index Node)
Query Node:
负责处理实时搜索请求,如近邻搜索(ANN,Approximate Nearest Neighbor Search)和过滤操作。
支持多种检索算法,例如 IVF(Inverted File Index)、HNSW(Hierarchical Navigable Small World)、Flat 等。
动态分配计算资源,优化查询性能。
Index Node:
负责构建索引,支持多种索引类型以适应不同场景需求。
3. 存储层(Data Node 和 Storage Layer)
数据持久化存储在支持对象存储的系统中,例如 S3、Ceph、HDFS 等。
支持冷热数据分离策略,优化存储成本。
支持冷热数据分离策略,优化存储成本。
元数据存储(Meta Store):
通过 etcd 或其他分布式系统管理元数据。
记录集合、分片、副本、向量索引等信息。
通过 etcd 或其他分布式系统管理元数据。
记录集合、分片、副本、向量索引等信息。
4. 集群管理层
协调器:
管理集群中的节点资源分配。
负责任务调度和负载均衡。
管理集群中的节点资源分配。
负责任务调度和负载均衡。
监控和故障恢复:
内置 Prometheus 和 Grafana 支持,用于实时监控。
提供高可用性和故障自动恢复机制。
内置 Prometheus 和 Grafana 支持,用于实时监控。
提供高可用性和故障自动恢复机制。
Milvus 的工作原理
1. 数据插入
用户通过 API 将高维向量插入到 Milvus 集合中。
向量数据先存入内存中的缓冲区(Buffer),随后异步写入持久化存储。
数据会被分区、分片,并可以根据用户定义的策略构建索引。
向量数据先存入内存中的缓冲区(Buffer),随后异步写入持久化存储。
数据会被分区、分片,并可以根据用户定义的策略构建索引。
2. 索引构建
Milvus 提供多种索引算法,支持用户根据数据特点选择合适的索引
Milvus 索引在后台异步构建,优化了数据插入和索引构建的效率。
IVF:适用于海量数据的近似搜索。
HNSW:适用于小规模数据的高精度搜索。
Flat:适用于需要精确搜索的场景,但速度较慢。
HNSW:适用于小规模数据的高精度搜索。
Flat:适用于需要精确搜索的场景,但速度较慢。
3. 向量搜索
支持多种检索模式:
近邻搜索(ANN):快速找到与查询向量最接近的向量。
通过索引结构快速找到查询向量的近似邻居。
提供 Top-K 搜索结果,支持按距离排序。
Hybrid Search(混合搜索):结合属性过滤条件执行高效的向量检索。
结合过滤条件的搜索,例如“查找与向量A相似且满足某些属性条件的数据”。
查询流程:
查询请求由 API 接口接收,传递到 Query Node。
Query Node 根据元数据找到相应的分区和索引。
使用索引加速检索,并结合过滤条件返回结果。
查询请求由 API 接口接收,传递到 Query Node。
Query Node 根据元数据找到相应的分区和索引。
使用索引加速检索,并结合过滤条件返回结果。
4. 高可用和扩展性
高可用性:
通过 Raft 协议或其他分布式一致性算法确保元数据的一致性。
数据分片和副本机制保障了容灾能力。
通过 Raft 协议或其他分布式一致性算法确保元数据的一致性。
数据分片和副本机制保障了容灾能力。
水平扩展:
节点可动态增加或减少,支持弹性扩展。
基于计算和存储分离设计,轻松处理 PB 级数据规模。
节点可动态增加或减少,支持弹性扩展。
基于计算和存储分离设计,轻松处理 PB 级数据规模。
Milvus 检索召回策略
多种距离算法:支持余弦相似性、欧式距离等多种向量间相似度计算,以满足各种应用需求。
内存优化索引:Milvus 支持如 IVF(Induction of Vector)和 Faiss 索引,这些索引能够在保证搜索精度的同时尽量节省内存资源。
Milvus 效率
高效存储:通过冷热分离、分片存储和异步索引降低存储开销,提高效率。
并行计算能力:利用本地内存和计算资源进行高效的向量化查询和聚合计算,通过并行处理加速搜索过程。
检索加速: Milvus利用了分块、近似近邻(ANNS)、空间索引等技术以减少查询响应时间,对数百万级/千万级的数据规模
利用 GPU 资源
对比ES
Elasticsearch 和 Milvus 在设计上有不同侧重点。Elasticsearch 更侧重于文本搜索和多样化的数据索引
Milvus 是针对大型向量数据设计的,特别强调高维数据的存储和查询。
实践操作中考虑: 性能要求、数据复杂性、集成的现有系统等,确保最佳的检索召回效果
0 条评论
下一页