在这篇文章,咱们会主要描述 Milvus 里向量数据是如何被记录在内存中,以及这些记录以怎样的形式维护。git
咱们的设计目标主要有下面三点:github
所以,咱们创建了插入数据的内存缓冲区(insert buffer),以减小磁盘随机 IO 和操做系统中上下文切换的次数,从而提高数据插入的性能。基于 MemTable 和 MemTableFile 的内存存储架构,能使咱们更加方便的管理和序列化数据。将 buffer 的状态分为 Mutable 和 Immutable,能让数据持久化到磁盘的同时保持对外服务可用。架构
当用户准备插入向量到 Milvus 时,首先须要建立一个 Collection(*Milvus 在0.7.0版本中将 Table 改名为 Collection)。Collection 是 Milvus 记录和搜索向量的最基本单位。每一个 Collection 有一个独特的名字和一些能够被设置的属性,而且根据 Collection 的名字进行向量的插入或搜索。建立一个新的 Collection 时,Milvus 会在元数据里记录下这个 Collection 的信息。异步
当用户发出插入数据的请求时,数据通过序列化和反序列化,到达 Milvus server。数据这时候开始写入内存。内存写入大体分为下面几个步骤:分布式
经过 MemManager, MemTable 和 MemTableFile 多层级的架构,数据的插入能够更好地被管理和维护。固然,它们能作的远不止这些。性能
在 Milvus 里,从数据被记录在内存,到数据能被搜到,你最快只须要等待一秒。这整个过程能够大概由下面这张图来归纳:spa
首先,插入的数据会进入一个内存中的 insert buffer。这些 buffer 会由开始的 Mutable 状态周期性的转为 Immutable 状态,以准备序列化。而后,这些 Immutable buffer 会周期性的被后台序列化线程序列化到磁盘。数据落盘后,落盘信息会被记录在元数据里。至此,数据就能被搜到了!操作系统
如今,咱们会具体描述图中的步骤。.net
数据插入 Mutable buffer 的过程咱们都已经知道了,接下来,就是从 Mutable buffer 转为 Immutable buffer 的过程:线程
Immutable queue 这个队列会向后台序列化线程提供 immutable 状态的,已经准备好被序列化的 MemTableFile。每一个 MemTable 管理着本身的 immutable queue,当 MemTable 惟一 mutable 的 MemTableFile 大小达到阈值,就会进入 immutable queue。一个负责 ToImmutable 的后台线程会周期性的拉取全部 MemTable 管理的 immutable queue 中的 MemTableFile,并将他们输送到总的 Immutable queue。须要注意的是,数据写入内存和将内存中的数据变为不可被写的状态这两个操做不能同时发生,须要共用一把锁。可是,ToImmutable 这个操做由于过程很简单,几乎不会形成任何延迟,因此对插入数据的性能影响微乎其微。
接下来就是将 serialization queue 中的 MemTableFile 序列化到磁盘了。这主要分为三步:
首先,后台序列化线程会周期性的从 immutable queue 中拉取 MemTableFile。而后,他们被序列化成固定大小的原始文件(Raw TableFiles)。最后,咱们会将这个信息记录在元数据中。当咱们进行向量搜索时,咱们会在元数据中查询对应的 TableFile。至此为止,这些数据就能被搜索到了!
此外,根据设置的 index_file_size,后台序列化线程在完成一次序列化周期后,会将一些固定大小的 TableFile 合并成一个 TableFile,而且一样在元数据中记录这些信息。这时候,这个 TableFile 就能够被构建索引了。构建索引一样也是异步的,另一个负责构建索引的后台线程会周期性的读取元数据中 ToIndex 状态的 TableFile,进行对应的索引构建。
实际上,你会发现,经过 TableFile 和元数据的帮助,向量的搜索变得更加直观和方便。大致上说,咱们须要从元数据中获取与被查询 Collection 对应的 TableFiles,在每一个 TableFile 进行搜索,最后进行归并。在这篇文章里,咱们不深刻探讨搜索的具体实现。若是你想要了解更多,欢迎阅读咱们的源码,或者阅读 Milvus 系列的其余文章!
http://github.com/milvus-io/milvus| 源码
http://milvus.io| 官网
http://milvusio.slack.com| Slack 社区
http://zilliz.blog.csdn.net| CSDN 博客