Otimizar o driver CSI do Cloud Storage FUSE para a performance do GKE


Este guia mostra como otimizar o desempenho do driver CSI do FUSE do Cloud Storage no Google Kubernetes Engine (GKE).

Embora o Cloud Storage FUSE ofereça flexibilidade e escalonabilidade, a configuração e o ajuste cuidadoso são essenciais para alcançar o desempenho ideal. O desempenho do Cloud Storage FUSE pode ser diferente de um sistema de arquivos POSIX em termos de latência, throughput e consistência. O objetivo do ajuste é minimizar a sobrecarga das operações de metadados e maximizar a eficiência do acesso aos dados. Se você estiver executando aplicativos de IA/ML que consomem dados em buckets do Cloud Storage, o ajuste do driver CSI pode levar a tempos de treinamento e inferência mais rápidos para seus aplicativos de IA/ML.

Este guia é destinado a desenvolvedores e engenheiros de aprendizado de máquina (ML) que querem melhorar o desempenho dos aplicativos que acessam dados armazenados em buckets do Cloud Storage.

Antes de ler esta página, confira se você conhece os conceitos básicos do Cloud Storage, do Kubernetes e do driver CSI do Cloud Storage FUSE. Confira também os requisitos da versão do GKE para recursos específicos que você quer usar.

Configurar opções de montagem

O driver FUSE CSI do Cloud Storage oferece suporte a opções de montagem para configurar como os buckets do Cloud Storage são montados no sistema de arquivos local. Para conferir a lista completa de opções de montagem com suporte, consulte a documentação do arquivo da CLI do FUSE do Cloud Storage.

É possível especificar as opções de montagem das seguintes maneiras, dependendo do tipo de volume que você está usando:

Volume temporário do CSI

Se você usar volumes temporários do CSI, especifique as opções de montagem no campo spec.volumes[n].csi.volumeAttributes.mountOptions do manifesto do pod.

É necessário especificar as opções de montagem como uma string, com flags separadas por vírgulas e sem espaços. Exemplo:

  mountOptions: "implicit-dirs,file-cache:enable-parallel-downloads:true,file-cache:download-chunk-size-mb:3"

Volume permanente

Se você usar volumes permanentes, especifique as opções de montagem no campo spec.mountOptions no manifesto do PersistentVolume.

É necessário especificar as opções de montagem como uma lista. Exemplo:

  mountOptions:
    - implicit-dirs
    - file-cache:enable-parallel-downloads:true
    - file-cache:download-chunk-size-mb:3

Considerações sobre a montagem

Use as seguintes considerações ao configurar as montagens com o driver CSI:

Considerações gerais

  • As flags a seguir não são permitidas: app-name, temp-dir, foreground, log-file, log-format, key-file, token-url e reuse-token-from-url.
  • O Cloud Storage FUSE não torna os diretórios implícitos visíveis por padrão.
  • Se você só quiser ativar um diretório no bucket em vez de todo o bucket, passe o caminho relativo do diretório usando a sinalização only-dir=relative/path/to/the/bucket/root.

Segurança e permissões

  • Se você usa um Contexto de segurança para o pod ou contêiner, ou se a imagem do contêiner usa um usuário ou grupo não raiz, é necessário definir as flags de montagem uid e gid. Você também precisa usar as flags de montagem file-mode e dir-mode para definir as permissões do sistema de arquivos. Não é possível executar comandos chmod, chown ou chgrp em um sistema de arquivos do Cloud Storage FUSE. Use as flags de montagem uid, gid, file-mode e dir-mode para ter acesso a um usuário ou grupo que não seja raiz.

Opções de montagem do kernel do Linux

  • Se você precisar configurar as opções de montagem do kernel do Linux, poderá transmiti-las usando a flag o. Por exemplo, se você não quiser permitir a execução direta de binários no sistema de arquivos montado, defina a flag o=noexec. Cada opção requer uma flag separada, por exemplo, o=noexec, o=noatime. Somente as seguintes opções são permitidas: exec, noexec, atime, noatime, sync, async e dirsync.

Configurar o armazenamento em cache

Esta seção apresenta uma visão geral das opções de armazenamento em cache disponíveis com o driver FUSE CSI do Cloud Storage para melhorar o desempenho.

Armazenamento em cache de arquivos

É possível usar o driver CSI do FUSE do Cloud Storage com armazenamento em cache de arquivos para melhorar o desempenho de leitura de aplicativos que processam arquivos pequenos de buckets do Cloud Storage. O recurso de cache de arquivos do Cloud Storage FUSE é um cache de leitura baseado em cliente que permite que leituras de arquivos repetidas sejam veiculadas mais rapidamente no armazenamento de cache de sua escolha.

Você pode escolher entre várias opções de armazenamento para o cache de leitura, incluindo SSDs locais, armazenamento baseado em Persistent Disk e disco RAM (memória), com base nas suas necessidades de preço-desempenho.

Ativar e usar o armazenamento em cache de arquivos

Por padrão, o recurso de armazenamento em cache de arquivos está desativado no GKE. É necessário ativar o armazenamento em cache de arquivos com o driver CSI do Cloud Storage FUSE.

Para ativar e controlar o armazenamento em cache de arquivos, defina o atributo de volume fileCacheCapacity ou use a opção de montagem file-cache:max-size-mb.

O GKE usa um volume emptyDir por padrão para o armazenamento em cache de arquivos do Cloud Storage FUSE com suporte do armazenamento temporário configurado no nó. Pode ser o disco de inicialização anexado ao nó ou um SSD local no nó. Se você ativar o SSD local no nó, o GKE usará o SSD local para retornar o volume emptyDir.

É possível configurar um volume personalizado de cache de leitura para o contêiner secundário para substituir o volume emptyDir padrão para armazenamento em cache de arquivos em operações de leitura.

Para saber mais sobre as práticas recomendadas de armazenamento em cache de arquivos, consulte Desempenho do Cloud Storage FUSE.

Selecione o armazenamento para fazer backup do cache de arquivos

Para selecionar o armazenamento para fazer backup do cache de arquivos, consulte estas considerações:

  • Para famílias de VMs de GPU e CPU que oferecem suporte a SSD local (por exemplo, VMs A3), recomendamos o uso de SSD local.

    • Para VMs A3 e mais recentes, o GKE configura automaticamente o SSD local para consumo dos pods.
    • Se a família de VMs não for compatível com o SSD local, o GKE vai usar o disco de inicialização para armazenamento em cache. O tipo de disco padrão para o disco de inicialização no GKE é pd-balanced.
    • Se a família de VMs oferecer suporte a SSD local, mas não tiver o armazenamento temporário no SSD local ativado por padrão, você poderá ativar o SSD local no pool de nós. Isso se aplica às famílias de máquinas de primeira e segunda geração, como N1 e N2. Para saber mais, consulte Criar um cluster com SSD local.

      Para verificar se o nó tem o armazenamento temporário no SSD local ativado, execute o seguinte comando:

      kubectl describe node <code><var>NODE_NAME</var></code> | grep "cloud.google.com/gke-ephemeral-storage-local-ssd"
      
  • Para famílias de VM TPU, especialmente v6+, recomendamos usar RAM como um cache de arquivos para o melhor desempenho, já que essas instâncias de VM têm RAM maior.

    • Ao usar a RAM, preste atenção aos erros de falta de memória (OOM), porque eles causam interrupções no pod. O Cloud Storage FUSE consome memória. Portanto, configurar um cache de arquivos para consumir o contêiner sidecar pode resultar em erros de OOM. Para evitar esses cenários, ajuste o campo file-cache:max-size-mb da configuração do cache de arquivos para um valor menor.
    • Para outras famílias de TPU, recomendamos o uso de pd-balanced ou pd-ssd. O tipo de disco padrão para o disco de inicialização no GKE é pd-balanced.
  • Evite usar o disco de inicialização para armazenamento em cache, porque isso pode reduzir o desempenho e causar encerramentos inesperados. Em vez disso, considere usar um PersistentVolume com suporte de um disco permanente.

Usar o armazenamento em cache de arquivos baseado em disco RAM

É possível usar o disco RAM para armazenamento em cache de arquivos ou download paralelo para reduzir o overhead do uso de um disco de inicialização ou um Persistent Disk, se você estiver usando uma VM TPU com RAM suficientemente grande.

Para usar um disco RAM com o driver CSI do Cloud Storage FUSE, adicione o seguinte ao manifesto:

volumes:
  - name: gke-gcsfuse-cache
    emptyDir:
      medium: Memory

Cache de estatísticas

O driver CSI do Cloud Storage FUSE melhora o desempenho armazenando em cache os metadados do arquivo, como tamanho e tempo de modificação. O driver CSI ativa esse cache de estatísticas por padrão e reduz a latência armazenando informações localmente em vez de solicitar repetidamente o Cloud Storage. É possível configurar o tamanho máximo (o padrão é 32 MB) e o tempo que os dados permanecem no cache (o padrão é 60 segundos). Ao ajustar o cache de metadados, você pode reduzir as chamadas de API para o Cloud Storage, melhorando o desempenho e a eficiência do aplicativo, minimizando o tráfego de rede e a latência.

Para saber mais sobre as práticas recomendadas de armazenamento em cache de estatísticas, consulte a Visão geral do armazenamento em cache do Cloud Storage FUSE.

Usar a busca antecipada de metadados para preencher o cache de metadados

O recurso de pré-carregamento de metadados permite que o driver FUSE CSI do Cloud Storage carregue proativamente metadados relevantes sobre os objetos no bucket do Cloud Storage nos caches do FUSE do Cloud Storage. Essa abordagem reduz as chamadas para o Cloud Storage e é especialmente benéfica para aplicativos que acessam grandes conjuntos de dados com muitos arquivos, como cargas de trabalho de treinamento de IA/ML.

Esse recurso requer o GKE versão 1.31.3-gke.1162000 ou mais recente.

Para notar ganhos de desempenho com a pré-busca de metadados, defina o valor de time to live (TTL) dos itens de cache de metadados como ilimitado. Normalmente, definir um TTL evita que o conteúdo armazenado em cache fique desatualizado. Ao definir o TTL como ilimitado, é necessário tomar cuidado para não mudar o conteúdo do bucket fora da banda, ou seja, permitindo que uma carga de trabalho ou um ator diferente modifique a carga de trabalho. As mudanças fora da banda não são visíveis localmente e podem causar problemas de consistência.

Para ativar o pré-carregamento de metadados, faça as seguintes alterações de configuração. Recomendamos ativar esse recurso em volumes que são lidos com frequência.

Para conferir um exemplo, consulte o exemplo de código em Melhorar a performance de leitura de arquivos grandes usando o download paralelo.

Cache da lista

Para acelerar as listagens de diretório de aplicativos, ative o armazenamento em cache de lista. Esse recurso armazena as listas de diretórios na memória para que solicitações repetidas possam ser atendidas mais rapidamente. O cache de lista é desativado por padrão. Para ativá-lo, defina o parâmetro kernel-list-cache-ttl-secs nas opções de montagem. Isso define por quanto tempo as listagens são armazenadas em cache.

Melhorar a performance da leitura de arquivos grandes usando o download paralelo

O download paralelo do Cloud Storage FUSE pode ser usado para acelerar a leitura de arquivos grandes do Cloud Storage para downloads multithread. O download paralelo do Cloud Storage FUSE pode ser particularmente benéfico para casos de uso de disponibilização do modelo com leituras de mais de 1 GB.

São exemplos comuns:

  • A disponibilização do modelo, em que você precisa de um buffer de pré-busca grande para acelerar o download do modelo durante a inicialização da instância.
  • Restaurações de checkpoints, em que você precisa de um cache de dados somente leitura para melhorar o acesso único a vários arquivos grandes.
Prática recomendada:

Use o download paralelo para aplicativos que executam leituras de arquivos grandes de thread único. Aplicativos com alto paralelismo de leitura (que usam mais de oito threads) podem apresentar um desempenho menor com esse recurso.

Para usar o download paralelo com o driver CSI do Cloud Storage FUSE, siga estas etapas:

  1. Crie um cluster com o armazenamento em cache de arquivos ativado, conforme descrito em Ativar e usar o armazenamento em cache de arquivos.

  2. No manifesto, configure estas outras configurações usando opções de montagem para ativar o download paralelo:

    1. Defina file-cache:enable-parallel-downloads:true.
    2. Ajuste file-cache:parallel-downloads-per-file, file-cache:parallel-downloads-per-file, file-cache:max-parallel-downloads e file-cache:download-chunk-size-mb conforme necessário.
  3. (Opcional) Se necessário, ajuste estes atributos de volume:

Reduzir o consumo de cota das verificações de controle de acesso

Por padrão, o driver CSI realiza verificações de controle de acesso para garantir que a conta de serviço do pod tenha acesso aos seus buckets do Cloud Storage. Isso resulta em uma sobrecarga adicional na forma de chamadas da API Service do Kubernetes, do Security Token Service e do IAM. A partir da versão 1.29.9-gke.1251000 do GKE, é possível usar o atributo de volume skipCSIBucketAccessCheck para pular essas verificações redundantes e reduzir o consumo de cota.

Exemplo de veiculação de inferência

O exemplo a seguir mostra como ativar o download paralelo para veiculação de inferência:

  1. Crie um manifesto PersistentVolume e PersistentVolumeClaim com a seguinte especificação:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: serving-bucket-pv
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 64Gi
      persistentVolumeReclaimPolicy: Retain
      storageClassName: example-storage-class
      claimRef:
        namespace: NAMESPACE
        name: serving-bucket-pvc
      mountOptions:
        - implicit-dirs #avoid if list cache enabled and doing metadata prefetch
        - metadata-cache:ttl-secs:-1
        - metadata-cache:stat-cache-max-size-mb:-1
        - metadata-cache:type-cache-max-size-mb:-1
        - file-cache:max-size-mb:-1
        - file-cache:cache-file-for-range-read:true
        - file-system:kernel-list-cache-ttl-secs:-1
        - file-cache:enable-parallel-downloads:true
      csi:
        driver: gcsfuse.csi.storage.gke.io
        volumeHandle: BUCKET_NAME
        volumeAttributes:
          skipCSIBucketAccessCheck: "true"
          gcsfuseMetadataPrefetchOnMount: "true"
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: serving-bucket-pvc
      namespace: NAMESPACE
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 64Gi
      volumeName: serving-bucket-pv
      storageClassName: example-storage-class
    

    Substitua os seguintes valores:

    • NAMESPACE: o namespace do Kubernetes em que você quer implantar o pod.
    • BUCKET_NAME: o nome do bucket do Cloud Storage especificado ao configurar o acesso aos buckets do Cloud Storage. É possível especificar um sublinhado (_) para ativar todos os buckets que a conta de serviço do Kubernetes pode acessar. Para saber mais, consulte Ativação dinâmica na documentação do FUSE do Cloud Storage.
  2. Aplique o manifesto ao cluster:

    kubectl apply -f PV_FILE_PATH
    

    Substitua PV_FILE_PATH pelo caminho para o arquivo YAML.

  3. Crie um manifesto de pod com a especificação a seguir para consumir o PersistentVolumeClaim, dependendo se você está usando o armazenamento em cache de arquivos com suporte a SSD local ou o armazenamento em cache de arquivos com suporte a disco RAM:

    SSD local

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-pod
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/cpu-limit: "0"
        gke-gcsfuse/memory-limit: "0"
        gke-gcsfuse/ephemeral-storage-limit: "0"
    spec:
      containers:
        # Your workload container spec
        ...
        volumeMounts:
        - name: serving-bucket-vol
          mountPath: /serving-data
          readOnly: true
      serviceAccountName: KSA_NAME
      volumes:
      - name: serving-bucket-vol
        persistentVolumeClaim:
          claimName: serving-bucket-pvc
    

    Disco de RAM

    apiVersion: v1
    kind: Pod
    metadata:
      name: gcs-fuse-csi-example-pod
      namespace: NAMESPACE
      annotations:
        gke-gcsfuse/volumes: "true"
        gke-gcsfuse/cpu-limit: "0"
        gke-gcsfuse/memory-limit: "0"
        gke-gcsfuse/ephemeral-storage-limit: "0"
    spec:
      containers:
        # Your workload container spec
        ...
        volumeMounts:
        - name: serving-bucket-vol
          mountPath: /serving-data
          readOnly: true
      serviceAccountName: KSA_NAME 
      volumes:
        - name: gke-gcsfuse-cache # gcsfuse file cache backed by RAM Disk
          emptyDir:
            medium: Memory 
      - name: serving-bucket-vol
        persistentVolumeClaim:
          claimName: serving-bucket-pvc
    
  4. Aplique o manifesto ao cluster:

    kubectl apply -f POD_FILE_PATH
    

    Substitua POD_FILE_PATH pelo caminho para o arquivo YAML.

Configurar atributos de volume

Os atributos de volume permitem configurar o comportamento específico do driver CSI do Cloud Storage FUSE.

O driver CSI do Cloud Storage FUSE não permite especificar diretamente o arquivo de configuração do Cloud Storage FUSE. É possível configurar alguns dos campos no arquivo de configuração usando os atributos de volume do CSI do Cloud Storage FUSE. O driver CSI processa a conversão dos valores dos atributos de volume para os campos do arquivo de configuração.

Para conferir a lista completa de atributos de volume aceitos, consulte a Referência de atributos de volume.

É possível especificar os atributos de volume das seguintes maneiras:

  • No campo spec.csi.volumeAttributes de um manifesto do PersistentVolume, se você usar volumes persistentes.
  • No campo spec.volumes[n].csi.volumeAttributes, se você usar volumes temporários do CSI.

No manifesto, os atributos de volume podem ser especificados como pares de chave-valor. Exemplo:

volumeAttributes:
  mountOptions: "implicit-dirs"
  fileCacheCapacity: "-1"
  gcsfuseLoggingSeverity: warning

Métricas do Cloud Storage FUSE

As seguintes métricas do FUSE do Cloud Storage agora estão disponíveis na API Monitoring do GKE. Detalhes sobre as métricas do Cloud Storage FUSE, como rótulos, tipo e unidade, podem ser encontrados em Métricas do sistema do GKE. Essas métricas estão disponíveis para cada pod que usa o Cloud Storage FUSE, e você pode usá-las para configurar insights por volume e bucket.

As métricas ficam desativadas por padrão. Para ativá-los, defina o atributo de volume disableMetrics como "false".

Métricas do sistema de arquivos

As métricas do sistema de arquivos rastreiam o desempenho e a integridade do sistema, incluindo o número de operações, erros e velocidade. Essas métricas podem ajudar a identificar gargalos e otimizar o desempenho.

  • gcsfusecsi/fs_ops_count
  • gcsfusecsi/fs_ops_error_count
  • gcsfusecsi/fs_ops_latency

Métricas do Cloud Storage

É possível monitorar as métricas do Cloud Storage, incluindo volume de dados, velocidade e atividade de solicitações, para entender como seus aplicativos interagem com buckets do Cloud Storage. Esses dados podem ajudar a identificar áreas para otimização, como melhorar os padrões de leitura ou reduzir o número de solicitações.

  • gcsfusecsi/gcs_download_bytes_count
  • gcsfusecsi/gcs_read_count
  • gcsfusecsi/gcs_read_bytes_count
  • gcsfusecsi/gcs_reader_count
  • gcsfusecsi/gcs_request_count
  • gcsfusecsi/gcs_request_latencies

Métricas de cache de arquivos

É possível monitorar as métricas do cache de arquivos, incluindo o volume de leitura de dados, a velocidade e a taxa de ocorrência em cache, para otimizar o FUSE do Cloud Storage e o desempenho do aplicativo. Analise essas métricas para melhorar sua estratégia de armazenamento em cache e maximizar as ocorrências em cache.

  • gcsfusecsi/file_cache_read_bytes_count
  • gcsfusecsi/file_cache_read_latencies
  • gcsfusecsi/file_cache_read_count

Práticas recomendadas para ajuste de performance

Esta seção lista algumas técnicas recomendadas de ajuste e otimização de desempenho para o driver CSI do Cloud Storage FUSE.

  • Usar buckets de namespace hierárquico (HNS, na sigla em inglês):escolha buckets de HNS para aumentar em 8 vezes as consultas iniciais por segundo (QPS, na sigla em inglês). Essa escolha também facilita a renomeação rápida e atômica de diretórios, um requisito crucial para o checkpointing eficiente com o FUSE do Cloud Storage. Os buckets do HNS oferecem uma experiência semelhante a arquivos, com suporte a 40.000 solicitações de leitura de objeto e 8.000 solicitações de gravação de objeto por segundo, uma melhoria significativa em relação aos 8.000 pedidos de leitura de objeto e 1.000 solicitações de gravação de objeto por segundo oferecidas pelos buckets planos.

  • Monte diretórios específicos quando possível:se a carga de trabalho envolver o acesso a um diretório específico em um bucket, use a flag --only-dir durante a montagem. Essa abordagem focada acelera as chamadas de lista, já que limita o escopo das chamadas LookUpInode, que envolvem uma chamada list+stat para cada arquivo ou diretório no caminho especificado. Ao restringir a montagem ao subdiretório necessário, você minimiza essas chamadas, o que leva a ganhos de desempenho.

  • Otimizar o armazenamento em cache de metadados:configure os caches de metadados para maximizar a capacidade e definir um time to live (TTL) infinito. Essa prática armazena em cache todos os metadados acessados durante a execução do job, minimizando as solicitações de acesso a metadados para o Cloud Storage. Essa configuração é particularmente vantajosa para volumes somente leitura, porque elimina pesquisas de metadados repetidas do Cloud Storage. No entanto, verifique se o consumo de memória associado a esses grandes caches de metadados está alinhado com os recursos do sistema.

  • Maximizar os recursos do sidecar do GKE:o Cloud Storage FUSE opera em um contêiner sidecar em um ambiente do GKE. Para evitar gargalos de recursos, remova as limitações no consumo de CPU e memória do contêiner sidecar. Isso permite que o Cloud Storage FUSE dimensione a utilização de recursos com base nas demandas de carga de trabalho, evitando o estrangulamento e garantindo a capacidade de processamento ideal.

  • Preencher o cache de metadados de forma proativa:ative a pré-busca de metadados para o driver CSI. Isso preenche os metadados e os caches de lista de maneira eficiente, minimizando chamadas de metadados para o Cloud Storage e acelerando a execução inicial. Muitos frameworks de ML fazem isso automaticamente, mas é crucial garantir essa etapa para o código de treinamento personalizado. Para saber mais, consulte Usar o pré-carregamento de metadados para pré-preencher o cache de metadados.

  • Utilize o cache de arquivos e os downloads em paralelo:ative o recurso de cache de arquivos, principalmente para cargas de trabalho de treinamento com várias épocas, em que os dados são lidos repetidamente. O cache de arquivos armazena dados acessados com frequência no armazenamento local (SSD no caso de máquinas A3), melhorando o desempenho de leitura. Complemente isso com o recurso de downloads paralelos, principalmente para atender cargas de trabalho, para acelerar o download de arquivos grandes dividindo-os em partes menores e fazendo o download simultaneamente.

  • Otimizar checkpoints:para checkpointing com o Cloud Storage FUSE, recomendamos o uso de um bucket do HNS. Se você estiver usando um bucket que não é HNS, defina o parâmetro rename-dir-limit como um valor alto para acomodar as renomeações de diretório usadas com frequência por frameworks de ML durante o checkpointing. No entanto, a renomeação de diretórios em buckets que não são do HNS pode não ser atômica e pode levar mais tempo para ser concluída.

  • Ativar o armazenamento em cache de lista:ative o armazenamento em cache de lista usando a flag --kernel-list-cache-ttl-secs para melhorar ainda mais a performance. Esse recurso armazena em cache as listagens de diretórios e arquivos, melhorando a velocidade das operações ls. O armazenamento em cache de listas é especialmente benéfico para cargas de trabalho que envolvem listagens de diretório completas repetidas, comuns em cenários de treinamento de IA/ML. É recomendável usar o armazenamento em cache de listas com montagens somente leitura para manter a consistência dos dados.

A seguir