로컬 디스크로 Milvus QueryNode 구성하기
이 문서에서는 로컬 디스크 스토리지를 사용하도록 Milvus QueryNode를 구성하는 방법에 대해 설명합니다.
개요
Milvus는 방대한 양의 벡터 데이터를 효율적으로 저장하고 검색할 수 있도록 맞춤화된 AI 중심 벡터 데이터베이스입니다. 이미지 및 동영상 분석, 자연어 처리, 추천 시스템과 같은 작업에 이상적입니다. 최적의 성능을 보장하려면 디스크 읽기 지연 시간을 최소화하는 것이 중요합니다. 지연을 방지하고 시스템 안정성을 유지하려면 로컬 NVMe SSD를 사용하는 것이 좋습니다.
로컬 디스크 스토리지가 중요한 역할을 하는 주요 기능은 다음과 같습니다:
- 청크 캐시: 빠른 검색을 위해 로컬 디스크 캐시에 데이터를 미리 로드합니다.
- MMap: 메모리 효율성을 높이기 위해 파일 콘텐츠를 메모리에 직접 매핑합니다.
- DiskANN 인덱스: 효율적인 인덱스 관리를 위해 디스크 스토리지가 필요합니다.
이 문서에서는 클라우드 플랫폼에 Milvus Distributed를 배포하는 방법과 NVMe 디스크 스토리지를 사용하도록 쿼리 노드를 구성하는 방법에 대해 중점적으로 설명합니다. 다음 표에는 다양한 클라우드 제공업체의 권장 머신 유형이 나와 있습니다.
클라우드 제공자 | 머신 유형 |
---|---|
AWS | R6id 시리즈 |
GCP | N2 시리즈 |
Azure | Lsv3 시리즈 |
Alibaba Cloud | i3 시리즈 |
Tencent Cloud | IT5 시리즈 |
이러한 머신 유형은 NVMe 디스크 스토리지를 제공합니다. 이러한 머신 유형의 인스턴스에서 lsblk
명령을 사용하여 NVMe 디스크 스토리지가 있는지 확인할 수 있습니다. 있는 경우 다음 단계로 진행할 수 있습니다.
$ lsblk | grep nvme
nvme0n1 259:0 0 250.0G 0 disk
nvme1n1 259:1 0 250.0G 0 disk
로컬 디스크를 사용하도록 쿠버네티스 구성하기
밀버스 디스트리뷰션의 쿼리노드가 NVMe 디스크 스토리지를 사용하도록 구성하려면, 대상 쿠버네티스 클러스터의 워커 노드가 컨테이너와 이미지를 NVMe 디스크에 저장하도록 구성해야 합니다. 이 절차는 클라우드 제공자에 따라 다릅니다.
AWS
Amazon EKS를 사용하는 경우, 노드 그룹에 대한 구성 설정을 지정할 수 있는 시작 템플릿으로 관리형 노드를 사용자 정의할 수 있습니다. 다음은 Amazon EKS 클러스터의 작업자 노드에 NVMe 디스크를 마운트하는 방법의 예입니다:
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==--
위의 예에서는 NVMe 디스크가 /dev/nvme1n1
이라고 가정합니다. 특정 구성에 맞게 스크립트를 수정해야 합니다.
자세한 내용은 시작 템플릿으로 관리형 노드 사용자 지정하기를 참조하세요.
GCP
GKE(Google 쿠버네티스 엔진) 클러스터에서 로컬 SSD 스토리지를 프로비저닝하고 클러스터의 노드에 연결된 로컬 SSD 지원 임시 스토리지에서 데이터를 사용하도록 워크로드를 구성하려면 다음 명령을 실행하세요:
gcloud container node-pools create ${POOL_NAME} \
--cluster=${CLUSTER_NAME} \
--ephemeral-storage-local-ssd count=${NUMBER_OF_DISKS} \
--machine-type=${MACHINE_TYPE}
자세한 내용은 GKE에서 로컬 SSD 스토리지 프로비저닝을 참조한다.
Azure
로컬 NVMe 디스크 스토리지로 VMSS(가상 머신 스케일 세트)를 만들려면 VM 인스턴스에 사용자 지정 데이터를 전달해야 합니다. 다음은 VMSS의 VM 인스턴스에 NVMe 디스크를 연결하는 방법의 예시입니다:
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
위의 예에서는 NVMe 디스크가 /dev/nvme0n1
및 /dev/nvme1n1
이라고 가정합니다. 특정 구성에 맞게 스크립트를 수정해야 합니다.
알리바바 클라우드 및 테센트 클라우드
로컬 SSD 볼륨을 사용하는 노드 풀을 만들려면 사용자 지정 데이터를 전달해야 합니다. 다음은 사용자 지정 데이터의 예시입니다.
#!/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..."
위 예제에서는 NVMe 디스크가 /dev/nvme0n1
이라고 가정합니다. 특정 구성에 맞게 스크립트를 수정해야 합니다.
자체 IDC
자체 IDC를 실행 중이고 컨테이너에서 기본적으로 새로 마운트된 NVMe 디스크의 파일 시스템을 사용하도록 컨테이너를 구성하려는 경우 다음 단계를 따르세요:
NVMe 디스크를 마운트한다.
NVMe 디스크가 호스트 머신에 제대로 마운트되었는지 확인합니다. 원하는 디렉터리에 마운트할 수 있습니다. 예를 들어
/mnt/nvme
에 마운트하는 경우, 제대로 설정되었는지 확인하고lsblk
또는df -h
을 실행하여/mnt/nvme
에서 디스크를 사용할 수 있는지 확인합니다.컨테이너 구성 업데이트.
새 마운트를 컨테이너 스토리지의 루트 디렉터리로 사용하도록 컨테이너 구성을 수정합니다.
sudo mkdir -p /mnt/nvme/containerd /mnt/nvme/containerd/state sudo vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd]
섹션을 찾아snapshotter
및root
설정을 다음과 같이 수정합니다.[plugins."io.containerd.grpc.v1.cri".containerd] snapshotter = "overlayfs" root = "/mnt/nvme/containerd" state = "/mnt/nvme/containerd/state"
컨테이너를 다시 시작합니다.
컨테이너 서비스를 다시 시작하여 변경 사항을 적용합니다.
sudo systemctl restart containerd
디스크 성능 확인
디스크 성능을 벤치마킹하는 데 널리 사용되는 도구인 Fio를 사용하여 디스크 성능을 확인하는 것이 좋습니다. 다음은 Fio를 실행하여 디스크 성능을 테스트하는 방법의 예시입니다.
NVMe 디스크가 있는 노드에 테스트 파드를 배포합니다.
kubectl create -f ubuntu.yaml
ubuntu.yaml
파일은 다음과 같습니다: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: {}
Fio를 실행하여 디스크 성능을 테스트합니다.
# 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
출력은 다음과 같아야 합니다:
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
Milvus 배포 배포
확인 결과가 만족스러우면 다음 단계에 따라 Milvus Distributed를 배포할 수 있습니다:
헬름을 사용하여 밀버스 배포를 위한 팁
쿼리노드 파드는 기본적으로 NVMe 디스크를 EmptyDir 볼륨으로 사용한다. 최적의 성능을 보장하려면 NVMe 디스크를 쿼리노드 파드 내의 /var/lib/milvus/data
에 마운트하는 것이 좋다.
헬름을 사용하여 밀버스 디스트리뷰션을 배포하는 방법에 대한 자세한 내용은 헬름으로 쿠버네티스에서 밀버스 실행하기를 참조한다.
밀버스 오퍼레이터를 사용하여 밀버스 디스트리뷰티드 배포를 위한 팁
밀버스 오퍼레이터는 NVMe 디스크를 EmptyDir 볼륨으로 사용하도록 쿼리노드 파드를 자동으로 구성한다. MilvusCluster
사용자 정의 리소스에 다음 구성을 추가하는 것이 좋습니다:
...
spec:
components:
queryNode:
volumeMounts:
- mountPath: /var/lib/milvus/data
name: data
volumes:
- emptyDir:
name: data
이렇게 하면 쿼리노드 파드가 NVMe 디스크를 데이터 볼륨으로 사용하게 됩니다. 밀버스 오퍼레이터를 사용하여 밀버스 디스트리뷰션을 배포하는 방법에 대한 자세한 내용은 밀버스 오퍼레이터로 쿠버네티스에서 밀버스 실행하기를 참조한다.