新老使用者看過來~最實用的 Milvus 遷移手冊來啦!

發表於2023-09-22

毫無疑問,Milvus 已經成為全球諸多使用者構建生產環境時必不可少的向量資料庫。

近期,Milvus 釋出了全新升級的 Milvus 2.3 版本,核心引擎加速的同時也加入了諸如支援 GPU 這樣實用且強大的特性。可以說,以 Milvus 2.3 為代表的 Milvus 2.x 版本無論在功能還是效能上都遠超 Milvus 1.x 版本。因此,有很多新老使用者反饋,想要將存量向量資料從其他資料來源遷移到 Milvus2.x 中,為了解決這一需求,Milvus-migration 專案應運而生。

讀完本文,使用者可以快速掌握 Milvus-migration 的功能特點和使用方法。(小聲打個廣告:Zilliz 雲平臺提供了更方便的一鍵遷移功能)

01.功能概述

目前遷移支援的資料來源有:

  • Milvus 1.x 到 Milvus 2.x 遷移
  • Elasticsearch 到 Milvus 2.x 資料遷移
  • Faiss 到 Milvus 2.x 資料遷移 (Beta版本)
  • 支援包括命令列和 Restful API 的多種互動方式
  • 支援多種檔案形式的遷移 (本地檔案、S3、OSS、GCP)
  • 支援 Elasticsearch 7.x 以上版本、自定義遷移欄位構造表結構

02.設計思路

總體架構

程式語言

Milvus-migration 使用 go 語言實現.

互動方式

命令列

命令列是最簡便直接的使用方式,Milvus-migration 基於 cobra 框架實現了命令列。

Restful Api

Milvus-Migration 還提供 Restful API,便於工具服務化,並提供 Swagger UI。

Go module

Milvus-Migration 還可以作為 go module,整合到其他工具之中。

實現原理

對於遷移 Milvus 1.x 和 Faiss 資料,主要會對原始資料檔案內容進行解析,編輯轉換成 Milvus 2.x 對應的資料儲存格式,然後透過呼叫 Milvus sdk 的 bulkInsert 將資料寫入,整個資料解析轉換過程為流式處理,處理的資料檔案大小理論上只受磁碟空間大小限制。資料檔案支援存放在 Local File、S3、OSS、GCP 和 Minio。

對於遷移 Elasticsearch 資料,不同之處資料獲取不是從檔案,而是透過 ES 提供的 scroll api 能力 將 ES 資料依次遍歷獲取,從而解析轉成 Milvus 2.x 儲存格式檔案,同樣是呼叫 bulkInsert 將資料寫入。除了對儲存在 ES dense_vector 型別的向量進行遷移,也支援 ES 其他欄位的遷移,目前支援的其他欄位型別有:long、integer、short、boolean、keyword、text、double。

介面定義

/start - 開啟一個遷移 job(相當於 dump 和 load 的結合,目前只支援 ES 遷移)

/dump - 開啟一個遷移 dump job (將source資料 寫入到 target 所在的儲存介質中)

/load - 開啟一個遷移 load job(將寫入 target 儲存介質的資料 寫入到 Milvus 2.x)

/get_job - 檢視 job 執行結果

詳情可參考 https://github.com/zilliztech/milvus-migration/blob/main/server/server.go

03.功能演示

下面使用專案中的例子來講解 Milvus-migration 的使用方法。示例可在專案 README.md 中找到。

Elasticsearch -> Milvus 2.x

1. 準備 ES 資料

要遷移 ES 資料,前提假設您已經擁有屬於自己的 es Server(自建、ElasticCloud、阿里雲 ES 等),向量資料儲存在 dense_vector,以及其他欄位在 index 中,index mapping 形式如:

2. 編譯打包

首先下載遷移專案原始碼:https://github.com/zilliztech/milvus-migration

執行: go get & go build,編譯完成會在當前路徑下產生可執行檔案: milvus-migration。

3. 配置 migration.ymal config

開始遷移之前, 還需要準備遷移配置檔案:包含資料的 source、target 資料等資訊,內容示例如下:


dumper:
  worker:
    workMode: elasticsearch        ------ 工作模式:elasticsearch
    reader:
      bufferSize: 2500             --------- 從es每次批次獲取的數量
meta:
  mode: config                     -------- 固定寫法,其他資料來源遷移會有其他不同值  
  index: test_index                -------- es index
  fields:                          -------- 需要同步的es欄位有哪些:    
    - name: id                     -------- es 欄位名
      pk: true                     -------- pk=true,表示這個欄位作為milvus的主鍵, 沒設定情況下預設會採用es document _id作為主鍵          
      type: long
    - name: other_field
      maxLen: 60                   ------- 對應milvus VarChar欄位型別的maxLen, 對於varchar型別不設定maxLen則預設最大值:65535
      type: keyword
    - name: data
      type: dense_vector           ------- 向量欄位,對應milvus的 field_vector型別, 必須遷移有dense_vector的欄位
      dims: 512
  milvus:                          ------- 這部分配置非必填,設定生成的milvus表的屬性,為空則按預設值
      collection: "rename_index_test"  --- 表名,為空則 esIndex作為表名
      closeDynamicField: false         --- 為空預設為false(開啟動態列功能)
      consistencyLevel: Eventually   --- 一致性,為空按 milvus的預設級別
      shardNum: 1                      --- 分片數量,為空預設為2

source:                        ------- es server連線配置資訊,支援 serviceToken,fingerprint,cloudId/apiKey,user/pwd,ca.crt 等方式連線/認證
  es:
    urls:
      - http://localhost:9200
    username: xxx
    password: xxx
target:                       ------ 遷移到目標mivlus的bucket資訊
  mode: remote
  remote:
    outputDir: outputPath/migration/test1
    cloud: aws
    region: us-west-2
    bucket: xxx
    useIAM: true
    checkBucket: false
  milvus2x:
    endpoint: {yourMilvusAddress}:{port}
    username: ******
    password: ******

關於配置檔案更加詳細的介紹,請參考專案 README.md。

4. 執行遷移 job

將配置檔案放入任意檔案目錄下,透過執行命令方式開啟遷移任務:

./milvus-migration start --config=/{YourConfigFilePath}/migration.yaml

觀察日誌輸出,當出現類似如下日誌表示遷移成功:

[task/load_base_task.go:94] ["[LoadTasker] Dec Task Processing-------------->"] [Count=0] [fileName=testfiles/output/zwh/migration/test_mul_field4/data_1_1.json] [taskId=442665677354739304]
[task/load_base_task.go:76] ["[LoadTasker] Progress Task --------------->"] [fileName=testfiles/output/zwh/migration/test_mul_field4/data_1_1.json] [taskId=442665677354739304]
[dbclient/cus_field_milvus2x.go:86] ["[Milvus2x] begin to ShowCollectionRows"]
[loader/cus_milvus2x_loader.go:66] ["[Loader] Static: "] [collection=test_mul_field4_rename1] [beforeCount=50000] [afterCount=100000] [increase=50000]
[loader/cus_milvus2x_loader.go:66] ["[Loader] Static Total"] ["Total Collections"=1] [beforeTotalCount=50000] [afterTotalCount=100000] [totalIncrease=50000]
[migration/es_starter.go:25] ["[Starter] migration ES to Milvus finish!!!"] [Cost=80.009174459]
[starter/starter.go:106] ["[Starter] Migration Success!"] [Cost=80.00928425]
[cleaner/remote_cleaner.go:27] ["[Remote Cleaner] Begin to clean files"] [bucket=a-bucket] [rootPath=testfiles/output/zwh/migration]
[cmd/start.go:32] ["[Cleaner] clean file success!"]

除了使用命令方式,專案也支援 Restful api 來執行遷移。首先執行如下命令來啟動 Restful api server:

./milvus-migration server run -p 8080

看到以下日誌表示服務啟動成功:

將 migration.yaml 配置放在當前專案的 configs/migration.yaml, 然後呼叫api 來啟動遷移:

curl -XPOST http://localhost:8080/api/v1/start

當遷移結束後,我們也可以透過 Attu 來檢視遷移成功的總行數,也可以在 Attu 進行 load collection操作;而 collection 主鍵和 vector 欄位建立 autoIndex 索引在遷移過程會自動建立好。

訪問 swagger 來檢視服務提供的 api:http://localhost:8080/docs/index.html

ES 到 Milvus 2.x 遷移就介紹到這裡,下面我們來看下 milvus1.x -> 2.x 遷移過程。

Milvus 1.x -> Milvus 2.x

1. Milvus 1.x 資料準備 - (可跳過,Zilliz Cloud上的 Milvus 使用者遷移會用到)

為了讓使用者快速體驗,在專案原始碼的 testfiles目錄下放置了1w 條 Milvus 1.x 測試資料在test1/目錄下,目錄結構:包含 tables 和 meta.json 兩部分。快速體驗可用該測試資料:

正常情況使用者需要匯出自己的 Milvus 1.x 的 meta.json檔案,匯出方式可透過命令:

./milvus-migration export -m "user:password@tcp(adderss)/milvus?charset=utf8mb4&parseTime=True&loc=Local" -o outputDir

其中 user/password/address 為 Milvus1.x 使用的 mysql;會匯出到 outputDir,匯出前 Milvus1.x server 需要停機或者停止寫入資料。隨後將 Milvus 的 tables資料夾進行copy和meta.json放到同一個目錄下面。(Milvus 的 tables資料夾一般在 /${user}/milvus/db/tables )

目錄結構如下:

filesdir

--- meta.json    

--- tables


當準備好資料後,如果使用的 Milvus 2.x 在 Zilliz Cloud雲,則可直接在 cloud console 頁面進行遷移操作。

2. 編譯打包

專案原始碼編譯同上,最終生成可執行檔案: milvus-migration (在上面的 export 命令中也是使用該檔案命令)

3.配置 migration.ymal config

dumper:
  worker:
    limit: 2
    workMode: milvus1x    ------ 工作模式:milvus1x
    reader:
      bufferSize: 1024      ----- file reader/writer buffer size
    writer:
      bufferSize: 1024
loader:
  worker:
    limit: 16       ------- 支援同時併發遷移的表數量
meta:
  mode: local    ------ meta.json檔案存放方式,有:local, remote, mysql, sqlite, 
  localFile: /outputDir/test/meta.json
  -- mode: mysql  # milvus的後設資料mysql地址
  -- mysqlUrl: "user:password@tcp(localhost:3306)/milvus?charset=utf8mb4&parseTime=True&loc=Local"
source:        ----- milvus1.x talbes目錄檔案儲存源,可以在local, s3,minio,oss,gcp
  mode: local
  local:
    tablesDir: /db/tables/  --資料檔案tables目錄
target:           ------ 資料透過bulkInsert寫入的目標儲存位置,
  mode: remote    --- 寫入的儲存的方式可以可以是:remote 和 local(僅驗證dump功能使用)
  remote:
    outputDir: "migration/test/xx" --寫入的路徑
    ak: xxxx
    sk: xxxx
    cloud: aws   ------ 寫入的cloud, 可以是aws, gcp, ali, (如果是minio也填寫aws)
    region: us-west-2
    bucket: xxxxx
    useIAM: true
    checkBucket: false
  milvus2x:
    endpoint: "{yourMilvus2_xServerAddress}:{port}"
    username: xxxx
    password: xxxx

關於 migration.yaml 配置檔案更加詳細的介紹,請檢視專案 README.md。

4.執行遷移 Job

不同於 ES 的遷移使用一個命令即可完成遷移,目前 Milvus 1.x 和 Faiss 遷移需要執行 dump 和 load 兩個命令(後期規劃會改造成一個指令即可)。

  • dump 命令

./milvus-migration dump --config=/{YourConfigFilePath}/migration.yaml

它將 Milvus 1.x 檔案資料轉為 numpy 檔案透過 bulkInsert 寫入 target bucket.

  • load 命令

執行 load 命令,將轉換好的資料檔案匯入到 Milvus 2x 裡面:

./milvus-migration load --config=/{YourConfigFilePath}/migration.yaml

最終在 Milvus 2.x中,生成的 collection 中會有兩個欄位:id 和 data, 可透過 Attu 檢視 collection。

Faiss -> Milvus 2.x

#### 1. Faiss 資料準備

前提條件是使用者已經準備好了自己的 faiss 資料檔案。(為了能快速體驗,在專案原始碼的 testfiles 目錄下放置了 faiss 測試資料方便使用者體驗: faiss_ivf_flat.index.

2. 編譯打包

這部分同上,不再展開介紹。

3. 配置 migration.ymal config

dumper:
  worker:
    limit: 2
    workMode: faiss    ------ 工作模式:faiss
    reader:
      bufferSize: 1024
    writer:
      bufferSize: 1024
loader:
  worker:
    limit: 2
source:
  mode: local    ---- 資料來源可以為 local和 remote
  local:
    faissFile: ./testfiles/faiss/faiss_ivf_flat.index

target:
  create:            ----- 指定生成的collection屬性
    collection:
      name: test1w
      shardsNums: 2
      dim: 256
      metricType: L2

  mode: remote
  remote:            ------- 下面配置是將資料寫入到本地搭建的minio中,milvus2x也是本地
    outputDir: testfiles/output/
    cloud: aws       ---- 同樣支援 aws, gcp, ali 
    endpoint: 0.0.0.0:9000
    region: ap-southeast-1
    bucket: a-bucket
    ak: minioadmin        
    sk: minioadmin
    useIAM: false
    useSSL: false
    checkBucket: true
  milvus2x:
    endpoint: localhost:19530
    username: xxxxx
    password: xxxxx

關於Faiss 的 migration.yaml 配置檔案更加詳細的介紹,請檢視專案 README.md

4. 執行遷移 Job

  • dump 命令

./milvus-migration dump --config=/{YourConfigFilePath}/migration.yaml

它將 Faiss 檔案資料轉為numpy 格式檔案透過 bulkInsert 寫入 target bucket.

  • load 命令

執行 load 命令,將轉換好的資料檔案匯入到 Milvus 2x 裡面:

./milvus-migration load --config=/{YourConfigFilePath}/migration.yaml

完成後可透過 Attu 檢視生成的 collection 資訊進行驗證。

04.未來規劃

  • 支援 Redis 遷移到 Milvus
  • 支援 Mongodb 遷移到 Milvus
  • 支援遷移過程斷點續傳
  • 簡化遷移命令:合併 dump 和 load 過程
  • 支援其他資料來源遷移到 Milvus

參考資料

  1. Milvus-migration: https://github.com/zilliztech/milvus-migration
  2. Attu: https://milvus.io/docs/attu.md
  3. bulkinsert: https://milvus.io/docs/bulk_insert.md
  4. 官方文件: https://milvus.io/docs
  5. ES scroll api: https://www.elastic.co/guide/en/elasticsearch/reference/7.17/paginate-search-results.html#scroll-search-results

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

本文由mdnice多平臺釋出

相關文章