产品常见问题解答
Milvus 的价格是多少?
Milvus 是一个完全免费的开源项目。
在生产或分发 Milvus 时,请遵守 Apache 许可证 2.0。
负责 Milvus 的公司 Zilliz 还为那些不想构建和维护自己的分布式实例的用户提供了一个完全托管的云版本平台。Zilliz Cloud 自动维护数据可靠性,并允许用户按实际使用量付费。
Milvus 是否支持非 x86 架构?
Milvus 无法安装或在非 x86 平台上运行。
您的 CPU 必须支持以下指令集之一才能运行 Milvus:SSE4.2、AVX、AVX2、AVX512。这些都是专为 x86 架构设计的 SIMD 指令集。
Milvus 能处理的最大数据集大小是多少?
从理论上讲,Milvus 能处理的最大数据集大小取决于其运行的硬件,具体来说是系统内存和存储:
- Milvus 在运行查询之前将所有指定的集合和分区加载到内存中。因此,内存大小决定了 Milvus 可以查询的数据量的最大值。
- 当向 Milvus 添加新实体和与集合相关的模式(目前仅支持 MinIO 进行数据持久化)时,系统存储确定了可插入数据的最大允许大小。
Milvus 将数据存储在哪里?
Milvus 处理两种类型的数据,即插入数据和元数据。
插入数据,包括向量数据、标量数据和特定于集合的模式,以增量日志的形式存储在持久性存储中。Milvus 支持多个对象存储后端,包括 MinIO、AWS S3、Google Cloud Storage(GCS)、Azure Blob Storage、阿里云 OSS 和 腾讯云对象存储(COS)。
元数据是 在 Milvus 中生成的。每个 Milvus 模块都有自己的元数据,这些元数据存储在 etcd 中。
为什么 etcd 中没有向量数据?
etcd 存储 Milvus 模块的元数据;MinIO 存储实体。
Milvus 是否支持同时插入和搜索数据?
是的。插入操作和查询操作由两个相互独立的模块处理。从客户端的角度来看,当插入的数据进入消息队列时,插入操作就完成了。然而,在加载到查询节点之前,插入的数据是无法被搜索的。如果段的大小未达到构建索引的阈值(默认为512 MB),Milvus会采用蛮力搜索,查询性能可能会降低。
在Milvus中可以插入具有重复主键的向量吗?
可以。Milvus不会检查向量主键是否重复。
当插入具有重复主键的向量时,Milvus会将其视为更新操作吗?
不会。Milvus目前不支持更新操作,也不会检查实体主键是否重复。您需要确保实体主键是唯一的,如果不是,Milvus可能会包含具有重复主键的多个实体。
如果出现这种情况,查询时将返回哪个数据副本是一个未知行为。这个限制将在未来的版本中修复。
自定义实体主键的最大长度是多少?
实体主键必须是非负64位整数。
每次插入操作可以添加的数据量的最大值是多少?
插入操作的大小不能超过1,024 MB。这是gRPC强加的限制。
集合大小是否会影响在特定分区搜索时的 查询性能?
不会。如果指定了搜索的分区,Milvus只会搜索指定的分区。
当为搜索指定分区时,Milvus是否会加载整个集合?
不会。Milvus的行为各不相同。在搜索之前必须将数据加载到内存中。
- 如果您知道数据位于哪些分区,请在
search()
方法调用中调用load_partition()
来加载预期的分区,然后指定分区。 - 如果您不知道确切的分区,请在调用
search()
之前调用load_collection()
。 - 如果在搜索之前未加载集合或分区,Milvus将返回错误。
在插入向量后是否可以创建索引?
可以。如果通过create_index()
为集合构建了索引,Milvus将自动为随后插入的向量构建索引。但是,Milvus直到新插入的向量填满整个段并且 新创建的索引文件与之前的索引文件分开时才会构建索引。
FLAT和IVF_FLAT索引有什么不同?
IVF_FLAT 索引将向量空间划分为列表簇。在默认列表值 16,384 的情况下,Milvus 比较目标向量与所有 16,384 个簇的质心之间的距离,以返回探测到的最近簇。然后 Milvus 比较目标向量与所选簇中的向量之间的距离,以获取最近的向量。与 IVF_FLAT 不同,FLAT 直接比较目标向量与每个其他向量之间的距离。
当向量总数大约等于 nlist 时,IVF_FLAT 和 FLAT 在计算需求和搜索性能方面的差距很小。然而,当向量数量超过 nlist 两倍或更多时,IVF_FLAT 开始展现出性能优势。
详细信息请参阅 Vector Index。
Milvus 如何刷新数据?
当插入的数据加载到消息队列时,Milvus 返回成功。但是,数据尚未刷新到磁盘。然后 Milvus 的数据节点将消息队列中的数据以增量日志的形式写入持久存储。如果调用 flush()
,数据节点将被强制立即将消息队列中的所有数据写入持久存储。