小伙伴关心的问题:milvus 35 1.4,milvus 25 1.4,本文通过数据整理汇集了milvus 35 1.4,milvus 25 1.4相关信息,下面一起看看。

milvus 35 1.4,milvus 25 1.4

Milvus社区发展很快,年初的时候刚发布了Milvus2.0GA版本,在年末之际,Milvus已经发布到了2.2.2版本。这期间经历了2.1.0,2.1.1,2.1.2,2.1.4,2.2.0,2.2.1这些版本,每一个版本都凝聚了社区几百位贡献者的心血,感谢每一位在背后为Milvus默默付出的同学。在这快速发展的一年中,我发现社区里有很多朋友对Milvus的认识还存在一些误区,今天这篇文章就来聊聊使用Milvus的十大常见误区,快来看看这些误区你以前有踩过吗?

误区1:GPU一定比CPU快?

社区里面我经常被问到的一个问题是,“Milvus什么时候可以支持GPU?”。这时候我一般会顺势问一句,“你们为什么需要使用GPU呢?”。得到的答案经常是“使用GPU肯定比CPU算得快”。诚然,GPU上的计算单元会比CPU多很多,在做并行计算上很有优势。但是GPU的显存容量目前是不能和CPU的内存相比的,经常会出现向量数据过多,无法全部将其加载到显存的情况。这时候,计算过程中将不可避免地进行内存数据和显存数据的置换,由于数据置换时间的存在,总体的搜索速度也就不是那么快了。可以看到,当数据量不大可以全部加载到显存的时候,GPU搜索是有可能比CPU更快,但是在数据量更大无法全部加载到显存的时候,情况就不一定了。

关于搜索性能,Milvus团队从2.1版本开始就一直在持续得做优化,到今天的2.2.2版本,社区的Benchmark已经可以在开源的Sift1M数据集上达到1w+QPS,并且latency控制在几十毫秒。所以有时候性能不好可能是咱们自己的使用方式不对,没有把Milvus的潜能全部释放出来。这里我推荐大家日后遇到性能问题的时候,看一下Milvus maintainer小凡写的文章《浅谈如何优化 Milvus 性能》,里面讲了很多做性能优化的思路,应该可以帮助大家。

误区2: num_entities()的结果真得准吗?

“为什么我删了向量之后, *** 的向量条数还是没变化?num_entities()的结果怎么不准?” 。要解答这个问题,就需要给大家介绍一下Milvus里面的删除原理。当我们在调用delete()接口的时候,milvus内部其实不会真正马上将磁盘上segment里的数据做清除,而是通过标记删除的方式,将对应的entity打上删除标记,下次搜索的时候直接将其过滤掉。而 num_entities()接口,它的准确含义应该为, the number of insert entities,只要通过insert()接口插入进来的entity,它都可以统计到,即使这个entity后续被打上了删除的标记。

所以现在的num_entities()获得的向量条数会包含删除了的向量,这个是by design的,不过后面可以建议在Milvus的文档里面加上一些说明。至于真正准确的count()接口,可以预料到将是一个比较重的接口,社区可能会在明年提供给大家这个选项。

误区3: Milvus的主键(primary key)会自动去重?

使用过Oracle、MySql等传统关系型数据库的朋友都清楚,当你插入数据的时候,如果主键重复了,是不允许 *** 入的。因为Milvus里面也有主键(primary key)的概念,所以大家会很自然地认为在插入数据的时候,Milvus也不会允许重复主键的数据 *** 入,也会自动做主键去重的。但是事实并非如此,由于一些实现成本的原因,主键去重的功能目前还没有在milvus里支持的,现在是可以插入重复主键的数据。这一点也算是Milvus和传统关系型数据库差别比较大的一点,大家需要格外注意。未来,随着Milvus发展得越来越成熟,这些功能相信会逐步补齐。

误区4: 删完 *** 之后,数据会立即被清理?

对于不想要的 *** ,我们通常会选择删除,并希望这个 *** 的数据也能立即从磁盘上清理掉,释放出磁盘的可用空间。基于这样的期待,很多朋友认为Milvus里面,删完 *** 之后,数据也会立即被清理。实则不然,Milvus里面有一个叫做时间旅行的功能,为了在大家误删数据的时候能够有后悔药,Milvus在删完 *** 之后不会立即将数据从磁盘上清除,而是需要再等待一段时间后才真正清理磁盘上的数据。Milvus里面控制数据清理时间的是datacoord下的gc相关的参数,默认是保留一天再清除数据。

```dataCoord:gc:interval:3600# gc interval in second *** issingTolerance:86400# file meta missing tolerance duration in seconds, 60*24dropTolerance:86400# file belongs to dropped entity tolerance duration in seconds, 60*24```

误区5: docker-compose也可以部署一个真正生产可用的Milvus分布式集群。

docker-compose是社区提供的一种部署Milvus分布式集群的方式。由于它使用起来很简单,很多小伙伴最开始的部署Milvus的方式都会选择docker-compose。到后来,有些朋友会觉得在生产环境中用docker-compose部署一个Milvus分布式集群也是可以的。这其实也是一个误区,Milvus虽然提供了docker-compose部署分布式的方案,但是这个方案只是适用于在测试环境中对milvus的功能进行快速验证。真正上生产环境,还是需要使用k8s的方式来部署。主要有这几点原因:一是docker-compose不能方便地扩缩容节点,当数据量增加时对集群扩容是一件麻烦的事情;二是docker-compose虽然能把milvus里的各个组件都启动起来,但是当其中某个组件挂掉后,它不能像k8s那样帮助你自动重启恢复,容易引发故障。所以,使用k8s部署Milvus才是生产上的最佳实践,还在生产环境里面使用docker-compose部署的朋友,最好去升级一下。

误区6: querynode越多,搜得越快;datanode越多,插得越快。

初看这句话好像说得很正确,但是仔细去分析,会发现它根本经不起推敲。先说query,当你的数据量很大,现在已有的这些querynode节点已经满负荷运载,那么此时增加querynode的数量,确实可以分担已有querynode的压力,搜索速度确实也会变快。但是当你的数据量并不大,querynode并没有达到瓶颈的时候呢?就比如你只有20w的数据,milvus里面只有一个segment的时候,此时你增加再多的querynode也是用不起来的。在这种情况下,通过调节索引或者增加有负载的那个querynode的CPU核数,才有可能使搜索速度更快。

再说datanode,因为datanode是负责数据插入的,所以有些小伙伴会想当然认为datanode的数目越多,插入速度也就越快。其实原理和前面讲的query类似,当你的datanode数目不断增加,多于创建 *** 时的shard数目时,部分datanode可能就无法获得负载。所以,一般当datanode的数目等于 *** 的shard数目时,可以达到最佳的插入性能,datanode数量过多并不一定能提高插入速度。

误区7: Milvus可以用做图数据库来帮你找关系。

这个也是一些刚接触Milvus不久的朋友经常踩到的一个误区。可能是因为Milvus的一个最典型的应用是以图搜图,所以不少新朋友认为Milvus是一个图数据库,可以用来找数据之间的关系。实际上,Milvus是一个向量数据库,它主要是用来存向量数据并且做向量相关的增删改查。因为图片可以通过深度学习模型转换成特征向量,这些向量可以存储到Milvus里面做检索,所以Milvus可以间接地实现图片的相似检索。而图数据库(Graph Database)是指以图表示、存储和查询数据的一类数据库。图数据库里的“图”,与图片、图形、图表等没有关系,而是基于数学领域的“图论”概念,通常用来描述某些事物之间的某种特定关系。所以这两者之间差别还是很大的,大家后面可不要再搞混了。

误区8: 消息系统是Milvus的系统骨架,数据的增删改查操作都需要走消息系统。

Milvus依赖Pulsar/Kafka这样的消息系统来作为整个系统的骨架,在Milvus2.1.0之前,其实上面这句话是对的,Milvus的所有DML操作都需要走消息系统。但是,后面我们逐渐发现数据查询操作是一个对延时十分敏感的操作,数据查询走消息系统,整个链路的开销肯定居高难下。这对于Milvus这种读操作十分频繁并且性能要求严格的数据库系统来说是不能接受的。所以,在Milvus2.1.0之后,社区对读链路做了重构,Proxy对于搜索请求会直接发送RPC请求给querynode,然后querynode计算完结果也直接通过RPC请求返回给Proxy。整个搜索链路不会再经过消息系统,从而极大地提升系统的搜索性能。

误区9: 为了保证新插入的数据建上索引并被搜到,每次插入后都要调用create_index()和load()接口。

很多小伙伴为了保险,每次插入完数据后,都会调用一次create_index()和load()接口,从而来确保新插入的数据能够被建上索引同时还能被加载到内存中。其实大可不必。首先来说create_index(),这个接口使用的时候,内部有一个限制。只有当一个segment被sealed了并且该segment里的向量条数超过了1024条之后,那么调用create_index的时候才能顺利建上索引。当一个segment里的向量条数过少时,暴搜已经很快了,再建索引也没有明显的效果。另外,更重要的一点是,当一个segment被sealed了并且该segment里的向量条数超过了1024条,只要你曾经给 *** 建过索引,即使你现在不去显示调用create_index()的接口,那么这时候系统也会自动给这个segment建索引。load()这个接口也是类似的,只要你曾经调用过load(),那么后续你新插入的数据都会自动load到内存中的,不用担心新插入的数据搜不到。

误区10: 建索引一定比不建索引搜得更快。

这句话听起来感觉再正确不过了,在大多数情况下这句话也都是对的,但是凡事都是有例外的。Milvus在一些标量过滤的场景中,假如过滤之后的结果非常稀疏,符合条件的entity只有一两个,那么此时再去走索引(比如,HNSW图索引)做向量检索的时候,很可能内部在搜索多次都无法找到符合条件的结果,从而需要不断扩大搜索深度。最终整体的搜索性能可能比暴搜都还要慢。

关于Milvus的十大误区今天就先盘点到这里,后面发现有新的误区出现,我也会继续更新。最后,在即将到来的新的一年里,祝愿Milvus社区发展得越来越好,有越来越多的朋友在工作中把Milvus用起来!

更多milvus 35 1.4,milvus 25 1.4相关信息请关注本站,本文仅仅做为展示!