Chat with Milvus #16-v0.10.0 & 用 ES 做圖片搜索?

Chat with Milvus #16: Milvus 分佈式擴展方案-Mishards

 

 

| Milvus Q&A 部分文字實錄

 

Attendee= 參會者

 

Attendee A:你好顧老師, 我想了解一下 Mishards 它具體在擴容的過程怎麼實現的?動態擴容那一步,就是 Milvus readonly 服務它擴容具體怎麼實現?

 

顧老師 @Milvus: 現在我們的分佈式其實是做第一步相對比較簡單的,應該稱之爲分佈式擴展。我們還沒有把整個 Milvus 構建成一個分佈式集羣的模式,因爲之前也跟大家有解釋這個原因,其實我們有很多功能還在不斷的引入當中。因爲一個分佈式集羣,當你開始做分佈式集羣的時候,就意味着你自己自身的單點的能力也好,都要相對到一個平臺期,那麼在做那個會比較的自然一點,不然的話因爲我們現在很多功能要引入進去,那麼其實如果是在一個分佈式集羣的環境裏面的話,它會變得非常的複雜,所以現在更多的是做一個分佈式擴展。

 

分佈式擴展其實是現在主要的方式,也就是提供一些這種分佈式代理像 Mishards,然後前面可以借 nginx 去幫助大家做一些這種動態的負載均衡。擴容這部分的話,其實我們即便是把它做成一個集羣,我們因爲最終奔着一個雲的環境去的,所以我們也不會說把所有的功能都讓自己去做實現,更多的是會利用現代的組件,怎麼樣去利用 k8s 去新增節點,然後去註冊服務,然後怎麼樣把它加入到負載均衡的裏面,所以其實我們不會說自己單純做一套完整的東西去做所有的東西。

 

Attendee A:在查詢文件的過程中是挨個對文件進行查找,然後查找過來,然後在內存中....

 

顧老師 @Milvus:你是說搜索的時候?

 

Attendee A:對,我在看的查找的過程中,不是挨個文件,就是在 search 的時候挨對每一個文件夾進行比較,求出 Top N,然後再歸併是吧?

 

顧老師 @Milvus:對的,是這麼個過程。

 

Attendee A:我看到咱的在知乎上分享的文章裏面,怎麼是還往內存中加載的時候用的 LRU(Least Recently Used)策略,既然對每一個文件都進行了 Top N,它不就沒有必要進行 LRU?

 

顧老師 @Milvus:這個是兩個不同的方面,LRU 主要是指的是因爲在 Milvus 服務當中,它有一個內存當中的 cache 緩存這一層,那麼其實所有的數據文件都先放在內存當中,然後我去進行搜索,這是速度最快的。所以這部分是挨個搜索其實就是發生在內存裏的。但是如果說你的文件特別大,然後你的服務器內存也不是那麼夠,那麼你不可能把所有的文件都放在內存裏面,這個緩衝區它肯定需要一些淘汰的機制,對吧?

 

我讀了 10 個文件,現在你第 11 個文件要進來,我不是已經放不下了,我就要把最早的文件清除掉,釋放的空間去給後面新的文件。它其實更多是指的一個緩衝區的內存淘汰的一個機制。您那邊現在是一個什麼樣的場景?

 

Attendee A:就是 10 億級的這種的向量,512 維的。如果我一個節點寫入,然後多個節點可以查詢的話,我從刪除然後到可以進行查詢,可以同步到這能用,這多長時間?

  

顧老師 @Milvus:你是說被刪掉的,然後到查詢的時間是嗎?肯定是要有一個延遲的。你如果要在 10 億的規模上做一個幾百的併發度的話,其實已經算是一個比較高的規模相對會比較大一點,硬件的規模。

 

Attendee A:實際上咱們那個工具的話算了一下,1700多G。

 

顧老師 @Milvus:10 億的話內存的話,我想一想,如果你是帶壓縮的話,應該不會那麼大,可能在 500 就 600 多 G 左右。如果不這樣做的話,可能它就一個 T,一點幾個 T 了。

 

Attendee A:對。就這種全量匹配的不進行壓縮的話,也不進行聚類,如果這樣查詢的話,這種速度查 Top10 的話,多長時間能夠返回?

 

顧老師 @Milvus:10 億的我們沒有測過 512 的,我們只測過 128 的,128 的 10 億的帶點壓縮的話,差不多是在 400 毫秒左右。因爲我們公開數據是 128 維的 sift-1b 的數據集。

 

Attendee A:咱們提供的 bootcamp 裏面,如果按分佈式的操作的話,它只有沒有 k8s的部署是吧?

 

顧老師 @Milvus:Bootcamp 裏面我們應該沒有給分佈式的教程,應該分佈式的教程都是在本身就是 Milvus 主 repo 的。因爲 Bootcamp 中的教程都是偏向於一些小型的應用場景,就是告訴大家怎麼和自己的應用去結合的。

 

Attendee A:Bootcamp 裏面有一個叫《基於 Mishards 的分佈式方案》,這個不是基於 k8s 的,它是直接自己部署的是吧?

 

顧老師 @Milvus:對的。所以你的併發度要能達到幾百的話,你這個場景還是比較繁忙的,而且又不斷的有數據更新進來。我不知道你這些更新的頻率大概是什麼樣的?

 

Attendee A:整個底庫的更新的話不是很大,但是有刪除的操作。

 

顧老師 @Milvus:就是時不時有一些刪除,但是更新的量每天會新增加來多少呢?百萬級的嗎?還是說千萬級的這樣?

 

Attendee A:每天大概百萬級左右。

 

顧老師 @Milvus:其實之前也有很多人有類似的一個問題,我覺得給大家建議。把底庫和增量的部分創建兩個不同的索引的 collection,因爲這樣的話,不同的 collection 可以有不同的這種文件大小的配置,比較適合不同的場景。

 

因爲底庫本身特別大,但是又不怎麼更新,相對來說比例不是那麼高的話,它文件可以放大一點,它搜索的效率就會高一點。但是動態增加的部分就文件可以小一點的,你可以更快的構建起索引去搜索它。 


B 同學是做電商的, 希望用 Milvus 做商品圖片的搜索(因爲多是做場景的討論所以這裏就不寫出來, 想了解的可以看視頻 16:27-38:30 的部分)


Attendee C:因爲最近主要看向量搜索,其實我們主要是做 1 比 N 這個方案,讓我看到了Milvus。然後我們之前考慮了有大概 4 個方案,1 個是 PG 的就是 PG 拿它插件,還有 image signal 來做,只不過它那個維度比較低。然後也考慮了一下 ES 的,只不過 ES 用了它特性 dense vector 來做,還也就前幾天我看到你這個叫 Milvus 的。稍微測試了一下,感覺性能還有一些周邊的生態都做得還可以,基礎的有的都有,所以我想更深入的瞭解一下這塊。

 

我現在的話我有幾個問題,第一個像提取特徵值這一塊,因爲剛纔顧老師有說到 VGG 那個模型是吧?然後我想你們這邊之後做就是說無論是圖片還是一些文字,還是一些聲音頻之類的,像這種提取特徵值這塊你們有做一個什麼口子來做嗎?給別人提供一個比如說一個算法插件什麼之類的,然後相當於直接把圖片轉成一些特徵值,然後直接就可以跟你 Milvus 結合起來,會有這方面的考慮?

  

顧老師 @Milvus:是會有的,其實我們在做的圖片搜索套件也是就幫助大家去構建這樣一個 pipeline,然後你這邊圖片就是你配好流水線,然後你把圖片提交過來之後,它可以幫你去按照你的要求的操作,比如說做一些對象的偵測,然後根據得出來的對象,然後去按照你指定的模型過一下這些特徵值,然後再插入到 Milvus 當中。

 

但是因爲這部分的東西它其實它更偏向於應用層,所以它不在 Milvus 裏面,但是它會在非結構數據服務的大的框架裏面,所以我們是會在 Milvus 的上游去提供這些東西,方便大家去做這些東西。

 

Attendee C:對這邊可能更專注於做向量搜索引擎這一塊整個的方案是吧?

 

顧老師 @Milvus:對,Milvus 本身它是一個怎麼說,這是一個大的非結構數據服務當中一個比較核心的高性能的向量搜索引擎。然後什麼模型的推理,pipeline 的構建,這些其實也在我這個框架裏面,但是它是在 Milvus 的外部去做這些事情。

 

Attendee C:

我想問一下有沒有一些落地的這種與業務場景的集成?就是與場景它肯定有一些業務場景方面的一些參數,這邊的集成是怎麼做的,因爲我看到像比如說有圖片,這可能用戶說我根據以圖所圖,我可能在 Milvus 裏面我可能搜出的是一段特徵值,對吧?但是我最終要返回給用戶的肯定不能是一些特徵值,而且是相應的一些圖片的數據。我現在想的看是不是大家都是用那個特徵值的 ID 來做是吧?ID 來做一些相關的聯繫是嗎?

 

顧老師 @Milvus:對沒錯,而且我們的以圖搜圖的示例裏面也是這麼搞的。

 

Attendee C:還有一個是涉及到分佈式這一塊,因爲我們這邊的量還是挺大的,量還是非常大。單依靠單機的話可能...單機的話不是說性能不好單機的話也好,但是可能還是想做分佈式這一塊。我看到這邊只支持一個 Mishards 是吧?他好像是用 Python 來做的是吧?

 

顧老師 @Milvus:是的,但是後續其實這部分也會去做一些優化,然後我們肯定會提高擴展的能力,這是肯定的,只是說 Milvus 本身還有很多功能需要去增加進來,去幫助大家更好的處理非結構數據的,所以我們是把它單獨當成一個新的場景,非結構數據服務的場景來做的。所以他其實會比一般的 ES 也好,或者說某一個結構化數據庫的向量插件也好,它會有更多的東西和更多的可能性你要加入進去。所以在這部分確實我們是先想把基礎打好了之後,再往這種集羣的,分佈式集羣的方向去做一個延伸。

 

Attendee C:好的。我看了你們的一些文檔,好像跟我理解的有些出入,我看你們這邊是對請求,比如說他不同的用戶,他可能發的有比如說 10 個關於特徵檢索的這一個請求,當然這個特徵檢索可能會分爲不同的 collection。那麼你這裏我看到你們那邊設計是將不同的請求分發到通過負載均衡一些方式,分發到不同的讀寫可讀的節點去做的是嗎?

 

顧老師 @Milvus:對,因爲每個節點他有的服務的索引不可能是不一樣的,比如說你有 10 個索引,10 個索引文件,可能 12345 在 A 節點的時候,678910 是在 B 節點上。因爲你分佈式擴展有幾種,這有兩種典型的情況,比如說第一種是你的 10 個索引文件,其實它太大,它超過了你單機內存能夠處理的,能夠容納的一個大小,這個時候你做分佈式的擴展,更多的是你擴機器來增加整個內存的容量,然後能夠把所有這些文件放下,就可能是在節點 A 上有一些文件,在節點 B 上有一些文件。

 

它可能就是要去不同的機器去進行搜索,所以就會有一個路由的過程。情況就是說我可能就是隻有一個數據文件,但是我一個機器可能跑不過來,我需要把它放在多個機器當中,我利用這個更多機器的 CPU 的計算的資源,來提供更高併發服務這樣的一種模式,所以他其實會不太一樣。

  

Attendee C:我看你們知乎上面有一篇專欄,上面講了一下,就是說 Mishards 負責將來自客戶端的請求拆分,並路由到內部各細分子實例,最後將子實例結果彙總,返回給客戶端,對吧?好像跟你剛纔描述的不太一致。

               

顧老師 @Milvus:因爲這說的是另外一種情況,就是說是比如說這索引它很大,它有好多的文件,他可能這些文件都落在不同的只讀節點上,那麼你是需要在所有這些只讀節點上都查完一個 top k 最後再做一次合併,你才知道最終的結果。這個其實是我剛纔說的第一種情況,就是你要你索引它包含 10 個文件,但是一個機器放不下這種情況。

 

Attendee C:對,然後還有可能還剩下一種情況,反正就像我剛剛說的分發不同的請求,就是說可能說有不同的 collection,然後它索引,然後比如說有三個集合的索引放在一個節點上,另外幾個節點,另外幾個的索引放在另一個節點上,實際上他們索引都不是特別大。

 

現在 Mishards 都是支持的,是嗎?還是說我需要定製化的去做一些什麼操作,然後才能滿足這兩個情況?

 

顧老師 @Milvus:都是支持的。

你之前在 ElasticSearch 上嘗試做的圖片搜索,你覺得他支持的怎麼樣?

 

Attendee C:ES 其實我當時也是測了大概維度比較低,也就 1000 萬左右,100 維的這種特徵值,實際上速度的話,因爲我們單機比較慢,因爲我沒有做任何的優化,還是比較慢的。

 

遇到的問題的話也沒有特別多,因爲它有一個特性,7.6 左右版本,提供了一個兩個相應的 vector 數據類型,對吧?然後可能當時考慮的是把這些 vector 這種特徵值直接存放到 ES 裏面,然後在其他的一些相應的業務數據,我們可能就會用另外的來進行陳述,實際上他們兩個之間的關聯也是通過一些正如 Milvus 一樣的,有一些特定的什麼 ID 來進行一些這樣的一個關聯。

 

現在主要考慮 Milvus 是因爲它像你們這邊一些具體的方案都有了,因爲還要看有落地的這些方案。然後 ES 這邊我們如果要做的話,可能像其他的一些前面的工作,包括做一些自定義 API 什麼, 做一些相應的開發任務,還有後面那些具體的當時有沒有考慮太細,但是現在目前來看還是打算用你們 Milvus 來做。

 

我當時做的主要是單機的,沒有考慮到分佈式這個場景,有可能 ES 那邊的分佈式場景的話,跟你們這還是有相比的話有一定的優勢。

 

顧老師 @Milvus:ES 它確實本身是有分佈式的,但是它的這種關鍵詞型的這種 IVF 索引,就是文本型的索引,它的原理和向量的搜索的原理還是不太一樣的,所以這部分分佈式能的話能不能帶來一個很好的效果,其實可能你們得試過才知道。對。它應該還是能提供一些分佈式基本的保證,但對向量的效果這個可能需要自己實測過。

 


 

Attendee D:我們其實是做推薦的一些東西的,然後推薦裏面可能是召回的一個環節。對召回的話,其實原來它向量確實是可以匹配上的比較好的一種方式,但其實對於業務來說,我們其實還是會對這種標量的過濾有挺強需求的,我想了解一下現在 Milvus 對標量的支持是一個什麼樣的一個計劃?

 

顧老師 @Milvus:對屬性的過濾會在下一個版本里面,具體就是在 0.11.0 版本,按照現在的規劃來說。

 

Attendee D:那它的具體的實現是會像 ES 那樣的倒排來做嗎?

 

顧老師 @Milvus:不是,是這樣的,就是說從我們的角度來講,我們也不叫標量了。這兩部分結合在一起是向量數據和屬性數據,我們稱之爲屬性的數據,那麼我們可以允許用戶定義一些屬性,當然它長度也會有限制,後續我們也會確定一下。然後每一個屬性可以是整型的數字也可以是浮點型的數字。然後在搜索的時候是會以向量搜索爲主,以向量索引的這個方式,以 ANN (approximate nearest neighbor, 近似最近鄰算法)的方式爲主,但是 ANN 比如說是一個 IVF 型的索引,他會先去搜尋一個區域的聚類,對吧?我去搜尋這一個區域的聚類裏的具體每一條向量的時候,我們這個時候會做一次屬性的過濾,這樣的話能夠確保最終出來的結果一定是比較準確的,是符合你的屬性的要求的。然後這個數量也是能夠達到,比如說你求 top 10 一定會給你返回 10 條記錄,它是經過屬性過濾之後的相似性的結果。

 

Attendee D:就是說它可能還是說是所有的向量都會去掃一遍?

 

顧老師 @Milvus:它不是一個所有向量都會去掃一遍,因爲剛纔我講了他是以 ANNS 的模式爲主的。這 ANNS 的模式,比如說 IVF 類的索引,他會首先去計算你搜索向量它所坐落的最近的圖形在哪裏,然後就圖形周圍的一片區域看它搜索區域,所以它只會搜索那一小片區域。

 

先確定你這條搜索向量應該落在索引當中的哪一個聚類當中,然後在聚類周圍你可以指定一片區域,它不一定是去聚類的,他說他應該帶的聚類那一小個類是可以搜,比如說周圍 10 個類這樣。對他掃描的那一個子空間裏的所有的向量,先做從屬性的過濾,然後再去做相似的計算。

 

 

 

| 歡迎加入 Milvus 社區

 

github.com/milvus-io/milvus | 源碼

milvus.io | 官網

milvusio.slack.com | Slack 社區

zhihu.com/org/zilliz-11/columns | 知乎

zilliz.blog.csdn.net | CSDN 博客

space.bilibili.com/478166626 | Bilibili

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章