milvus-logo
LFAI
Casa
  • Guida all'amministrazione

Configurazione di Milvus QueryNode con disco locale

Questo articolo descrive come configurare Milvus QueryNode per utilizzare l'archiviazione su disco locale.

Panoramica

Milvus è un database vettoriale incentrato sull'intelligenza artificiale e concepito per l'archiviazione e il recupero efficiente di grandi quantità di dati vettoriali. È ideale per attività come l'analisi di immagini e video, l'elaborazione del linguaggio naturale e i sistemi di raccomandazione. Per garantire prestazioni ottimali, è fondamentale ridurre al minimo la latenza di lettura del disco. L'uso di unità SSD NVMe locali è altamente consigliato per evitare ritardi e mantenere la stabilità del sistema.

Le caratteristiche principali in cui entra in gioco l'archiviazione su disco locale includono:

  • Chunk cache: Precarica i dati nella cache del disco locale per una ricerca più rapida.
  • MMap: Mappa il contenuto dei file direttamente nella memoria per una migliore efficienza della memoria.
  • Indice DiskANN: Richiede la memorizzazione su disco per una gestione efficiente dell'indice.

In questo articolo ci concentreremo sulla distribuzione di Milvus Distributed su piattaforme cloud e su come configurare il QueryNode per utilizzare lo storage su disco NVMe. La tabella seguente elenca i tipi di macchina consigliati dai vari cloud provider.

Provider cloudTipo di macchina
AWSSerie R6id
GCPSerie N2
AzureSerie Lsv3
Alibaba CloudSerie i3
Nuvola di TencentSerie IT5

Questi tipi di macchina forniscono l'archiviazione su disco NVMe. È possibile utilizzare il comando lsblk sulle istanze di questi tipi di macchina per verificare se dispongono di storage su disco NVMe. In caso affermativo, si può procedere al passo successivo.

$ lsblk | grep nvme
nvme0n1     259:0    0 250.0G  0 disk 
nvme1n1     259:1    0 250.0G  0 disk 

Configurare Kubernetes per usare il disco locale

Per configurare il QueryNode di Milvus Distributed in modo che utilizzi l'archiviazione su disco NVMe, è necessario configurare i nodi worker dei cluster Kubernetes di destinazione per archiviare i contenitori e le immagini su un disco NVMe. La procedura varia a seconda dei cloud provider.

AWS

Quando si utilizza Amazon EKS, è possibile personalizzare i nodi gestiti con modelli di lancio, in cui è possibile specificare le impostazioni di configurazione per i gruppi di nodi. Di seguito è riportato un esempio di come montare un disco NVMe sui nodi worker del cluster Amazon EKS:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==MYBOUNDARY=="

--==MYBOUNDARY==
Content-Type: text/x-shellscript; charset="us-ascii"

#!/bin/bash
echo "Running custom user data script"
if ( lsblk | fgrep -q nvme1n1 ); then
    mkdir -p /mnt/data /var/lib/kubelet /var/lib/docker
    mkfs.xfs /dev/nvme1n1
    mount /dev/nvme1n1 /mnt/data
    chmod 0755 /mnt/data
    mv /var/lib/kubelet /mnt/data/
    mv /var/lib/docker /mnt/data/
    ln -sf /mnt/data/kubelet /var/lib/kubelet
    ln -sf /mnt/data/docker /var/lib/docker
    UUID=$(lsblk -f | grep nvme1n1 | awk '{print $3}')
    echo "UUID=$UUID     /mnt/data   xfs    defaults,noatime  1   1" >> /etc/fstab
fi
echo 10485760 > /proc/sys/fs/aio-max-nr

--==MYBOUNDARY==--

Nell'esempio precedente, si assume che il disco NVMe sia /dev/nvme1n1. È necessario modificare lo script per adattarlo alla propria configurazione specifica.

Per maggiori dettagli, vedere Personalizzazione dei nodi gestiti con i modelli di lancio.

GCP

Per eseguire il provisioning dello storage Local SSD sui cluster Google Kubernetes Engine (GKE) e configurare i carichi di lavoro in modo che consumino i dati dallo storage effimero supportato da Local SSD collegato ai nodi del cluster, eseguire il seguente comando:

gcloud container node-pools create ${POOL_NAME} \
    --cluster=${CLUSTER_NAME} \
    --ephemeral-storage-local-ssd count=${NUMBER_OF_DISKS} \
    --machine-type=${MACHINE_TYPE}

Per maggiori dettagli, vedere Provisioning dello storage SSD locale su GKE.

Azure

Per creare un virtual machine scale set (VMSS) con storage su disco NVMe locale, è necessario passare dati personalizzati alle istanze VM. Di seguito viene illustrato un esempio di come collegare un disco NVMe alle istanze VM nel VMSS:

mdadm -Cv /dev/md0 -l0 -n2 /dev/nvme0n1 /dev/nvme1n1
mdadm -Ds > /etc/mdadm/mdadm.conf 
update-initramfs -u

mkfs.xfs /dev/md0
mkdir -p /var/lib/kubelet
echo '/dev/md0 /var/lib/kubelet xfs defaults 0 0' >> /etc/fstab
mount -a

Nell'esempio precedente, si ipotizza che i dischi NVMe siano /dev/nvme0n1 e /dev/nvme1n1. È necessario modificare lo script per adattarlo alla propria configurazione specifica.

Alibaba Cloud e TecentCloud

Per creare un pool di nodi che utilizza volumi SSD locali, è necessario passare i dati personalizzati. Di seguito è riportato un esempio di dati personalizzati.

#!/bin/bash
echo "nvme init start..."
mkfs.xfs /dev/nvme0n1
mkdir -p /mnt/data
echo '/dev/nvme0n1 /mnt/data/ xfs defaults 0 0' >> /etc/fstab
mount -a

mkdir -p /mnt/data/kubelet /mnt/data/containerd /mnt/data/log/pods
mkdir -p  /var/lib/kubelet /var/lib/containerd /var/log/pods

echo '/mnt/data/kubelet /var/lib/kubelet none defaults,bind 0 0' >> /etc/fstab
echo '/mnt/data/containerd /var/lib/containerd none defaults,bind 0 0' >> /etc/fstab
echo '/mnt/data/log/pods /var/log/pods none defaults,bind 0 0' >> /etc/fstab
mount -a

echo "nvme init end..."

Nell'esempio precedente, si assume che il disco NVMe sia /dev/nvme0n1. È necessario modificare lo script per adattarlo alla propria configurazione specifica.

Il proprio IDC

Se si esegue un proprio IDC e si desidera configurare i container in modo che utilizzino il filesystem su un disco NVMe appena montato per impostazione predefinita in containerd, procedere come segue:

  • Montare i dischi NVMe.

    Assicurarsi che il disco NVMe sia montato correttamente sulla macchina host. È possibile montarlo in una directory a scelta. Per esempio, se si monta su /mnt/nvme, assicurarsi che sia impostato correttamente e che sia possibile vedere il disco disponibile su /mnt/nvme eseguendo lsblk o df -h.

  • Aggiornare la configurazione di containerd.

    Modificare la configurazione di containerd per usare il nuovo mount come directory principale per lo storage dei container.

    sudo mkdir -p /mnt/nvme/containerd /mnt/nvme/containerd/state
    sudo vim /etc/containerd/config.toml
    

    Individuare la sezione [plugins."io.containerd.grpc.v1.cri".containerd] e modificare le impostazioni di snapshotter e root nel modo seguente: - Riavviare containerd.

    [plugins."io.containerd.grpc.v1.cri".containerd]
    snapshotter = "overlayfs"
    root = "/mnt/nvme/containerd"
    state = "/mnt/nvme/containerd/state"
    
  • Riavviare containerd.

    Riavviare il servizio containerd per applicare le modifiche.

    sudo systemctl restart containerd
    

Verificare le prestazioni del disco

Si consiglia di verificare le prestazioni del disco utilizzando Fio, uno strumento molto diffuso per il benchmarking delle prestazioni del disco. Di seguito è riportato un esempio di come eseguire Fio per verificare le prestazioni del disco.

  • Distribuire il pod di prova sul nodo con il disco NVMe.

    kubectl create -f ubuntu.yaml
    

    Il file ubuntu.yaml è il seguente:

    apiVersion: v1
    kind: Pod
    metadata:
    name: ubuntu
    spec:
    containers:
    - name: ubuntu
        image: ubuntu:latest
        command: ["sleep", "86400"]
        volumeMounts:
        - name: data-volume
            mountPath: /data
    volumes:
        - name: data-volume
        emptyDir: {}
    
  • Eseguire Fio per testare le prestazioni del disco.

    # enter the container
    kubectl exec pod/ubuntu -it bash
    
    # in container
    apt-get update
    apt-get install fio -y
    
    # change to the mounted dir
    cd /data
    
    # write 10GB
    fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4K -size=10G -numjobs=10 -runtime=600 -group_reporting -filename=test -name=Rand_Write_IOPS_Test
    
    # verify the read speed
    # compare with the disk performance indicators provided by various cloud providers.
    fio --filename=test --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=128 --time_based --group_reporting --name=iops-test-job --eta-newline=1  --readonly
    

    L'output dovrebbe essere simile a questo:

    Jobs: 128 (f=128): [r(128)][100.0%][r=1458MiB/s][r=373k IOPS][eta 00m:00s]
    iops-test-job: (groupid=0, jobs=128): err= 0: pid=768: Mon Jun 24 09:35:06 2024
    read: IOPS=349k, BW=1364MiB/s (1430MB/s)(160GiB/120067msec)
        slat (nsec): min=765, max=530621k, avg=365836.09, stdev=4765464.96
        clat (usec): min=35, max=1476.0k, avg=23096.78, stdev=45409.13
        lat (usec): min=36, max=1571.6k, avg=23462.62, stdev=46296.74
        clat percentiles (usec):
        |  1.00th=[    69],  5.00th=[    79], 10.00th=[    85], 20.00th=[    95],
        | 30.00th=[   106], 40.00th=[   123], 50.00th=[   149], 60.00th=[ 11469],
        | 70.00th=[ 23462], 80.00th=[ 39584], 90.00th=[ 70779], 95.00th=[103285],
        | 99.00th=[189793], 99.50th=[244319], 99.90th=[497026], 99.95th=[591397],
        | 99.99th=[767558]
    bw (  MiB/s): min=  236, max= 4439, per=100.00%, avg=1365.82, stdev= 5.02, samples=30591
    iops        : min=60447, max=1136488, avg=349640.62, stdev=1284.65, samples=30591
    lat (usec)   : 50=0.01%, 100=24.90%, 250=30.47%, 500=0.09%, 750=0.31%
    lat (usec)   : 1000=0.08%
    lat (msec)   : 2=0.32%, 4=0.59%, 10=1.86%, 20=8.20%, 50=17.29%
    lat (msec)   : 100=10.62%, 250=4.80%, 500=0.38%, 750=0.09%, 1000=0.01%
    lat (msec)   : 2000=0.01%
    cpu          : usr=0.20%, sys=0.48%, ctx=838085, majf=0, minf=9665
    IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
        submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
        complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
        issued rwts: total=41910256,0,0,0 short=0,0,0,0 dropped=0,0,0,0
        latency   : target=0, window=0, percentile=100.00%, depth=64
    

Distribuire Milvus distribuito

Una volta che i risultati della verifica sono soddisfacenti, è possibile distribuire Milvus Distributed con i seguenti passaggi:

Suggerimenti per la distribuzione di Milvus Distributed con Helm

Il pod QueryNode utilizza i dischi NVMe come volumi EmptyDir per impostazione predefinita. Si consiglia di montare i dischi NVMe su /var/lib/milvus/data all'interno dei pod QueryNode per garantire prestazioni ottimali.

Per i dettagli su come distribuire Milvus Distributed usando Helm, vedere Eseguire Milvus in Kubernetes con Helm.

Suggerimenti per la distribuzione di Milvus Distributed con Milvus Operator

Milvus Operator configura automaticamente il pod QueryNode per utilizzare i dischi NVMe come volumi EmptyDir. Si consiglia di aggiungere le seguenti configurazioni alla risorsa personalizzata MilvusCluster:

...
spec:
  components:
    queryNode:
      volumeMounts:
      - mountPath: /var/lib/milvus/data
        name: data
      volumes:
      - emptyDir:
        name: data

Questo assicura che il pod QueryNode utilizzi il disco NVMe come volume di dati. Per i dettagli su come distribuire Milvus Distributed usando Milvus Operator, vedere Eseguire Milvus in Kubernetes con Milvus Operator.

Tradotto daDeepL

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Questa pagina è stata utile?