更多場景、更多選擇,Milvus 新訊息佇列 NATS 瞭解一下

發表於2023-09-20

在 Milvus 的雲原生架構中,訊息佇列(Log Broker)可謂任重道遠,它不僅要具備流式資料永續性、支援 TT 同步、事件通知等能力,還要確保工作節點從系統崩潰中恢復時增量資料的完整性。

在 Milvus 的架構中,一切圍繞訊息佇列構建,遵循日誌結構化儲存的原則,訊息佇列在 Milvus 中的作用可以類比於傳統資料庫的 WAL(Redo Log)的角色。在 Milvus 2.3 之前,Milvus 官方支援 RocksMQ(Standalone 模式限定,Milvus 官方基於 RockDB 實現的 MQ 系統),以及 Pulsar、Kafka 等傳統 MQ。

在 Milvus Standalone 模式下,相比於 Pulsar 和 Kafka,RocksMQ 是最簡單的 MQ 部署方案。但由於 RocksMQ 基於 RocksDB,在大訊息體以及海量訊息的場景下效能表現一般。同時 RocksMQ 需要 rocksdb,頻繁的呼叫 CGO,帶來額外的效能負擔。在 Milvus 2.3中,Milvus Standalone 最新引入了新的基於 NATS 的單機 MQ 實現,給使用者提供在不同的使用場景下更多的 MQ 選擇。

本文將介紹新 MQ 的使用方式以及與其他 MQ 的對比。

01.什麼是 NATS

NATS 是 GO 實現的分散式系統連線技術,支援 Request-Reply、Publish-Subscribe 等跨系統溝通模式,透過底層的 JetStream 支援資料的持久化,以及內建的 RAFT 來提供分散式能力。想要系統的瞭解 NATS,可以檢視官方網站:https://nats.io/

NATS 支援的 Feature 非常多,在 Milvus 2.3 standalone 模式下,Milvus 利用單機版的 NATS+JetStream+PubSub 模式提供 MQ 能力。同時,Nats-server 被 Embedding 進了 Milvus 的程式中,不需要額外的 NATS 部署即可實現 NATSMQ。

02.如何啟用 NATS

在 Milvus 2.3中,新引入了mq.type作為 MQ 型別的控制選項,為了保持向上相容,NATS 不會進入預設的 MQ 選擇優先順序中,需要使用mq.type=natsmq強制指定。在 Milvus 例項啟動後,如果看到以下的日誌,則說明 Milvus使用了 NATS 作為 MQ。

[INFO] [dependency/factory.go:83] ["try to init mq"] [standalone=true] [mqType=natsmq]

03.NATS 配置項詳解

當前配置項支援下述的定製化配置能力:

natsmq:
  server: # server side configuration for natsmq.
    port: 4222 # 4222 by default, Port for nats server listening.
    storeDir: /var/lib/milvus/nats # /var/lib/milvus/nats by default, directory to use for JetStream storage of nats.
    maxFileStore: 17179869184 # (B) 16GB by default, Maximum size of the 'file' storage.
    maxPayload: 8388608 # (B) 8MB by default, Maximum number of bytes in a message payload.
    maxPending: 67108864 # (B) 64MB by default, Maximum number of bytes buffered for a connection Applies to client connections.
    initializeTimeout: 4000 # (ms) 4s by default, waiting for initialization of natsmq finished.
    monitor:
      trace: false # false by default, If true enable protocol trace log messages.
      debug: false # false by default, If true enable debug log messages.
      logTime: true # true by default, If set to false, log without timestamps.
      logFile: /tmp/milvus/logs/nats.log # /tmp/milvus/logs/nats.log by default, Log file path relative to .. of milvus binary if use relative path.
      logSizeLimit: 536870912 # (B) 512MB by default, Size in bytes after the log file rolls over to a new one.
    retention:
      maxAge: 4320 # (min) 3 days by default, Maximum age of any message in the P-channel.
      maxBytes: # (B) None by default, How many bytes the single P-channel may contain. Removing oldest messages if the P-channel exceeds this size.
      maxMsgs: # None by default, How many message the single P-channel may contain. Removing oldest messages if the P-channel exceeds this limit.
  • server.port:由於 Nats 為 C-S 模式程式,當前不支援使用類似於 unix socket 等不佔用埠的套接字方案,當前在 Milvus 中需要指定server.port作為 NATS Server 的埠,如果出現埠衝突,則 Milvus 不能正常啟動。填寫server.port=-1,可以隨機選擇埠。
  • storeDir:用於指定底層的 JetStream 持久化機制的儲存目錄,建議將該目錄掛載在高效能的 SSD 上來提升 Milvus 的讀寫吞吐。如果出現 Milvus 無法啟動的情況,請檢查該目錄是否存在或者目錄的使用許可權。
  • maxFileStore:用於限制 JetStream 的儲存量上限,如果超出該上限將會出現禁止寫入的情況。
  • maxPayload:單個訊息的硬大小限制,Milvus 最大的訊息chunk支援到5MB,因此該配置應該要保持在5MB以上並留有一定的餘量,否則可能出現 Milvus 拒絕寫入的情況。
  • initializeTimeout:用於控制 Milvus 啟動時,Nats Server 的啟動超時配置。如果出現以下日誌,可以適當調高該配置。
[WARN] [nmq/nmq_server.go:77] ["nmq is not ready within timeout"]
  • monitor:用於配置 NATS 的獨立日誌,建議在日常執行環境中啟用 trace 日誌。
  • retention:用於控制 NATS 訊息的保持機制,由於當前 Milvus 的訊息保持機制與訊息消費機制尚未實現同步。因此請務必保持該配置有充足的餘量,讓 Milvus 可以在訊息被訊息佇列清退前消費完畢,否則 Milvus 可能會出現資料丟失的情況。

以上的絕大部分配置都與 NATS 官方配置對齊,如果需要了解更多的配置,或者希望 Milvus 引入更多的定製化配置,可以檢視 NATS 的官方文件 https://docs.nats.io/running-a-nats-service/config

04.RocksMQ 遷移至 NATS

可以採用 Milvus 的通用 MQ 遷移方案。

  • 停止 Milvus 一切的寫入操作。
  • 呼叫 FlushALL 操作,等待 FlushALL 完畢後,關閉Milvus 程式。
  • 修改配置項 mq.type=natsmq,以及 natsmq下相關需要修改的配置項(如果出現埠衝突或者目錄許可權等問題)
  • 啟動 2.3 版本的 Milvus 程式:
    • 日誌應當出現mqType=natsmq日誌。
    • natsm.server.storeDir配置的目錄下應當出現 jetstream 資料夾。
  • 可選:備份並清理原rocksmq.path儲存目錄下的檔案資料。

05.NATS 和 RocksMQ 對比

Pub/Sub 效能對比

測試平臺與方案

  • M1 Pro Chip / Memory: 16GB
  • 啟動 MQ,同時對一個 Topic 進行訂閱和釋出隨機內容資料包,迴圈 N 次釋出操作後,直到訂閱得到最後一次釋出結果時,測試結束。

測試結果

  • NATS 為純 GO 的實現,而 RocksMQ 使用 CGO 與 rocksdb 的 lib 互動。因此 NATS 的絕大部分記憶體由 GO 的 GC 接管,而 RocksMQ 依賴 lib 自身的記憶體管理。NATS 的記憶體開銷會更高。
  • 在資料包較小(小於 64kb)的場景下,RocksMQ 不論在記憶體、CPU 還是在響應速度都具備較大優勢。(1kb message rocksmq 有1x 以上效能優勢)
  • 在資料包較大的場景下(大於 64kb),NATS 在記憶體充足以及理想的 GC 場景下,在響應速度方面有較大的優勢(5MB message NATS 有 1x 以上效能優勢)
  • 儲存方面,RocksMQ 當前有 Zstd 壓縮加持,消耗的磁碟空間更少(NATS 未開壓縮)

Milvus 整合測試

  • 在 1 億級別的向量對比測試中:NATS 可以支援更低的檢索延遲。

  • 在資料量較少的場景下:NATS 與 RocksMQ 的差距不大。

以上就是關於 Milvus 新訊息佇列 NATS 的全部內容,如果大家有任何疑問都可以跟我們溝通,下一篇我們會繼續講解 Milvus 2.3 的新功能——MMap,敬請期待。


  • 如果在使用 Milvus 或 Zilliz 產品有任何問題,可新增小助手微信 “zilliz-tech” 加入交流群。
  • 歡迎關注微信公眾號“Zilliz”,瞭解最新資訊。

本文由mdnice多平臺釋出

相關文章