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 cloud | Tipo di macchina |
---|---|
AWS | Serie R6id |
GCP | Serie N2 |
Azure | Serie Lsv3 |
Alibaba Cloud | Serie i3 |
Nuvola di Tencent | Serie 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
eseguendolsblk
odf -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 disnapshotter
eroot
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.