Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Práticas recomendadas para o Cloud Firestore

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Use as práticas recomendadas listadas aqui como uma referência rápida ao criar um aplicativo que usa o Cloud Firestore.

Localização do banco de dados

Ao criar sua instância de banco de dados, selecione o local do banco de dados mais próximo de seus usuários e recursos de computação. Os saltos de rede de longo alcance são mais propensos a erros e aumentam a latência da consulta.

Para maximizar a disponibilidade e a durabilidade de seu aplicativo, selecione um local multirregional e coloque recursos de computação críticos em pelo menos duas regiões.

Selecione um local regional para custos mais baixos, para menor latência de gravação se seu aplicativo for sensível à latência ou para colocalização com outros recursos do GCP .

IDs de documento

  • Evite os IDs de documento . e .. .
  • Evite usar / barras em IDs de documentos.
  • Não use IDs de documento que aumentam monotonicamente, como:

    • Customer1 , Customer2 , Customer3 ,...
    • Product 1 , Product 2 , Product 3 , ...

    Esses IDs sequenciais podem levar a pontos de acesso que afetam a latência.

Nomes de campo

  • Evite os seguintes caracteres em nomes de campo porque eles exigem escape extra:

    • . período
    • [ colchete esquerdo
    • ] colchete direito
    • * asterisco
    • ` acento grave

Índices

  • Evite usar muitos índices. Um número excessivo de índices pode aumentar a latência de gravação e aumentar os custos de armazenamento para entradas de índice.

  • Esteja ciente de que a indexação de campos com valores crescentes monotônicos, como registros de data e hora, pode levar a pontos de acesso que afetam a latência de aplicativos com altas taxas de leitura e gravação.

Isenções de índice

Para a maioria dos aplicativos, você pode confiar na indexação automática, bem como em qualquer link de mensagem de erro para gerenciar seus índices. No entanto, você pode querer adicionar isenções de campo único nos seguintes casos:

Caso Descrição
Campos de string grandes

Se você tiver um campo de string que geralmente contém valores de string longos que não são usados ​​para consulta, você pode reduzir os custos de armazenamento isentando o campo da indexação.

Altas taxas de gravação em uma coleção contendo documentos com valores sequenciais

Se você indexar um campo que aumenta ou diminui sequencialmente entre documentos em uma coleção, como um registro de data e hora, a taxa máxima de gravação para a coleção é de 500 gravações por segundo. Se você não consultar com base no campo com valores sequenciais, poderá isentar o campo da indexação para ignorar esse limite.

Em um caso de uso de IoT com alta taxa de gravação, por exemplo, uma coleção contendo documentos com um campo de carimbo de data/hora pode se aproximar do limite de 500 gravações por segundo.

campos TTL

Se você usar políticas TTL (time-to-live) , observe que o campo TTL deve ser um carimbo de data/hora. A indexação em campos TTL é habilitada por padrão e pode afetar o desempenho em taxas de tráfego mais altas. Como prática recomendada, adicione isenções de campo único para seus campos TTL.

Matriz grande ou campos de mapa

Grandes campos de matriz ou mapa podem se aproximar do limite de 40.000 entradas de índice por documento. Se você não estiver consultando com base em uma grande matriz ou campo de mapa, deverá isentá-lo da indexação.

Operações de leitura e gravação

  • Evite escrever em um documento mais de uma vez por segundo. Para obter mais informações, consulte Atualizações em um único documento .

  • Use chamadas assíncronas quando disponíveis em vez de chamadas síncronas. As chamadas assíncronas minimizam o impacto da latência. Por exemplo, considere um aplicativo que precisa do resultado de uma pesquisa de documento e dos resultados de uma consulta antes de renderizar uma resposta. Se a pesquisa e a consulta não tiverem uma dependência de dados, não há necessidade de esperar de forma síncrona até que a pesquisa seja concluída antes de iniciar a consulta.

  • Não use compensações. Em vez disso, use cursores . O uso de um deslocamento apenas evita o retorno dos documentos ignorados ao seu aplicativo, mas esses documentos ainda são recuperados internamente. Os documentos ignorados afetam a latência da consulta e seu aplicativo é cobrado pelas operações de leitura necessárias para recuperá-los.

Novas tentativas de transações

Os SDKs do Cloud Firestore e as bibliotecas de cliente repetem automaticamente as transações com falha para lidar com erros transitórios. Se seu aplicativo acessa o Cloud Firestore por meio das APIs REST ou RPC diretamente em vez de um SDK, seu aplicativo deve implementar novas tentativas de transação para aumentar a confiabilidade.

Atualizações em tempo real

Para obter o melhor desempenho do ouvinte instantâneo , mantenha seus documentos pequenos e controle a taxa de leitura de seus clientes. As recomendações a seguir fornecem diretrizes para maximizar o desempenho. Exceder essas recomendações pode resultar em maior latência de notificação.

Recomendação Detalhes
Reduza a taxa de rotatividade do ouvinte de instantâneo

Evite a rotatividade frequente de ouvintes, especialmente quando seu banco de dados estiver sob carga de gravação significativa

Idealmente, seu aplicativo deve configurar todos os ouvintes de instantâneo necessários logo após abrir uma conexão com o Cloud Firestore. Depois de configurar seus ouvintes de instantâneo iniciais, você deve evitar adicionar ou remover rapidamente ouvintes de instantâneo na mesma conexão.

Para garantir a consistência dos dados, o Cloud Firestore precisa preparar cada novo ouvinte de instantâneo de seus dados de origem e acompanhar as novas alterações. Dependendo da taxa de gravação do seu banco de dados, essa pode ser uma operação cara.

Seus ouvintes de instantâneo podem experimentar maior latência se você adicionar ou remover ouvintes de instantâneo com frequência às referências. Em geral, um ouvinte conectado constantemente tem um desempenho melhor do que anexar e desanexar um ouvinte naquele local para a mesma quantidade de dados. Para obter o melhor desempenho, os ouvintes de instantâneo devem ter um tempo de vida de 30 segundos ou mais. Se você encontrar problemas de desempenho do ouvinte em seu aplicativo, tente rastrear as escutas e não escutas de seu aplicativo para determinar se eles podem estar acontecendo com muita frequência.

Limite os ouvintes de instantâneos por cliente

100

Mantenha o número de ouvintes de instantâneo por cliente abaixo de 100.

Limitar a taxa de gravação da coleção

1.000 operações/segundo

Mantenha a taxa de operações de gravação para uma coleção individual abaixo de 1.000 operações/segundo.

Limite a taxa de envio de cliente individual

1 documento/segundo

Mantenha a taxa de documentos que o banco de dados envia para um cliente individual abaixo de 1 documento/segundo.

Limite a taxa global de push do cliente

1.000.000 de documentos/segundo

Mantenha a taxa de documentos que o banco de dados envia para todos os clientes abaixo de 1.000.000 de documentos/segundo.

Este é um limite suave. O Cloud Firestore não impede que você ultrapasse esse limite, mas afeta muito o desempenho.

Limite a carga útil do documento individual

10 KiB/segundo

Mantenha o tamanho máximo do documento baixado por um cliente individual abaixo de 10 KiB/segundo.

Limitar a carga útil global do documento

1 GiB/segundo

Mantenha o tamanho máximo do documento baixado em todos os clientes abaixo de 1 GiB/segundo.

Limite o número de campos por documento

100

Seus documentos devem ter menos de 100 campos.

Entenda os limites padrão do Cloud Firestore

Lembre-se dos limites padrão do Cloud Firestore .

Preste atenção especial ao limite de 1 gravação por segundo para documentos e ao limite de 1.000.000 de conexões simultâneas por banco de dados. Esses são limites suaves que o Cloud Firestore não impede que você exceda. No entanto, ultrapassar esses limites pode afetar o desempenho, dependendo das taxas totais de leitura e gravação.

Projetando para escala

As práticas recomendadas a seguir descrevem como evitar situações que criam problemas de contenção.

Atualizações em um único documento

Ao projetar seu aplicativo, considere a rapidez com que ele atualiza documentos individuais. A melhor maneira de caracterizar o desempenho de sua carga de trabalho é realizar testes de carga. A taxa máxima exata que um aplicativo pode atualizar um único documento depende muito da carga de trabalho. Os fatores incluem a taxa de gravação, contenção entre solicitações e o número de índices afetados.

Uma operação de gravação de documento atualiza o documento e quaisquer índices associados, e o Cloud Firestore aplica a operação de gravação de forma síncrona em um quorum de réplicas. Em taxas de gravação altas o suficiente, o banco de dados começará a encontrar contenção, latência mais alta ou outros erros.

Altas taxas de leitura, gravação e exclusão para um intervalo estreito de documentos

Evite altas taxas de leitura ou gravação para fechar documentos lexicograficamente, ou seu aplicativo apresentará erros de contenção. Esse problema é conhecido como ponto de acesso, e seu aplicativo pode apresentar ponto de acesso se fizer um dos seguintes:

  • Cria novos documentos a uma taxa muito alta e aloca seus próprios IDs monotonicamente crescentes.

    O Cloud Firestore aloca IDs de documentos usando um algoritmo de dispersão. Você não deve encontrar pontos de acesso em gravações se criar novos documentos usando IDs de documentos automáticos.

  • Cria novos documentos em alta velocidade em uma coleção com poucos documentos.

  • Cria novos documentos com um campo monotonicamente crescente, como um timestamp, em uma taxa muito alta.

  • Exclui documentos em uma coleção em alta velocidade.

  • Grava no banco de dados a uma taxa muito alta sem aumentar gradualmente o tráfego.

Evite pular dados excluídos

Evite consultas que pulem dados excluídos recentemente. Uma consulta pode ter que ignorar um grande número de entradas de índice se os primeiros resultados da consulta tiverem sido excluídos recentemente.

Um exemplo de uma carga de trabalho que pode ter que ignorar muitos dados excluídos é aquela que tenta localizar os itens de trabalho enfileirados mais antigos. A consulta pode se parecer com:

docs = db.collection('WorkItems').order_by('created').limit(100)
delete_batch = db.batch()
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
delete_batch.commit()

Cada vez que essa consulta é executada, ela examina as entradas de índice do campo created em quaisquer documentos excluídos recentemente. Isso atrasa as consultas.

Para melhorar o desempenho, use o método start_at para encontrar o melhor lugar para começar. Por exemplo:

completed_items = db.collection('CompletionStats').document('all stats').get()
docs = db.collection('WorkItems').start_at(
    {'created': completed_items.get('last_completed')}).order_by(
        'created').limit(100)
delete_batch = db.batch()
last_completed = None
for doc in docs.stream():
  finish_work(doc)
  delete_batch.delete(doc.reference)
  last_completed = doc.get('created')

if last_completed:
  delete_batch.update(completed_items.reference,
                      {'last_completed': last_completed})
  delete_batch.commit()

NOTA: O exemplo acima usa um campo de aumento monotônico que é um antipadrão para altas taxas de gravação.

Aumentando o tráfego

Você deve aumentar gradualmente o tráfego para novas coleções ou fechar documentos lexicograficamente para dar ao Cloud Firestore tempo suficiente para preparar os documentos para o aumento do tráfego. Recomendamos começar com no máximo 500 operações por segundo para uma nova coleta e depois aumentar o tráfego em 50% a cada 5 minutos. Da mesma forma, você pode aumentar seu tráfego de gravação, mas lembre-se dos limites padrão do Cloud Firestore . Certifique-se de que as operações sejam distribuídas de maneira relativamente uniforme em todo o intervalo de chaves. Isso é chamado de regra "500/50/5".

Migrando o tráfego para uma nova coleção

O aumento gradual é particularmente importante se você migrar o tráfego do aplicativo de uma coleção para outra. Uma maneira simples de lidar com essa migração é ler a coleção antiga e, se o documento não existir, ler a nova coleção. No entanto, isso pode causar um aumento repentino de tráfego para fechar documentos lexicograficamente na nova coleção. O Cloud Firestore pode não conseguir preparar com eficiência a nova coleção para o aumento do tráfego, especialmente quando contém poucos documentos.

Um problema semelhante pode ocorrer se você alterar as IDs de muitos documentos na mesma coleção.

A melhor estratégia para migrar o tráfego para uma nova coleção depende do seu modelo de dados. Abaixo está um exemplo de estratégia conhecida como leituras paralelas . Você precisará determinar se essa estratégia é ou não eficaz para seus dados, e uma consideração importante será o impacto de custo das operações paralelas durante a migração.

leituras paralelas

Para implementar leituras paralelas ao migrar o tráfego para uma nova coleção, leia primeiro a partir da coleção antiga. Se o documento estiver ausente, leia a nova coleção. Uma alta taxa de leituras de documentos inexistentes pode levar a hotspotting, portanto, certifique-se de aumentar gradualmente a carga para a nova coleção. Uma estratégia melhor é copiar o documento antigo para a nova coleção e, em seguida, excluir o documento antigo. Aumente gradualmente as leituras paralelas para garantir que o Cloud Firestore possa lidar com o tráfego para a nova coleção.

Uma estratégia possível para aumentar gradualmente as leituras ou gravações em uma nova coleção é usar um hash determinístico do ID do usuário para selecionar uma porcentagem aleatória de usuários que tentam gravar novos documentos. Certifique-se de que o resultado do hash do ID do usuário não seja distorcido por sua função ou pelo comportamento do usuário.

Enquanto isso, execute um trabalho em lote que copie todos os seus dados dos documentos antigos para a nova coleção. Seu trabalho em lote deve evitar gravações em IDs de documentos sequenciais para evitar pontos de acesso. Quando o trabalho em lote for concluído, você poderá ler somente a partir da nova coleção.

Um refinamento dessa estratégia é migrar pequenos lotes de usuários por vez. Adicione um campo ao documento do usuário que rastreie o status de migração desse usuário. Selecione um lote de usuários para migrar com base em um hash do ID do usuário. Use um trabalho em lote para migrar documentos para esse lote de usuários e use leituras paralelas para usuários no meio da migração.

Observe que você não pode reverter facilmente, a menos que faça gravações duplas das entidades antigas e novas durante a fase de migração. Isso aumentaria os custos incorridos do Cloud Firestore.

Impedir o acesso não autorizado

Evite operações não autorizadas em seu banco de dados com as regras de segurança do Cloud Firestore. Por exemplo, o uso de regras pode evitar um cenário em que um usuário mal-intencionado baixa repetidamente todo o seu banco de dados.

Saiba mais sobre como usar as regras de segurança do Cloud Firestore .