Milvus 2.0 質量保障系統詳解

Zilliz發表於2022-04-25
編者按:本文詳細介紹了 Milvus 2.0 質量保障系統的工作流程、執行細節,以及提高效率的優化方案。

內容大綱:

  • 質量保障總體介紹
    測試內容的關注點
    開發團隊與質量保障團隊如何協同
    Issue 的管理流程
    釋出標準
  • 測試模組介紹
    總體介紹
    單元測試
    功能測試
    部署測試
    可靠性測試
    穩定性和效能測試
  • 提效方法和工具
    Github Action
    效能測試工具
    質量保障總體介紹

質量保障總體介紹

架構設計圖對於質量保障同樣重要,只有充分了解被測物件,才能制定出更合理和高效的測試方案。Milvus 2.0 是一個雲原生、分散式的架構,主要的入口通過 SDK 進入,內部有很多分層的邏輯。因而對於使用者來說,SDK 這一端是非常值得關注的一部分,對 Milvus 測試時,首先會對 SDK 這一端進行功能測試,並通過 SDK 去發現 Milvus 內部可能存在的問題。同時 Milvus 也是一個資料庫,因此關於資料庫的各種系統測試也會涉及到。

雲原生、分散式的架構,既會給測試帶來好處,也會引入各種挑戰。好處在於,區別於傳統的本地部署執行,在 k8s 叢集中部署和執行能儘可能保證軟體在開發和測試時環境一致。挑戰則是分散式的系統變得複雜,引入了更多的不確定性,測試工作量和難度的增加。例如微服務化後服務數量增加、機器的節點會變多,中間階段越多,出錯的可能性越大,測試時就需要考慮各個情況。

測試內容的關注點

根據產品的性質、使用者的需求,Milvus 測試的內容與優先順序如下圖所示。

首先在功能(Function)上,關注介面能否與設計的預期符合。

其次在部署(Deployment)上,關注 standalone 或者 cluster 模式下重啟和升級是否能成功。

第三在效能(Performance)上,因為是流批一體的實時分析資料庫,所以對於速度會更重視,會更關注插入、建立索引、查詢的效能。

第四在穩定性(Stability)上,關注 Milvus 在正常的負載下的正常執行時間,預期目標是 5 - 10天。

第五在可靠性(Reliability)上,關注錯誤發生時 Milvus 的表現,以及錯誤消除是否還能正常工作。

第六是配置問題(Configuration),需要驗證每個開放出來的配置項能否正常工作,變更能否生效。

最後是相容性問題(Compatibility),主要是體現在硬體上和軟體配置上。

由圖可知,功能和部署是放在最高等級的,效能、穩定性、可靠性放在第二等級,最後將配置和相容性放在第三的位置。不過,這個等級重要性也是相對而言的。

開發團隊與質量保障團隊如何協同

一般使用者會認為質量保證的任務是僅僅分配給質量保證團隊的,但是軟體開發過程中,質量需要多方團隊合作以得到保障。

最開始的階段由開發設計文件,質量保障團隊根據設計文件寫測試計劃。這兩個文件需要測試和開發共同參與以減少理解誤差。釋出前會制定這一版本的目標,包括效能、穩定性、bug 數需要收斂到什麼程度等。在開發過程中,開發側重於編碼功能的實現,功能完成之後質量保障團隊會進行測試和驗證。這兩個階段會輪巡很多遍,質量保障團隊和開發團隊需要每天保持資訊同步。此外,除了本身功能的開發驗證,開源的產品還會收到很多來自於社群的問題,也會根據優先順序進行解決。

在最後階段,如果產品達到了釋出標準,團隊就會選定一個時間節點,釋出一個新的映象。在釋出前需要準備一個 release tag 和 release note,關注這個版本實現了什麼功能,修復了什麼 issue,後期質量保障團隊也會針對這個版本出一個測試報告。

Issue 的管理流程

質量保障團隊更多地關注於產品開發中的 issue。Issue 的作者除了質量保障團隊的成員,還有大量的外部使用者,因此需要規範每個 issue 的填寫資訊。每個 issue 都有一個模板,要求作者提供一些資訊,例如當前使用的版本,機器配置資訊,然後你的預期是什麼?實際的返回結果是什麼?如何去復現這個 issue,然後質量團隊和開發團隊會繼續去跟進。

在建立這個 issue 之後,首先會 assign 給質量保障團隊的負責人,然後負責人會對這個 issue 進行一些狀態流轉。如果 issue 成立且有足夠多的資訊,後續會有若干種狀態,如:是否解決了;是否能復現;是否與之前有重複;出現概率大小;優先順序大小。如果確認存在缺陷,開發團隊會提交 PR,關聯上這個 issue,進行修改。在得到驗證後,這個 issue 會被關閉,如果之後發現依然存在問題,還可以 reopen。此外,為了提高 issue 的管理效率,還會引入標籤和機器人,用於對 issue 分類和狀態流轉。

釋出標準

能否釋出主要指當前這個版本能否達到預期要求。例如上圖是一個大致的情況,RC6 到 RC7,RC8 和 GA 的標準。隨著版本的推進,對 Milvus 的質量提出更高的要求:

  • 從原先 50M 的數量級,逐漸演進到 1B 的數量級
  • 在穩定性的任務執行中,由單任務變成混合任務,時長逐漸由小時級變成天級
  • 對於程式碼而言,也在逐漸提高它的程式碼覆蓋率
  • ……
  • 此外,隨著版本的更替,也會加入其他的測試項。例如在 RC7 的時候,提出了要有一個相容項,升級的時候要有相容;在 GA 的時候,引入更多關於混沌工程的測試

測試模組介紹

第二部分是關於每個測試模組的一些具體細節。

總體介紹

業界有寫程式碼就是寫 bug 的戲謔,從下圖可以看到,85%的 bug 是由 coding 階段引入的。

從測試的角度來看,程式碼編寫到版本釋出這個過程中,依次可以通過 Unit Test / Functional Test / System Test 去發現 bug;但是隨著階段的推移,修復 bug 的成本也會遞增,所以往往傾向於早發現早修復。不過,每個階段的測試有自己的側重點,不可能只通過一種測試手段就發現所有的 bug。

開發從編寫程式碼到程式碼合併到主分支這個階段分別會從 UT、code coverage 和 code review 去保障程式碼質量,這幾項也體現在 CI 中 。在提交 PR 到程式碼合併的過程中,需要通過靜態程式碼檢查、單元測試、程式碼覆蓋率標準以及 reviewer 的程式碼稽核。

在合併程式碼時,同樣需要通過整合測試。為了保證整個 CI 的時間不會太長,在這個整合測試裡面,主要執行 L0 和 L1 這些具有高優先順序標籤的 case。通過所有檢查後,就可以到 milvusdb/milvus-dev 倉庫中釋出這個 PR 構建的映象。在映象釋出之後,會設定定時任務對最新的映象進行前文提到的多種測試:全量的原有功能測試,新特性的功能測試,部署測試,效能測試,穩定性測試,混沌測試等。

單元測試

單元測試可以在儘可能早的階段發現軟體存在的 bug,同時也可以為程式碼重構提供驗證標準。在 Milvus 的 PR 准入標準中,設定了程式碼的單元測試 80% 覆蓋率目標。

https://app.codecov.io/gh/mil...

功能測試

對 Milvus 的功能測試,主要是通過 pymilvus 這個 SDK 作為切入點。

功能測試主要關注於介面能否按照預期工作。

  • 輸入正常的引數或採用正常的操作時,SDK 是否能返回預期的結果
  • 當引數或操作是異常的時候,SDK 是否能 handle 住這些錯誤,同時能夠返回一些合理的錯誤資訊

下圖是當前的功能測試框架,整體而言是基於目前主流的測試框架 pytest,並對 pymilvus 進行了一次封裝,提供了介面自動化測試能力。

採用上述測試框架, 而不是直接用 pymilvus 原生的介面,是因為在測試過程中需要提取出一些公共方法,複用一些常用的函式。同時也會封裝一個 check 的模組,能更方便地去校驗一些預期和真實值。

當前 tests/python_client/testcases 目錄下的功能測試用例已經有 2700+,基本上覆蓋了 pymilvus 的所有介面,且包含正面用例和反面用例。功能測試作為 Milvus 的基本功能保障,通過自動化和持續整合,嚴格把控每一個提交的 PR 質量。

部署測試

部署測試中,支援 Milvus 部署形態有 standalone 和 cluster ,部署的方式有 docker 或者 helm。部署完成之後,需要對系統執行 restart 和 upgrade 的操作。

重啟測試,主要是驗證資料的持久化,即重啟前的資料在重啟後能否繼續使用;升級測試,主要是驗證資料的相容性,防止在不知情的情況下引入了不相容的資料格式。

重啟測試和升級測試可以統一為如下的測試流程:

如果是重啟測試,兩次部署使用相同映象;如果是升級測試,第一次部署使用舊版本映象,第二次部署使用新版本映象。第二次部署時,無論是重啟還是升級,均會保留第一次部署後的測試資料( Volumes 資料夾或者 PVC )。在 Run first test 這個步驟中,會建立多個 collection,並對每個 collection 執行不同的操作,使其處於不同的狀態,例如:

  • create collection
  • create collection --> insert data
  • create collection --> insert data -->load
  • create collection --> insert data -->flush
  • create collection --> insert data -->flush -->load
  • create collection --> insert data -->flush --> create index
  • create collection --> insert data -->flush --> create index --> load
  • ......

Run second test 這個步驟中會進行兩種驗證:

  • 之前建立的 collection 各種功能依然可用
  • 可以建立新的 collection,同樣各種功能依然可用

可靠性測試

當前針對雲原生,分散式產品的可靠性,大部分的公司都會通過混沌工程的方法進行測試。混沌工程旨在將故障扼殺在襁褓之中,也就是在故障造成中斷之前將它們識別出來。通過主動製造故障,測試系統在各種壓力下的行為,識別並修復故障問題,避免造成嚴重後果。

在執行 chaos test 時,選擇了 Chaos Mesh 作為故障注入工具。Chaos Mesh 是 PingCAP 公司在測試 TiDB 可靠性的過程中孵化出來的,非常適合用於雲原生分散式資料庫的可靠性測試。

在故障型別中,實現了以下幾種故障型別:

  • 首先就是 pod kill,測試範圍是所有的元件,模擬節點當機的情況
  • 其次 pod failure,主要是關注於 work node 的多副本情況下,有一個 pod 不能工作,整個系統還能正常運作
  • 第三個是 memory stress ,側重記憶體和 CPU 的壓力,主要注入到 work node 的節點
  • 最後一個 network partition ,即 pod 與 pod 之間的一個通訊隔離。Milvus 是一個儲存計算分離,工作節點和協調節點分離的多層架構,不同元件之間的通訊非常多,需要通過 network partition 測試它們之間的相互依賴關係

通過建構一套框架,較為自動化地實現 Chaos Test。

流程:

  • 通過讀取部署配置,初始化一個 Milvus 叢集
  • 叢集狀態 ready 後,首先會執行一個 e2e 測試,驗證 Milvus 的功能可用
  • 執行 hello_milvus.py,主要用於驗證資料的可持久化,會在故障注入前建立一個 hello_milvus 的 collection,進行資料插入,flush,create index,load,search,query。注意,不會將 collection release 和 drop
  • 建立一個監測物件,該物件主要是開啟 6 個執行緒,分別不斷執行 create,insert,flush,index,search,query 操作
checkers = {
    Op.create: CreateChecker(),
    Op.insert: InsertFlushChecker(),
    Op.flush: InsertFlushChecker(flush=True),
    Op.index: IndexChecker(),
    Op.search: SearchChecker(),
    Op.query: QueryChecker()
}
  • 故障注入前進行第一次斷言:所有操作預期成功
  • 注入故障:解析定義故障的 yaml 檔案,通過 Chaos Mesh,向 Milvus 系統中注入故障,例如使 query node 每 5s 被 kill 一次
  • 故障注入期間進行第二次斷言:判斷針對故障期間的 Milvus 執行的各個操作返回的結果與預期是否一致
  • 刪除故障:通過 Chaos Mesh 刪除之前注入的故障
  • 故障刪除,Milvus 恢復服務後(所有 pod 都 ready ),進行第三次斷言:所有操作預期成功
  • 執行一個 e2e 測試,驗證 Milvus 的功能可用,因為第三次斷言,有些操作會在 chaos 注入期間被阻塞,即使故障消除後,依然被阻塞,導致第三次斷言不能如預期一樣全部成功。因此增加這個步驟輔助第三次斷言的判斷,並暫時將這次 e2e 測試作為 Milus 是否恢復的標準
  • 執行 hello_milvus.py,載入之前建立的 collection,並對該 collection 執行一系列操作,判斷故障前的資料在故障恢復後,是否依然可用
  • 日誌收集

穩定性和效能測試

穩定性測試

穩定性測試的目的:

  • Milvus 可以在正常水平的壓力負載下,平穩執行設定的時長
  • 在執行過程中,系統使用的資源保持平穩,Milvus 的服務正常

主要考慮兩種負載場景:

  • 讀密集:search 請求 90%,insert 請求 5%, 其他 5%。這種場景主要是離線場景,資料匯入之後,基本不更新,主要提供查詢服務
  • 寫密集: insert 請求 50%,search 請求 40%,其他 10%。這種場景主要是線上場景,需要提供邊插入邊查詢的服務

檢查項:

  • 記憶體使用量平滑
  • CPU 使用量平滑
  • IO 延時平滑
  • Milvus 的 pod 狀態正常
  • Milvus 服務響應時間平滑

效能測試

效能測試的目的:

  • 對 Milvus 各個介面進行效能摸底
  • 通過效能對比,找到介面最佳的引數配置
  • 作為效能基準,防止之後的版本出現效能下降
  • 找到效能瓶頸點,為效能調優提供參考

主要考慮的效能場景:

  • 資料插入效能
    效能指標:吞吐量
    變數:每批次插入向量數,......
  • 索引構建效能
    效能指標:索引構建時間
    變數:索引型別,index node 數量,......
  • 向量查詢效能
    效能指標:響應時間,每秒查詢向量數,每秒請求數,召回率
    變數:nq,topK,資料集規模大小,資料集型別,索引型別,query node 數量,部署模式,......
  • ......

測試框架和流程

  • 解析並更新配置,定義指標
    server-configmap 對應的是 Milvus 單機或者叢集的配置
    client-configmap 對應的是測試用例配置
  • 配置服務端和客戶端
  • 資料準備
  • 客戶端與服務端之間的請求互動
  • 指標資料的上報與展示

提效方法和工具

由前文可知,測試中很多步驟流程是相同的,主要是修改 Milvus server 端的配置,client 端的配置,介面的傳入引數。在多項配置下,通過排列組合,需要執行很多次實驗才能比較全面地覆蓋各種測試場景,因此程式碼複用、流程複用、測試效率就是非常重要的問題。

  • 對原有方法進行一個 api_request 的裝飾器封裝,設定成類似於一個 API gateway,統一去接收所有的 API 請求,傳送給 Milvus 然後統一接收響應,再返回給 client。 這樣更容易去捕捉一些日誌資訊,比如傳的引數、返回的結果。同時返回的結果可以通過 checker 模組去校驗,便於將所有的檢查方法定義在同一個 checker 模組
  • 設定預設引數,將多個必要的初始化步驟封裝成一個函式,原先需要大量程式碼實現的功能就可以通過一個介面實現。這種設定能夠減少大量冗餘重複的程式碼,使每個測試用例更簡單清晰
  • 每個測試用例都是關聯獨有的 collection 進行測試,保證了測試用例之間的資料隔離性。在每個測試用例的的執行起始步驟,建立新的 collection 用於測試,在測試結束後也會刪除對應的 collection
  • 因為每個測試用例都是互相獨立的,在執行測試用例的時候,可以通過 pytest 的外掛 pytest -xdist 併發執行,提高執行效率

Github Action

GitHub Action 的優點:

  • 與 GitHub 深度整合,原生的 CI/CD 工具
  • 統一配置的機器環境,同時預裝了豐富的常用軟體開發工具
  • 支援多種作業系統和版本:Ubuntu, Mac 和 Windows-server
  • 擁有豐富的外掛市場,提供了各種開箱即用的功能
  • 通過 matrxi 進行排列組合,複用同一套測試流程,支援併發的 job,從而提高效率

部署測試和可靠性測試都需要獨立隔離的環境,非常適合在 GitHub Action 上進行小規模資料量的測試。通過每日定時執行,測試最新的 master 映象,起到日常巡檢的功能。

效能測試工具

  • Argo workflow:通過建立 workflow,實現任務的排程,將各個流程串聯起來。從右圖可以看出,通過 Argo 可以實現多個任務同時執行
  • Kubernetes Dashboard:視覺化 server-configmap 和 client-configmap
  • NAS:掛載常用的 ann-benchmark 資料集
  • InfluxDB 和 MongoDB: 儲存效能指標結果
  • Grafana:服務端資源指標監控,客戶端效能指標監控
  • Redash: 效能圖表展示

完整版視訊講解請戳:
https://www.bilibili.com/vide...

如果你在使用的過程中,對 Milvus 有任何改進或建議,歡迎在 GitHub 或者各種官方渠道和我們保持聯絡~

Zilliz 以重新定義資料科學為願景,致力於打造一家全球領先的開源技術創新公司,並通過開源和雲原生解決方案為企業解鎖非結構化資料的隱藏價值。

Zilliz 構建了 Milvus 向量資料庫,以加快下一代資料平臺的發展。Milvus 資料庫是 LF AI & Data 基金會的畢業專案,能夠管理大量非結構化資料集,在新藥發現、推薦系統、聊天機器人等方面具有廣泛的應用。

相關文章