在這篇文章,咱們會主要描述 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 博客