如何在 Milvus 中压缩数据?
Binlog 封面图片
随着 Milvus 2.0 GA 的正式发布,一系列新功能得到了支持。其中,"压缩 "是可以帮助你节省存储空间的新功能之一。
压缩指的是将小片段合并为大片段并清理逻辑删除数据的过程。换句话说,压缩通过清除 binlog 中已删除或过期的实体来减少磁盘空间的使用。它是一项后台任务,由数据协调器触发,并由 Milvus 中的数据节点执行。
本文将剖析 Milvus 中压缩的概念和实现。
什么是压实?
在深入探讨如何在 Milvus 2.0 中实现压实的细节之前,搞清楚什么是 Milvus 中的压实至关重要。
更多的时候,作为 Milvus 的用户,你可能已经被硬盘空间使用率越来越高所困扰。另一个问题是,少于 1 024 行的数据段不会被编入索引,只能支持暴力搜索来处理查询。自动刷新或用户强制刷新造成的小分段可能会影响查询效率。
因此,为了解决上述两个问题,帮助减少磁盘使用量和提高查询效率,Milvus 支持压缩。
LevelDB和RocksDB等数据库会将数据追加到排序字符串表(SSTables)中。每次查询的平均磁盘读取次数会随着 SSTables 数量的增加而增加,从而导致查询效率低下。为了减少读取放大并释放硬盘空间,这些数据库会将 SSTables 压缩成一个。压缩过程在后台自动运行。
同样,Milvus 也会将插入和删除的数据追加到binlog 中。随着 binlog 数量的增加,会占用更多的硬盘空间。为了释放硬盘空间,Milvus 会压缩已删除和已插入数据的 binlog。如果一个实体被插入,但后来又被删除,那么一旦压缩,它就不再存在于记录数据插入或删除的 binlog 中。此外,Milvus 还压缩段--Milvus 为保存插入数据而自动创建的数据文件。
如何配置压缩?
Milvus 的压缩配置主要涉及两个参数:dataCoord.enableCompaction
和common.retentionDuration
。
dataCoord.enableCompaction
指定是否启用压实。其默认值为 。true
common.retentionDuration
指定不运行压实的时间段。单位为秒。压缩数据时,所有删除的实体都将无法使用时间旅行进行搜索。因此,如果计划使用时间旅行进行搜索,就必须指定一段压缩不运行且不影响已删除数据的时间。为确保使用时间旅行搜索的结果准确,Milvus 会保留在 指定的时间段内操作的数据。也就是说,在这段时间内操作的数据不会被压缩。详情请参阅 "common.retentionDuration
使用时间旅行搜索"。
Milvus 默认启用压缩。如果您禁用了压实,但后来又想手动启用它,可以按照以下步骤操作:
- 调用
collection.compact()
方法手动触发全局压实进程。但请注意,此操作符可能需要很长时间。 - 调用该方法后,将返回一个压缩 ID。调用
collection.get_compaction_state()
方法可查看压实状态。
启用压缩后,它会在后台自动运行。由于压实过程可能需要很长时间,因此会异步处理压实请求以节省时间。
如何实现压缩?
在 Milvus 中,您可以手动或自动实施压实。
手动压缩 binlog 或分段不需要满足任何触发条件。因此,如果手动调用压实,无论如何都会对 binlog 或数据段进行压实。
但是,如果要启用自动压缩,则需要满足某些压缩触发条件,系统才会压缩段或 binlog。
一般来说,Milvus 可以压缩两种类型的对象:binglog 和数据段。
二进制日志压缩
binlog 是一个二进制日志,或者说是段中的一个较小的单元,它记录并处理对 Milvus 向量数据库中的数据所做的更新和更改。一个数据段的数据会被持久保存在多个 binlog 中。在 Milvus 中,二进制日志压缩涉及两种类型的二进制日志:插入二进制日志和三角二进制日志。
删除数据时会生成 Delta binlog,而插入 binlog 会在以下三种情况下生成。
- 当插入的数据被附加时,数据段达到大小上限,并自动刷新到磁盘。
- DataCoord 会自动刷新长时间未封存的数据段。
- 一些 API(如
collection.num_entities
、collection.load()
等)会自动调用 flush 将段写入磁盘。
因此,binlog 压缩,顾名思义,指的是压缩段内的 binlog。更具体地说,在 binlog 压缩过程中,所有未保留的 delta binlog 和插入 binlog 都会被压缩。
二进制日志压缩
当一个数据段被刷新到磁盘,或 Milvus 因长时间未运行压缩而请求全局压缩时,至少需要满足以下两个条件之一,才能触发自动压缩:
- delta binlog 中的行数超过总行数的 20%。
- delta binlog 的大小超过 10 MB。
段压缩
段是 Milvus 自动创建的用于保存插入数据的数据文件。Milvus 有两种类型的数据段:生长数据段和密封数据段。
成长段不断接收新插入的数据,直到被密封。密封段不再接收任何新数据,并将被刷新到对象存储空间,留下的新数据将被插入到新创建的增长段中。
因此,段压缩指的是压缩多个密封段。更具体地说,在段压缩过程中,小段被压缩成大段。
分段压实
压缩后生成的每个分段都不能超过分段大小的上限,默认为 512 MB。请阅读系统配置,了解如何修改段大小的上限。
当数据段刷新到磁盘,或 Milvus 因长时间未运行压缩而请求全局压缩时,需要满足以下条件才能触发自动压缩:
- 段小于 0.5 *
MaxSegmentSize
多于 10。
下一步是什么?
了解了 Milvus 压缩的基础知识后,下一步该做什么?目前,在milvus.yaml
文件中还没有配置压缩的所有参数,计划生成策略也相对比较基本。有兴趣的话,就来为 Milvus这个开源项目做贡献吧!
此外,在 2.0 新功能系列博客中,我们将介绍新功能的设计。阅读本系列博客的更多内容!
关于作者
孙斌义,Milvus 项目高级软件工程师,上海交通大学软件工程硕士。他主要负责开发 Milvus 2.0 中与存储相关的组件。他的兴趣领域是数据库和分布式系统。他是开源项目的忠实粉丝,也是一位美食家,业余时间喜欢玩电子游戏和阅读。
Like the article? Spread the word