Użyj rozproszonego akceleratora do przechowywania w chmurze z BlobFuse2 (podgląd)

Użyj BlobFuse2 z rozproszonym akceleratorem dla magazynu w chmurze (DACS), aby odczytać dane Azure Blob przez ścieżki systemu plików Linux. Aplikacje zachowują istniejący kod do odczytu plików, podczas gdy BlobFuse2 obsługuje dane w pamięci podręcznej przez DACS i pobiera brakujące dane z Blob Storage.

Sterownik Azure Blob Container Storage Interface (CSI) montuje kontener przez wolumin trwały (PV) oraz żądanie woluminu trwałego (PVC). Azure Blob Storage pozostaje trwałym źródłem prawdy.

Ten artykuł obejmuje konfigurację, weryfikację ścieżki odczytu oraz wyniki benchmarków Standard Storage.

Prerequisites

  • Klaster AKS, który spełnia wymagania dotyczące regionu platformy Azure i wersji Kubernetes w przewodniku Szybki start DACS.
  • Węzły pamięci podręcznej Linuksa z lokalnymi dyskami NVMe dedykowanymi do DACS.
  • Ubuntu Linux workload nodes dla aplikacyjnych podów, które montują BlobFuse2.
  • Kontener Azure Blob zawierający dane aplikacji.
  • Istniejąca tożsamość zarządzana przypisana przez użytkownika do uwierzytelniania obiektów blob.
  • Azure CLI i kubectl.
  • Uprawnienia do włączenia DACS i zarządzanego sterownika CSI Azure Blob, tworzenia zasobów Kubernetes, zarządzania federacyjnymi poświadczeniami tożsamości oraz przypisania wymaganej roli dostępu do danych Blob.
  • Na każdym kwalifikującym się węźle roboczym systemu Linux musi być zainstalowany BlobFuse2 2.5.6 lub nowszy. Informacje o obsłudze i ograniczeniach pamięci podręcznej rozproszonej można znaleźć w informacjach o wydaniu BlobFuse2 2.5.6.
  • Sterownik Azure Blob CSI zarządzany przez AKS v1.27.11, z włączonym wydawcą AKS OIDC oraz Tożsamość obciążeń Microsoft Entra dla uwierzytelniania wyłącznie tokenowego.

Important

Użyj montowania tylko do odczytu dla każdego kontenera. Weryfikuj aktywność DACS za pomocą metryk serwera podręcznego i logów BlobFuse2.

DACS traktuje klaster Kubernetes jako pojedynczą domenę zaufania i nie zapewnia izolacji tenantów. Nie używaj go w klastrze multitenant. Tożsamość obciążenia autoryzuje dostęp do Blob Storage; nie izoluje danych w pamięci podręcznej. Więcej informacji można znaleźć w modelu bezpieczeństwa DACS. DACS traktuje klaster Kubernetes jako pojedynczą domenę zaufania i nie zapewnia izolacji tenantów. Nie używaj go w klastrze wielodzierżawczym. Tożsamość obciążenia autoryzuje dostęp do Blob Storage; nie izoluje danych w pamięci podręcznej. Więcej informacji można znaleźć w modelu bezpieczeństwa DACS.

Ustawianie zmiennych

Uruchamiaj polecenia w tej samej sesji Bash. Zastąp symbole zastępcze nazwą klastra, kontenera magazynu i istniejącą tożsamością zarządzaną przypisaną przez użytkownika:

SUBSCRIPTION_ID="<subscription-id>"
RESOURCE_GROUP="<aks-resource-group>"
CLUSTER_NAME="<aks-cluster-name>"
WORKLOAD_NODE_POOL="<blobfuse-ready-node-pool>"
STORAGE_RESOURCE_GROUP="<storage-resource-group>"
STORAGE_ACCOUNT="<storage-account-name>"
STORAGE_CONTAINER="<existing-container-name>"
IDENTITY_RESOURCE_GROUP="<managed-identity-resource-group>"
IDENTITY_NAME="<managed-identity-name>"
CACHE_NAMESPACE=dacs-cache-system
CACHE_NAME=cache-sample
WORKLOAD_NAMESPACE=blobfuse-dacs
SERVICE_ACCOUNT=blobfuse-reader

az account set --subscription "$SUBSCRIPTION_ID"
az aks get-credentials --resource-group "$RESOURCE_GROUP" --name "$CLUSTER_NAME"

BLOBFUSE_CLIENT_ID=$(az identity show \
  --resource-group "$IDENTITY_RESOURCE_GROUP" \
  --name "$IDENTITY_NAME" \
  --query clientId --output tsv)

Zainstaluj rozproszony akcelerator do przechowywania w chmurze

Aby zainstalować DACS, przygotuj dedykowane dyski pamięci podręcznej, utwórz zasób pamięci podręcznej i zweryfikuj gotowość. Zobacz Wprowadzenie do rozproszonego akceleratora dla magazynu w chmurze na platformie AKS.

Pobierz nazwę hosta discovery dla ready Cache:

CACHE_DISCOVERY_HOST=$(kubectl get cache "$CACHE_NAME" \
  --namespace "$CACHE_NAMESPACE" \
  -o jsonpath='{.status.discoveryURL}')

test -n "$CACHE_DISCOVERY_HOST"

Użyj nazwy hosta opublikowanej przez Twój zasób pamięci podręcznej oraz jego skonfigurowany port. Quickstart używa portu 9065.

Włącz sterownik CSI Azure Blob i zweryfikowaj BlobFuse2

Użyj sterownika zarządzanego przez AKS. Postępuj zgodnie z Włączanie sterownika CSI usługi Azure Blob w AKS.

Używaj AKS do zarządzania uaktualnieniami sterowników CSI. Upewnij się, że każdy kwalifikujący się węzeł roboczy działa na BlobFuse2 2.5.6 lub nowszym i koordynuj aktualizacje pakietów z odmontowaniem woluminów.

Sprawdź proces montowania

Sprawdź gotowość CSI za pomocą zestawu DaemonSet węzła.

kubectl get csidriver blob.csi.azure.com
kubectl rollout status daemonset/csi-blob-node \
  --namespace kube-system --timeout=10m
kubectl get pods --namespace kube-system \
  --selector app=csi-blob-node --output wide
kubectl get daemonset csi-blob-node --namespace kube-system \
  --output jsonpath='{range .spec.template.spec.containers[*]}{.name}{": "}{.image}{"\n"}{end}'

Potwierdź, że obraz kontenera blob jest wersji v1.27.11 lub nowszy.

Wersja obrazu sterownika CSI nie identyfikuje wersji BlobFuse2 zainstalowanej na hostze. Dla każdego kwalifikującego się węzła Ubuntu wybierz jego csi-blob-node pod z poprzedniego wyjścia i zweryfikuj plik binarny hosta używany przez proxy'ego CSI:

BLOB_CSI_POD="<csi-blob-node-pod-name>"

kubectl exec --namespace kube-system "$BLOB_CSI_POD" --container blob -- \
  nsenter --mount=/proc/1/ns/mnt -- /usr/bin/blobfuse2 --version

kubectl exec --namespace kube-system "$BLOB_CSI_POD" --container blob -- \
  nsenter --mount=/proc/1/ns/mnt -- /usr/bin/blobfuse2 mount --help

Potwierdź wersję 2.5.6 lub nowszą oraz --distributed-cache-* opcje użyte w konfiguracji woluminu w następnej sekcji.

Aktualizuj BlobFuse2, gdy obraz węzła jest w starszej wersji

Jeśli brakuje pliku binarnego hosta lub jest on starszy niż 2.5.6, skonfiguruj kontener init zarządzanego sterownika install-blobfuse-proxy CSI, aby zainstalować wymagany pakiet BlobFuse2. Pomiń ten krok, gdy wszystkie uprawnione węzły mają już wersję 2.5.6 lub nowszą.

Ta aktualizacja korzysta z instalatora pakietów na węzłach Ubuntu, które potrzebują dostępu do skonfigurowanych repozytoriów pakietów Ubuntu i Microsoft. Nie zastępuje on zarządzanego obrazu sterownika CSI ani nie instaluje osobnego sterownika.

Important

Łatka wprowadza csi-blob-node DaemonSet w całym klastrze, nie tylko w puli węzłów obciążenia. Sprawdź wersje hostów na wszystkich dotkniętych węzłach Ubuntu i skoordynuj aktualizację z odmontowaniem woluminów przed kontynuowaniem. Jeśli węzeł już uruchamia wersję nowszą niż 2.5.6, ustaw poniższe BLOBFUSE2_VERSION na tę wersję lub późniejszy dostępny pakiet. Obniżanie poziomu pakietów jest wyłączone.

Zapisz obecny DaemonSet i stwórz patch:

kubectl get daemonset csi-blob-node --namespace kube-system \
  --output yaml > csi-blob-node-before.yaml

BLOBFUSE2_VERSION=2.5.6

cat <<EOF > csi-blob-proxy-patch.yaml
spec:
  template:
    spec:
      initContainers:
        - name: install-blobfuse-proxy
          env:
            - name: INSTALL_BLOBFUSE
              value: "false"
            - name: INSTALL_BLOBFUSE2
              value: "true"
            - name: BLOBFUSE2_VERSION
              value: "$BLOBFUSE2_VERSION"
            - name: INSTALL_BLOBFUSE_PROXY
              value: "true"
            - name: ALLOW_PACKAGE_INSTALL_DOWNGRADE
              value: "false"
EOF

kubectl patch daemonset csi-blob-node --namespace kube-system \
  --type strategic --patch-file csi-blob-proxy-patch.yaml

kubectl rollout status daemonset/csi-blob-node \
  --namespace kube-system --timeout=15m

Poprawka merge aktualizuje nazwany kontener init i wpisy środowiska, zachowując jednocześnie jego obraz i inne ustawienia. Informacje o elementach sterujących wyboru pakietów można znaleźć w instalatorze serwera proxy Blob CSI.

Po wdrożeniu ponownie wymień pody CSI i powtórz weryfikację binarną hosta na każdym kwalifikowanym węźle roboczym. Sprawdź wersję 2.5.6 lub nowszą oraz opcje pamięci podręcznej rozproszonej przed zamontowaniem wolumínu. Istniejące procesy montażu BlobFuse2 nie zmieniają wersji po zmianie pakietu; odtwórz ich montowania, aby użyć zaktualizowanego pliku binarnego.

Jeśli wdrożenie się nie powiedzie, sprawdź logi instalatora dotyczące dotkniętego podu:

kubectl logs --namespace kube-system "<csi-blob-node-pod-name>" \
  --container install-blobfuse-proxy

Aktualizacje AKS mogą doprowadzić zarządzony zestaw DaemonSet do zgodności. Sprawdź ponownie plik binarny hosta i ustawienia instalatora po aktualizacji sterownika CSI lub obrazu węzła. Gdy obraz węzła dostarczy wymaganą wersję BlobFuse2, usuń tymczasowe nadpisanie wersji pakietu jako część tej aktualizacji.

Konfiguruj uwierzytelnianie obiektu Blob

Użyj federowanej tożsamości obciążenia AKS z uwierzytelnianiem obiektów blob wyłącznie za pomocą tokenów. Konfiguracja woluminu umożliwia włączenie tego trybu za pomocą mountWithWorkloadIdentityToken: "true".

Wykonaj Enable OIDC i Tożsamość obciążeń Microsoft Entra, a następnie utwórz workload ServiceAccount:

kubectl create namespace "$WORKLOAD_NAMESPACE"

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: $SERVICE_ACCOUNT
  namespace: $WORKLOAD_NAMESPACE
  annotations:
    azure.workload.identity/client-id: "$BLOBFUSE_CLIENT_ID"
EOF

Powiąż ServiceAccount ze swoją tożsamością zarządzaną i przyznaj dostęp w zakresie kontenerowym:

OIDC_ISSUER=$(az aks show \
  --resource-group "$RESOURCE_GROUP" \
  --name "$CLUSTER_NAME" \
  --query oidcIssuerProfile.issuerUrl --output tsv)

az identity federated-credential create \
  --name blobfuse-dacs-reader \
  --identity-name "$IDENTITY_NAME" \
  --resource-group "$IDENTITY_RESOURCE_GROUP" \
  --issuer "$OIDC_ISSUER" \
  --subject "system:serviceaccount:$WORKLOAD_NAMESPACE:$SERVICE_ACCOUNT" \
  --audiences api://AzureADTokenExchange

IDENTITY_PRINCIPAL_ID=$(az identity show \
  --resource-group "$IDENTITY_RESOURCE_GROUP" \
  --name "$IDENTITY_NAME" \
  --query principalId --output tsv)

STORAGE_ID=$(az storage account show \
  --resource-group "$STORAGE_RESOURCE_GROUP" \
  --name "$STORAGE_ACCOUNT" \
  --query id --output tsv)

az role assignment create \
  --assignee-object-id "$IDENTITY_PRINCIPAL_ID" \
  --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Contributor" \
  --scope "$STORAGE_ID/blobServices/default/containers/$STORAGE_CONTAINER"

Przypisanie ról opiera się na wytycznych dotyczących montowania wyłącznie tokenów CSI. Poczekaj, aż się propaguje, przed testowaniem. Obciążenie to uzyskuje dostęp do Blob Storage przez federacyjną tożsamość i montaż tylko do odczytu.

Konfiguruj wolumin BlobFuse2 tylko do odczytu

Pobierz adres IP usługi DNS klastra dla nazwy hosta lokalnej dla klastra pamięci podręcznej:

CLUSTER_DNS_IP=$(az aks show \
  --resource-group "$RESOURCE_GROUP" \
  --name "$CLUSTER_NAME" \
  --query networkProfile.dnsServiceIp --output tsv)

test -n "$CLUSTER_DNS_IP"

Pozwól węzłom obciążenia na dostęp do DNS klastra, punktów końcowych DACS oraz Azure Blob Storage na wypadek błędów cache i mechanizmu awaryjnego.

Stwórz statyczne PV i PVC dla swojego istniejącego kontenera. Zasada Retain zachowuje dane po usunięciu roszczenia:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
  name: blobfuse-dacs-pv
spec:
  capacity:
    storage: 1Ti
  accessModes:
    - ReadOnlyMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: ""
  mountOptions:
    - --read-only=true
    - --allow-other=true
    - --disable-kernel-cache=true
    - --block-cache=false
    - --streaming=false
    - --preload=false
    - --distributed-cache-discovery-endpoint=$CACHE_DISCOVERY_HOST:9065
    - --distributed-cache-dns-server=$CLUSTER_DNS_IP
    - --distributed-cache-block-size=16
    - --distributed-cache-node-memory=1024
    - --distributed-cache-prefetch=16
    - --distributed-cache-parallelism=16
  csi:
    driver: blob.csi.azure.com
    readOnly: true
    volumeHandle: "$STORAGE_RESOURCE_GROUP#$STORAGE_ACCOUNT#$STORAGE_CONTAINER#blobfuse-dacs"
    volumeAttributes:
      protocol: fuse2
      resourceGroup: "$STORAGE_RESOURCE_GROUP"
      storageAccount: "$STORAGE_ACCOUNT"
      containerName: "$STORAGE_CONTAINER"
      clientID: "$BLOBFUSE_CLIENT_ID"
      mountWithWorkloadIdentityToken: "true"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: blobfuse-dacs-pvc
  namespace: $WORKLOAD_NAMESPACE
spec:
  accessModes:
    - ReadOnlyMany
  storageClassName: ""
  volumeName: blobfuse-dacs-pv
  resources:
    requests:
      storage: 1Ti
EOF

Użyj unikalnej nazwy PV i volumeHandle dla każdego woluminu. Deklaracja 1Ti podaje wartość pojemności dla wiązania PV/PVC.

Konfiguruj buforowanie za pomocą opcji --distributed-cache-*. Komponent rozproszonej pamięci podręcznej zarządza swoją lokalną warstwą pamięci podręcznej bloków.

Przykład przydziela 1 024 MiB do lokalnej pamięci podręcznej i wstępnie pobiera 16 bloków. Zaplanuj pamięć osobno na pody aplikacji, montaże BlobFuse2 po stronie hosta oraz serwery DACS w kolokacji.

Zamontuj wolumin w obciążeniu roboczym

Ustaw DATA_FILE na ścieżkę pliku względem katalogu głównego kontenera. To obciążenie Python odczytuje pierwsze 4 MiB dwa razy i porównuje sumy kontrolne:

DATA_FILE="<existing-file-path>"
WORKLOAD_IMAGE="python:3.12-slim-bookworm"

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: blobfuse-dacs-reader
  namespace: $WORKLOAD_NAMESPACE
  labels:
    azure.workload.identity/use: "true"
spec:
  serviceAccountName: $SERVICE_ACCOUNT
  restartPolicy: Never
  nodeSelector:
    kubernetes.io/os: linux
    agentpool: "$WORKLOAD_NODE_POOL"
  containers:
    - name: reader
      image: $WORKLOAD_IMAGE
      command:
        - python3
        - -c
        - |
          import hashlib
          import os
          import time
          from pathlib import Path

          path = Path("/mnt/blob") / os.environ["DATA_FILE"]
          previous = None
          for attempt in range(2):
              with path.open("rb") as stream:
                  data = stream.read(4 * 1024 * 1024)
              if not data:
                  raise RuntimeError("The selected file returned no data")
              digest = hashlib.sha256(data).hexdigest()
              if previous is not None and digest != previous:
                  raise RuntimeError("Repeated reads returned different bytes")
              print(f"read={attempt + 1} bytes={len(data)} sha256={digest}", flush=True)
              previous = digest
              time.sleep(5)
      env:
        - name: DATA_FILE
          value: "$DATA_FILE"
      resources:
        requests:
          cpu: "1"
          memory: 128Mi
        limits:
          cpu: "1"
          memory: 256Mi
      volumeMounts:
        - name: blob
          mountPath: /mnt/blob
          readOnly: true
  volumes:
    - name: blob
      persistentVolumeClaim:
        claimName: blobfuse-dacs-pvc
        readOnly: true
EOF

kubectl get pvc blobfuse-dacs-pvc --namespace "$WORKLOAD_NAMESPACE"
kubectl logs --namespace "$WORKLOAD_NAMESPACE" \
  blobfuse-dacs-reader --follow --pod-running-timeout=5m

Aplikacja odczytuje /mnt/blob/<path>. Selektor węzła przypisuje go do puli ze zweryfikowaną instalacją BlobFuse2.

Sprawdź ścieżkę odczytu DACS

Konfiguruj scraping dla każdego podu cache-server, stosując się do Monitor distributed accelerator for cloud storage.

  1. Potwierdź, że PVC jest powiązane z PV i że montowanie korzysta z oczekiwanych opcji wykrywania, DNS i tylko do odczytu.
  2. Sprawdź logi CSI i BlobFuse2 pod kątem zainstalowanej wersji oraz połączeń z oczekiwanymi serwerami cache.
  3. Zapisz punkt odniesienia dla cache_server_request_counter{request_type="Download",status="Success"}, sumowany tylko na podach serwerowych należących do Twojego Cache.
  4. Pozwól na ukończenie populacji w tle, a następnie powtórz odczyty we wszystkich węzłach obciążenia. Skoreluj udaną aktywność pobierania na serwerze z logami BlobFuse2 i telemetrią Blob, aby potwierdzić rozproszone ponowne użycie.

Używaj sum kontrolnych do weryfikacji integralności danych oraz liczników żądań do weryfikacji ścieżki pamięci podręcznej. Szczegółowe polecenia można znaleźć w artykule Zweryfikuj ścieżkę żądań DACS.

Zweryfikowanie ponownego użycia w dwóch węzłach

Wstępne obciążenie odczytuje się dwukrotnie z jednego węzła, który może ponownie wykorzystać lokalną pamięć podręczną. Aby zweryfikować ponowne użycie rozproszone, użyj dwóch gotowych węzłów ze zweryfikowanej puli obciążeń oraz pliku testowego, którego nie odczytano za pośrednictwem tej pamięci podręcznej. Wybierz plik na tyle mały, by zmieścił się w pamięci podręcznej i uzyskaj oczekiwany SHA-256 z oryginalnego źródła lub zaufanego manifestu. Początkowe obciążenie odczytuje dane dwukrotnie z jednego węzła, który może ponownie wykorzystać lokalną pamięć podręczną. Aby zweryfikować ponowne użycie rozproszone, użyj dwóch gotowych węzłów ze zweryfikowanej puli obciążeń oraz pliku testowego, którego nie odczytano za pośrednictwem tej pamięci podręcznej. Wybierz plik na tyle mały, by zmieścił się w pamięci podręcznej i uzyskaj oczekiwany SHA-256 z oryginalnego źródła lub zaufanego manifestu.

Użyj pamięci podręcznej dedykowanej temu testowi, aby niezwiązane obciążenia nie wpływały na liczniki żądań. Wymień odpowiednie węzły, a następnie ustaw etykiety nazw hostów, ścieżkę pliku względem korzenia kontenera oraz oczekiwaną sumę kontrolną: Wymień odpowiednie węzły, a następnie ustaw etykiety nazw hostów, ścieżkę pliku względem korzenia kontenera oraz oczekiwaną sumę kontrolną:

kubectl get nodes --selector "agentpool=$WORKLOAD_NODE_POOL" \
  --output wide --label-columns kubernetes.io/hostname

COLD_NODE="<first-node-hostname-label>"
WARM_NODE="<different-node-hostname-label>"
VALIDATION_FILE="<existing-uncached-file-path>"
EXPECTED_SHA256="<expected-full-file-sha256>"

Utwórz dwa czytniki, które będą utrzymywać aktywne montowania podczas wykonywania kontroli i oczekiwania na populację w tle:

create_validation_reader() {
  local name="$1" node="$2"
  if [ -z "$COLD_NODE" ] || [ -z "$WARM_NODE" ] || [ "$COLD_NODE" = "$WARM_NODE" ]; then
    echo "ERROR: choose two different workload nodes." >&2
    return 1
  fi

  cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: $name
  namespace: $WORKLOAD_NAMESPACE
  labels:
    azure.workload.identity/use: "true"
spec:
  serviceAccountName: $SERVICE_ACCOUNT
  restartPolicy: Never
  nodeSelector:
    kubernetes.io/os: linux
    agentpool: "$WORKLOAD_NODE_POOL"
    kubernetes.io/hostname: "$node"
  containers:
    - name: reader
      image: $WORKLOAD_IMAGE
      command: ["sleep", "86400"]
      resources:
        requests:
          cpu: "1"
          memory: 128Mi
        limits:
          cpu: "1"
          memory: 256Mi
      volumeMounts:
        - name: blob
          mountPath: /mnt/blob
          readOnly: true
  volumes:
    - name: blob
      persistentVolumeClaim:
        claimName: blobfuse-dacs-pvc
        readOnly: true
EOF
}

create_validation_reader blobfuse-dacs-cold "$COLD_NODE" &&
create_validation_reader blobfuse-dacs-warm "$WARM_NODE" &&
kubectl wait pod/blobfuse-dacs-cold pod/blobfuse-dacs-warm \
  --namespace "$WORKLOAD_NAMESPACE" --for=condition=Ready --timeout=5m &&
kubectl get pods blobfuse-dacs-cold blobfuse-dacs-warm \
  --namespace "$WORKLOAD_NAMESPACE" --output wide

Potwierdź, że oba czytniki są gotowe na różnych węzłach. Nie czytaj jeszcze pliku z warm node. Potwierdź, że oba czytniki są gotowe na różnych węzłach. Nie czytaj jeszcze pliku z ciepłego węzła.

Przeczytaj i zweryfikuj cały plik z zimnego węzła:

kubectl exec --namespace "$WORKLOAD_NAMESPACE" blobfuse-dacs-cold -- \
  sh -c 'set -eu; cd /mnt/blob; printf "%s  %s\n" "$1" "$2" | sha256sum --check' \
  sh "$EXPECTED_SHA256" "$VALIDATION_FILE"

Zatrzymaj się, jeśli sprawdzenie sumy kontrolnej się nie powiedzie. Utrzymuj czytnik zimnego startu włączony i korzystaj z metryk serwera pamięci podręcznej, aby potwierdzić, że populacja w tle jest kompletna. Tuż przed ciepłym odczytem zarejestruj wartość bazową licznika udanych pobrań na serwerach należących do pamięci podręcznej. Zatrzymaj się, jeśli sprawdzenie sumy kontrolnej się nie powiedzie. Utrzymuj czytnik zimnego startu włączony i korzystaj z metryk serwera pamięci podręcznej, aby potwierdzić, że populacja w tle jest kompletna. Tuż przed odczytem z rozgrzanej pamięci podręcznej zapisz punkt odniesienia pomyślnego licznika pobrań na serwerach należących do Twojej usługi Cache.

Odczytaj i zweryfikuj ten sam plik z drugiego węzła:

kubectl exec --namespace "$WORKLOAD_NAMESPACE" blobfuse-dacs-warm -- \
  sh -c 'set -eu; cd /mnt/blob; printf "%s  %s\n" "$1" "$2" | sha256sum --check' \
  sh "$EXPECTED_SHA256" "$VALIDATION_FILE"

Oba sprawdzenia sumy kontrolnej muszą raportować OK, a licznik pomyślnych pobrań z pamięci podręcznej musi wzrosnąć podczas drugiego odczytu. Samo dopasowanie sum kontrolnych nie dowodzi rozproszonego ponownego użycia. Jeśli licznik nie wzrośnie, stosuj się do diagnostyki awaryjnej w Rozwiązywanie problemów z integracją, zamiast deklarować sukces.

Optymalizuj wydajność odczytu

Dostrajaj wejście i wyjście aplikacji osobno od ustawień pamięci podręcznej BlobFuse2:

Setting Description
Rozmiar operacji wejścia/wyjścia aplikacji i liczba wątków Zakresy bajtów i współbieżność wymagane przez aplikację.
--distributed-cache-block-size Rozmiar bloku lokalnej i rozproszonej pamięci podręcznej w MiB.
--distributed-cache-node-memory Lokalne ustawienie pamięci podręcznej bloków w MiB dla punktu montowania.
--distributed-cache-prefetch Liczba bloków do wstępnego pobrania.
--distributed-cache-parallelism Równoczesne pobieranie bloków, w tym operacje wstępnego pobierania.
Dobór rozmiaru zasobów pamięci podręcznej Liczba serwerów DACS, pojemność lokalnego NVMe, procesor, pamięć oraz wątki serwera.

Mierz dostęp sekwencyjny i losowy osobno. Dostrajaj rozmiar bloku, wstępne pobieranie i współbieżność, monitorując przepustowość, pamięć, ruch do/z origin i ograniczanie prędkości.

Do wdrożeń współlokowanych rezerwuj procesor, pamięć, przepustowość sieciową oraz lokalną pojemność dysku zarówno dla procesów roboczych aplikacji, jak i serwerów cache.

Zmienione opcje montażu można zastosować poprzez skoordynowane odmontowanie i ponowne zamontowanie dla wszystkich podów dzielących ten wolumin. Sprawdź nowe opcje w logach CSI.

Wyniki testu wydajności standardowego magazynu

Benchmarki porównują sam BlobFuse2 z dedykowanymi i współlokowanymi DAC-ami na koncie StorageV2 Standard_LRS w warstwie Gorąca w centralnych Stanach Zjednoczonych. Każdy profil obejmuje pięć poziomów liczby wątków w trzech konfiguracjach.

Scenariusze wdrażania

  • Dedykowane DACS: Procesy robocze aplikacji i serwery pamięci podręcznej DACS działają na oddzielnych pulach węzłów.
  • Współlokalizowane DACS: Procesy robocze aplikacji i serwery pamięci podręcznej DACS dzielą te same węzły.

Sam BlobFuse2 stanowi podstawę dla obu scenariuszy.

konfiguracja testowa

Setting Skonfigurowana konfiguracja
VMs Serwery cache: Standard_E192ids_v6 * 10; workery: Standard_E192ids_v6 * 10
Limity zasobów serwera DACS 32 CPU i 128 GiB pamięci na serwer.
Natywne żądania zasobów serwera diagramów 250m CPU i 100Mi pamięć na serwer.
Benchmark Elbencho3.0-38; Głębokość I/O 1.
Dataset 800 istniejących plików o rozmiarze 10 GiB, łącznie 8 000 GiB; pięć plików na każdy wątek I/O.
BlobFuse2 Montowania tylko do odczytu; wyłączona pamięć podręczna jądra.
Pamięć podręczna klienta bloki o rozmiarze 16 MiB; wstępne pobieranie 128 bloków; poziom równoległości 128; natywne określanie rozmiaru pamięci.

Każdy przypadek wykorzystywał nowe procesy robocze i zasoby pamięci podręcznej. Wyniki to pomiary łączne, z liczbą wątków w przeliczeniu na proces roboczy.

Odczyty sekwencyjne

Testy sekwencyjne przeprowadzono z użyciem operacji wejścia/wyjścia o rozmiarze 16 MiB oraz pięciu iteracji odczytu dla każdego przypadku. Zimna wydajność to pierwsza iteracja. Przepustowość dla ciepłego uruchomienia i wariant bazowy tylko BlobFuse to średnie z iteracji od 2 do 5. Wartości to zagregowane MiB/s.

Wątki na pracownika tylko BlobFuse Chłodzenie dedykowane Tryb utrzymywania ciepła Współlokalizowane chłodzenie Kolokowane ciepło
1 18 074 15 689 19 976,75 15 564 20 443,5
2 18 745 18 923 36 779,75 19 380 36 827,75
4 21 497 22 028 41 211,75 23 793 44 692,25
8 25 544 25 970 42 445 24 532 47 158,25
16 25 953,25 21 296 43 082,25 22 899 47 760,75

Przy 16 wątkach na pracownika, kolokowana przepustowość warm była o 84% wyższa niż w przypadku samego BlobFuse i o 10,9% wyższa niż dedykowana przepustowość warm.

Szacowane oszczędności przepustowości źródłowej

Zachowana telemetria wskazuje na około 70% niższą średnią przepustowość Blob-origin dla dedykowanych i współlokowanych DACS w porównaniu do BlobFuse-only w dopasowanych testach sekwencyjnych, w tym początkowej populacji cold-cache.

Losowe odczyty 4-KiB

Testy losowe wykorzystują 4-KiB I/O z -i 1 --rand --infloop i czasem działania 300 sekund. Każdy przypadek podaje jeden zagregowany pomiar IOPS, w tym populację cache.

Wątki na proces roboczy IOPS tylko w BlobFuse Dedykowane IOPS IOPS w miejscu współlokacyjnym
1 59 503 530
2 117 952 882
4 236 1 586 1 446
8 448 2,004 2,046
16 540 1 804 1 809

Oba scenariusze DACS osiągają szczyt na poziomie ośmiu wątków na pracownika. Współlokalizowany DACS osiąga 2 046 IOPS, czyli 4,57 razy więcej niż wynik tylko BlobFuse przy tej samej liczbie wątków.

Rozwiązywanie problemów z integracją

Area Action
Wersja i opcje montowania Sprawdź wersję BlobFuse2 po stronie hosta oraz opcje --distributed-cache-* BlobFuse2.
Aktywność pamięci podręcznej Koreluj liczniki pobierania serwera cache z logami BlobFuse2 i telemetrią Blob.
Wykrywanie i DNS Weryfikacja --distributed-cache-dns-server, dostęp węzła do DNS klastra oraz usługi wykrywania pamięci podręcznej.
Authentication Zweryfikuj sfederowane konto ServiceAccount, rolę tożsamości, wersję CSI oraz sterownik mountWithWorkloadIdentityToken: "true".
Pamięć węzła Przydziel pamięć dla pamięci cache punktów montowania, populacji w tle, podów aplikacji oraz współlokowanych serwerów DACS.
Aktualizacje konfiguracji Ponownie zamontuj volume i potwierdź nowe opcje w logach CSI.

Aby rozwiązywać problemy z uchwytem pamięci, zobacz Troubleshoot BlobFuse2 oraz przewodnik po debugowaniu sterowników Blob CSI.

Zidentyfikuj lokalną pamięć podręczną lub przełączenie awaryjne do origin

Udane montowanie lub odczyt nie dowodzi, że DACS dostarcza dane:

  • Jeśli logi CSI raportują BlobFuse2 distributed-cache support could not be verified, sterownik usuwa opcje rozproszonej pamięci podręcznej i wybiera lokalną pamięć podręczną bloków. Sprawdź wersję i możliwości montażu hosta BlobFuse2, a następnie skoordynuj odmontowanie i ponowne zamontowanie.
  • Jeśli logi CSI raportują BlobFuse2 distributed-cache support could not be verified, sterownik usuwa opcje rozproszonej pamięci podręcznej i wybiera lokalną pamięć podręczną bloków. Sprawdź wersję hosta BlobFuse2 i możliwości montowania, a następnie skoordynuj odmontowanie i ponowne zamontowanie.
  • Jeśli BlobFuse2 wykryje brak serwerów cache, montaż może się powiódć i odczyty trafiają bezpośrednio do Blob Storage. Sprawdź usługę odkrywania, adres DNS, punkty końcowe oraz łączność węzłów z pamięcią podręczną.

Znajdź kapsułę CSI działającą na dotkniętym węźle czytnika i sprawdź jej blob kontener:

kubectl get pods --namespace "$WORKLOAD_NAMESPACE" --output wide
kubectl get pods --namespace kube-system \
  --selector app=csi-blob-node --output wide

CSI_POD="<csi-blob-node-pod-on-affected-reader-node>"
kubectl logs "$CSI_POD" --namespace kube-system --container blob --since=15m

Logi kontenerowe CSI to nie logi BlobFuse2 hosta. Na dotkniętym węźle obciążenia użyj zatwierdzonej metody dostępu do węzła, aby sprawdzić dziennik BlobFuse2:

journalctl --identifier=blobfuse2 --since "15 minutes ago" --no-pager

Jeśli BlobFuse2 jest skonfigurowany do zapisu zamiast tego do pliku, sprawdź jego skonfigurowaną ścieżkę dziennika. Po rozwiązaniu problemu skoordynuj odmontowanie i ponowne zamontowanie dla wszystkich podów dzielących ten wolumin, a następnie powtórz weryfikację ścieżki pamięci podręcznej.

Wyczyść obciążenie testowe

Usuń tylko zasoby stworzone na potrzeby tego artykułu. Zatrzymaj pody czytnika przed usunięciem zgłoszenia i PV:

kubectl delete pod blobfuse-dacs-reader blobfuse-dacs-cold blobfuse-dacs-warm \
  --namespace "$WORKLOAD_NAMESPACE" --ignore-not-found
kubectl delete pvc blobfuse-dacs-pvc \
  --namespace "$WORKLOAD_NAMESPACE" --ignore-not-found
kubectl delete pv blobfuse-dacs-pv --ignore-not-found

Zasada Retain zachowuje Twój pojemnik i bloby. Nie usuwaj istniejących danych aplikacji ani zarządzanej tożsamości. Usuń federowane poświadczenie, przypisanie roli lub przestrzeń nazw obciążenia tylko wtedy, gdy stworzyłeś je wyłącznie dla tego testu i żadne inne obciążenie ich nie wymaga.

Pozostaw włączone sterownik Blob CSI usługi Managed Blob oraz współdzielone zasoby DACS. Jeśli DACS był włączony tylko do tej oceny i żadne inne obciążenie go nie wymaga, stosuj opcję Remove distributed accelerator for cloud storage.

Następne kroki