Práticas recomendadas do Cloud Storage

Introdução

Nesta página você encontrará um resumo das práticas recomendadas de outras páginas na documentação do Cloud Storage. É possível usar as práticas recomendadas listadas aqui como uma referência rápida do que precisa ser lembrado ao criar um aplicativo que usa o Cloud Storage. Siga estas práticas recomendadas ao iniciar um aplicativo comercial.

Se você é iniciante no Cloud Storage, esta página pode não ser o melhor lugar para começar, já que não ensina o básico sobre a utilização dele. Se estiver começando agora, sugerimos que confira o Guia de início rápido: como usar o Console ou o Guia de início rápido: como usar a ferramenta gsutil.

Nomenclatura

  • Consulte os tópicos Nomenclatura de bucket e Nomenclatura de objetos para obter as considerações e os requisitos de nome.

  • Se você precisar de muitos buckets, use GUIDs ou um equivalente para nomes de bucket, coloque a lógica de repetição no código para lidar com colisões de nomes e mantenha uma lista para fazer referência cruzada a seus buckets. Outra opção é usar buckets com nome de domínio e gerenciar os nomes dos buckets como subdomínios.

  • Não use códigos de usuário, endereços de e-mail, nomes de projetos, números de projetos ou qualquer informação pessoal identificável (PII, na sigla em inglês) em nomes de buckets, porque qualquer um pode pesquisar a existência de um bucket. Da mesma forma, tenha muito cuidado ao inserir PII nos nomes dos objetos, porque eles aparecem nos URLs dos objetos.

  • Evite usar nomes de arquivos sequenciais, como nomes de arquivos baseados em carimbos de data/hora, se estiver fazendo upload de muitos arquivos em paralelo. Os arquivos com nomes sequenciais são armazenados consecutivamente, portanto, é provável que eles atinjam o mesmo servidor de back-end. Quando isso acontece, a capacidade é limitada. Para alcançar a capacidade ideal, insira o hash do número de sequência como parte do nome do arquivo para torná-lo não sequencial. Para mais informações, consulte as Diretrizes de taxa de solicitação e distribuição de acesso.

Tráfego

  • Faça uma estimativa do valor do tráfego que será enviado para o Cloud Storage. Pense especificamente em:

    • Operações por segundo. Quantas operações por segundo você espera, tanto para buckets e objetos, quanto para operações de criação, atualização e exclusão.

    • Largura de banda. Quantos dados serão enviados, em que período de tempo?

    • Controle de cache. Especificar os Cache-Control metadados nos objetos reduzirá a latência de leitura em objetos ativos ou frequentemente acessados. Consulte a Como visualizar e editar metadados para instruções sobre como configurar metadados de objeto, como Cache-Control.

  • Projete seu aplicativo para minimizar picos no tráfego. Se houver clientes do seu aplicativo fazendo atualizações, distribua-os ao longo do dia.

  • Mesmo que o Cloud Storage não tenha limite superior na taxa de solicitação, para conseguir o melhor desempenho ao escalonar para altas taxas, siga as Diretrizes de taxa de solicitação e distribuição de acesso.

  • Esteja ciente de que há limites de taxa para determinadas operações, então projete seu aplicativo de acordo.

  • Se você receber um erro:

    • Use a espera exponencial como parte de sua estratégia de nova tentativa para evitar problemas devido a grandes bursts de tráfego.

    • Tente novamente usando uma nova conexão e, se possível, resolva novamente o nome do domínio. Isso ajuda a evitar a "aderência do servidor", em que uma nova tentativa tenta passar pelo mesmo caminho e atinge o mesmo componente não íntegro que a solicitação inicial atingiu.

  • Se seu aplicativo for sensível à latência, use solicitações protegidas. As solicitações protegidas permitem que você repita mais rapidamente e reduza a latência de cauda. Elas fazem isso sem reduzir o prazo da solicitação, o que pode fazer com que as solicitações expirem prematuramente. Para mais informações, consulte https://www2.cs.duke.edu/courses/cps296.4/fall13/838-CloudPapers/dean_longtail.pdf

  • Entenda o nível de desempenho que os clientes esperam do seu aplicativo. Essas informações ajudarão você a escolher uma opção de armazenamento e região ao criar novos buckets.

Opções de armazenamento de dados e regiões

  • Os dados que serão exibidos em uma taxa alta com alta disponibilidade precisarão usar a classe de Armazenamento padrão. Essa classe fornece a melhor disponibilidade, mas por um preço mais alto.

  • Os dados que serão acessados com pouca frequência e podem tolerar uma disponibilidade um pouco menor podem ser armazenados usando a classe Nearline Storage, Coldline Storage ou Archive Storage.

  • Armazene seus dados em uma região mais próxima dos usuários do seu aplicativo. Por exemplo, para dados da UE, você pode escolher um bucket da UE e, para dados dos EUA, escolher um bucket nos EUA. Para mais informações, consulte Locais de bucket.

  • Tenha em mente os requisitos de conformidade ao escolher um local para os dados do usuário. Há requisitos legais em torno dos locais que seus usuários fornecerão dados?

Segurança, ACLs e controle de acesso

  • A primeira e mais importante precaução é: nunca compartilhe suas credenciais. É necessário que cada usuário tenha credenciais distintas.

  • Ao imprimir detalhes do protocolo HTTP, suas credenciais de autenticação, como tokens OAuth 2.0, ficam visíveis nos cabeçalhos. Se você precisar postar detalhes do protocolo em um quadro de mensagens ou fornecer detalhes do protocolo HTTP para solução de problemas, limpe ou revogue quaisquer credenciais que aparecem como parte da saída.

  • Sempre use TLS (HTTPS) para transportar seus dados quando puder. Isso assegura que suas credenciais e seus dados sejam protegidos conforme você os transporta pela rede. Por exemplo, para acessar a API Cloud Storage, use https://storage.googleapis.com.

  • Use uma biblioteca HTTPS que valide os certificados do servidor. A falta de uma validação de certificado do servidor torna seu aplicativo vulnerável a ataques "man-in-the-middle" ou outros tipos de ataque. As bibliotecas HTTPS enviadas com determinadas linguagens de implementação usadas normalmente não verificam, por padrão, os certificados do servidor. Por exemplo, o Python anterior à versão 3.2 não tem suporte integrado ou completo para a validação de certificado de servidor, portanto, você precisa usar bibliotecas de wrapper de terceiros para garantir que seu aplicativo valide os certificados de servidor.

  • Quando os aplicativos não precisarem mais de acesso a seus dados, revogue suas credenciais de autenticação. Para fazer isso em serviços e APIs do Google, faça login nas permissões da Conta do Google, clique nos aplicativos desnecessários e depois clique em Remover acesso.

  • Certifique-se de que suas credenciais sejam armazenadas com segurança. Isso pode ser feito de maneira diferente, dependendo de seu ambiente e de onde você armazena suas credenciais. Por exemplo, se você armazenar suas credenciais em um arquivo de configuração, defina permissões apropriadas nesse arquivo para impedir o acesso indesejado. Se você estiver usando o Google App Engine, use StorageByKeyName para armazenar suas credenciais.

  • As solicitações do Cloud Storage se referem a buckets e objetos pelos nomes deles. Como resultado, mesmo que as ACLs impeçam a operação não autorizada de terceiros em buckets ou objetos, um terceiro pode tentar solicitações com nomes de bucket ou de objeto e determinar a existência deles observando as respostas de erro. Dessa forma, é possível que as informações em nomes de bucket ou de objeto vazem. Se você estiver preocupado com a privacidade de seus nomes de bucket ou de objeto, tome as precauções adequadas, como:

    • Escolher nomes de bucket e de objeto difíceis de adivinhar. Por exemplo, um bucket chamado mybucket-gtbytul3 é aleatório o suficiente, de modo que terceiros não autorizados não possam adivinhá-lo ou enumerar outros nomes de bucket a partir dele.

    • Evitar usar informações confidenciais como parte de nomes de intervalos ou objetos. Por exemplo, em vez de nomear seu bucket como mysecretproject-prodbucket, uso o nome somemeaninglesscodename-prod. Em alguns aplicativos, convém manter metadados confidenciais em cabeçalhos personalizados do Cloud Storage, como x-goog-meta, em vez de codificá-los nos nomes de objetos.

  • Use grupos em vez de listar explicitamente um número grande de usuários. Isso não só torna o escalonamento melhor, mas também fornece uma maneira muito eficiente de atualizar o controle de acesso para um número grande de objetos de uma só vez. Por fim, é mais barato porque você não precisa fazer uma solicitação por objeto para alterar as ACLs.

  • Antes de adicionar objetos a um bucket, verifique se as ACLs de objeto padrão estão definidas de acordo com seus requisitos primeiro. Isso pode poupar muito tempo atualizando ACLs para objetos individuais.

  • ACLs de bucket e de objeto são independentes umas das outras, o que significa que as ACLs em um bucket não afetam as ACLs em objetos dentro desse bucket. É possível que um usuário sem permissões em um bucket tenha permissões em um objeto dentro do bucket. Por exemplo, é possível criar um bucket de tal forma que apenas o GrupoA tenha permissão para listar os objetos dele e depois fazer o upload de um objeto para esse bucket que concede ao GrupoB o acesso READ ao objeto. O GrupoB poderá ler o objeto, mas não poderá exibir o conteúdo do bucket ou executar tarefas relacionadas a ele.

  • O sistema de controle de acesso do Cloud Storage inclui a capacidade de especificar que os objetos são legíveis publicamente. Certifique-se de que você pretende que qualquer objeto gravado com essa permissão seja público. Uma vez "publicados", os dados na Internet podem ser copiados para muitos lugares, por isso é efetivamente impossível recuperar o controle de leitura sobre um objeto gravado com essa permissão.

  • O sistema de controle de acesso do Cloud Storage inclui a capacidade de especificar que os buckets são graváveis publicamente. Mesmo que configurar um bucket dessa maneira possa ser conveniente para vários fins, recomendamos evitar o uso dessa permissão. Ela pode ser usada para distribuir conteúdo ilegal, vírus e outros malwares, e o proprietário do bucket é legal e financeiramente responsável pelo conteúdo armazenado.

    Se você precisar disponibilizar o conteúdo com segurança para usuários que não têm contas do Google, recomendamos que você use URLs assinados. Por exemplo, com URLs assinados, você pode fornecer um link para um objeto e os clientes do seu aplicativo não precisam se autenticar com o Cloud Storage para acessá-lo. Quando você cria um URL assinado, controla o tipo (leitura, gravação, exclusão) e a duração do acesso.

  • Se você usa o gsutil, consulte estas outras recomendações.

Como fazer o upload de dados

  • Se você usa callbacks XMLHttpRequest (XHR) para receber atualizações de progresso, não feche e reabra a conexão se detectar que o progresso parou. Isso cria um loop de feedback positivo inválido durante os períodos de congestionamento da rede. Quando a rede está congestionada, os callbacks XHR podem ficar atrasados em relação à atividade de confirmação (ACK/NACK) do fluxo de upload, e fechar e reabrir a conexão quando isso acontece usa mais capacidade de rede exatamente no momento em que você menos pode arcar com isso.

  • Para o tráfego de upload, recomendamos a configuração de tempos limite razoavelmente longos. Para uma boa experiência do usuário final, é possível definir um timer do lado do cliente que atualiza a janela de status do cliente com uma mensagem (por exemplo, "congestionamento de rede") quando seu aplicativo não recebe um callback XHR por muito tempo. Não feche a conexão e tente novamente quando isso acontecer.

  • Se você usa instâncias do Compute Engine com processos que enviam POST para o Cloud Storage iniciar um upload retomável, use instâncias do Compute Engine nos mesmos locais que seus buckets do Cloud Storage. Em seguida, você usa um serviço de IP geográfico para escolher a região do Compute Engine para onde rotear solicitações de clientes, o que ajuda a manter o tráfego localizado em uma região geográfica.

  • Para uploads retomáveis, a sessão retomável precisa permanecer na região em que foi criada. Isso reduz o tráfego entre regiões que surge ao ler e gravar o estado da sessão, melhorando o desempenho do upload recuperável.

  • Evite dividir uma transferência em partes menores, se possível, e faça o upload de todo o conteúdo de uma só vez. Evitar essa divisão remove os custos fixos de latência e melhora a capacidade, além de reduzir o QPS em relação ao Cloud Storage.

    Situações em que é recomendável considerar o upload em partes incluem: quando seus dados de origem são gerados dinamicamente, seus clientes têm limitações de tamanho de solicitação (o que é verdadeiro para muitos navegadores) ou seus clientes não conseguem transmitir bytes em uma única solicitação sem antes carregar a solicitação completa na memória. Se seus clientes receberem um erro, eles poderão consultar o servidor quanto ao deslocamento de confirmação e retomar o upload dos bytes restantes desse deslocamento.

  • Se possível, evite fazer upload de conteúdo que tenha content-encoding: gzip e um content-type que esteja compactado, porque isso pode acarretar comportamento inesperado.

Como excluir dados

  • Se você acredita que o software ou os usuários do aplicativo podem excluir ou substituir erroneamente os objetos em algum momento, o Cloud Storage tem recursos que ajudam a proteger seus dados:

  • Se você quiser excluir em massa cem mil ou mais objetos, evite usar a gsutil, já que o processo leva muito tempo para ser concluído. Em vez disso, use uma das seguintes opções:

    • O Console do Cloud pode excluir em massa até vários milhões de objetos e faz isso em segundo plano. O Console do Cloud também pode ser usado para excluir em massa apenas os objetos que compartilham um prefixo comum, que aparecem como parte de uma pasta ao usar o Console do Cloud.

    • O Gerenciamento do ciclo de vida do objeto pode excluir em massa qualquer número de objetos. Para excluir objetos em massa no seu bucket, defina uma regra de ciclo de vida no bucket em que a condição tenha Age definido como 0 dias e a ação definida como Delete. Durante o processo de exclusão, a listagem de objetos do bucket em questão pode ser afetada.

Listagem de objetos

Se você acabou de excluir muitos objetos do seu bucket, a listagem de objetos pode ficar temporariamente muito lenta. Isso ocorre porque os registros excluídos não são eliminados imediatamente do sistema de armazenamento subjacente, portanto, a listagem de objetos precisa pular os registros excluídos ao localizar os objetos a serem retornados.

Em algum momento, os registros excluídos são removidos do sistema de armazenamento subjacente, e o desempenho da listagem de objetos se normaliza novamente. Isso normalmente leva algumas horas, mas em alguns casos pode levar alguns dias.

Projete sua carga de trabalho para evitar a listagem de um intervalo de objetos com muitas exclusões recentes. Por exemplo, se você estiver tentando excluir objetos de um bucket listando repetidamente objetos e depois excluindo-os, deverá usar o token de página retornado pela resposta da listagem de objetos para emitir a próxima solicitação de listagem, em vez de reiniciar a listagem para cada solicitação. Quando você reiniciar a listagem desde o início, cada solicitação precisará pular todos os objetos que acabaram de ser excluídos, fazendo com que a listagem de objetos fique mais lenta. Se você tiver excluído muitos objetos sob um determinado prefixo, tente evitar listar objetos nesse prefixo logo após as exclusões.

Hospedagem de site

O tópico Compartilhamento de recursos entre origens (CORS, na sigla em inglês) descreve como permitir que scripts hospedados em outros sites acessem recursos estáticos armazenados em um bucket do Cloud Storage. O cenário inverso é quando você permite que scripts hospedados no Cloud Storage acessem recursos estáticos hospedados em um site fora do Cloud Storage. No segundo cenário, o site está disponibilizando cabeçalhos CORS para que o conteúdo em storage.googleapis.com tenha acesso permitido.

Como prática recomendada, dedique um bucket específico para esse acesso de dados. Essa abordagem impede a superexposição inadvertida de recursos estáticos do site a todo o storage.googleapis.com. Por exemplo, se você quiser dedicar um bucket chamado mybucket para o acesso a dados, faça com que o site exiba o cabeçalho CORS Access-Control-Allow-Origin: https://mybucket.storage.googleapis.com em vez de Access-Control-Allow-Origin: https://storage.googleapis.com.