Firebase volverá a Google I/O el 10 de mayo. Registrarse ahora

Prácticas recomendadas para Cloud Firestore

Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Usa estas prácticas recomendadas como referencia rápida cuando compiles una aplicación que use Cloud Firestore.

Ubicación de la base de datos

Cuando crees tu instancia de base de datos, selecciona la ubicación más cercana a los usuarios y recursos de procesamiento. Los saltos de red de largo alcance son más propensos a errores y aumentan la latencia de las consultas.

Para maximizar la disponibilidad y durabilidad de tu aplicación, selecciona una ubicación multirregional y coloca recursos de procesamiento críticos en al menos dos regiones.

Selecciona una ubicación regional para disminuir los costos o la latencia de las operaciones de escritura si tu aplicación es sensible a la latencia o si deseas una ubicación conjunta con otros recursos de GCP.

IDs de documento

  • No uses . y .. en los IDs de documento.
  • No uses barras diagonales / en los IDs de documento.
  • No uses IDs de documento que aumenten monótonamente, como los siguientes ejemplos:

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

    Estos IDs secuenciales pueden generar hotspots que afectan la latencia.

Nombres de campos

  • No uses los siguientes caracteres en los nombres de campos, ya que requieren escapes adicionales:

    • . punto
    • [ corchete izquierdo
    • ] corchete derecho
    • * asterisco
    • ` acento grave

Índices

  • No uses demasiados índices. Una cantidad excesiva de índices puede aumentar la latencia de escritura y los costos de almacenamiento de las entradas de índice.

  • Ten en cuenta que indexar campos con valores que incrementan monótonamente, como las marcas de tiempo, puede generar hotspots que afectan la latencia de las aplicaciones con tasas altas de lectura y escritura.

Exenciones de índices

En la mayoría de las apps, puedes usar la indexación automática y los vínculos de mensajes de error para administrar tus índices. Sin embargo, tal vez debas agregar exenciones de campo único en los siguientes casos:

Caso Descripción
Campos de string grandes

Si tienes un campo de string que suele tener valores de string largos que no usas para realizar consultas, exime al campo de la indexación a fin de reducir los costos de almacenamiento.

Tasas altas de escritura en una colección que tiene documentos con valores secuenciales

Si indexas un campo que aumenta o disminuye secuencialmente entre los documentos de una colección, como una marca de tiempo, la tasa máxima de escritura en la colección es de 500 operaciones de escritura por segundo. Si no realizas consultas basadas en campos con valores secuenciales, puedes eximir al campo de la indexación para pasar ese límite.

Por ejemplo, en un caso de uso de IoT con una tasa alta de escritura, es posible que una colección de documentos con un campo de marca de tiempo se acerque al límite de 500 operaciones de escritura por segundo.

Campos TTL

Si usas políticas de TTL (tiempo de actividad), ten en cuenta que el campo TTL debe ser una marca de tiempo. La indexación en los campos TTL está habilitada de forma predeterminada y puede afectar el rendimiento con tasas de tráfico más altas. Como práctica recomendada, agrega exenciones de campo único para tus campos TTL.

Campos grandes de array o de mapa

Los campos grandes de array o de mapa pueden acercarse al límite de 40,000 entradas de índice por documento. Si no realizas consultas basadas en un campo grande de array o de mapa, debes excluir el campo de la indexación.

Operaciones de lectura y escritura

  • La frecuencia máxima exacta con la que una app puede actualizar un solo documento depende en gran medida de la carga de trabajo. Para obtener más información, consulta Actualizaciones en un solo documento.

  • Usa llamadas asíncronas en vez de síncronas cuando sea posible. Las llamadas asíncronas minimizan el impacto en la latencia. Por ejemplo, considera una aplicación que necesite el resultado de una consulta y de la búsqueda de un documento antes de procesar una respuesta. Si la búsqueda y la consulta no tienen una dependencia de datos, no es necesario esperar de manera síncrona hasta que finalice la búsqueda para iniciar la consulta.

  • No uses desplazamientos. En su lugar, usa cursores. Usar un desplazamiento solo evita que los documentos omitidos se muestren a tu aplicación, pero aún se recuperan internamente. Los documentos omitidos afectan la latencia de la consulta, y tu aplicación se factura por las operaciones de lectura necesarias para recuperarlos.

Reintentos de transacciones

Los SDK y las bibliotecas cliente de Cloud Firestore reintentan automáticamente las transacciones fallidas para lidiar con los errores transitorios. Si tu aplicación accede a Cloud Firestore a través de las APIs de REST o RPC de forma directa en lugar de hacerlo a través de un SDK, debes implementar reintentos de transacción en ella para aumentar la confiabilidad.

Actualizaciones en tiempo real

Para obtener el mejor rendimiento en los objetos de escucha de instantáneas, limita el tamaño de tus documentos y controla la tasa de lectura de tus clientes. Las siguientes recomendaciones proporcionan lineamientos para maximizar el rendimiento. Superar estas recomendaciones puede provocar un aumento en la latencia de las notificaciones.

Recomendación Detalles
Reduce la tasa de descarte de los objetos de escucha de instantáneas.

Evita descartar con frecuencia a los objetos de escucha, en especial cuando tu base de datos está recibiendo una carga de escritura importante.

Idealmente, tu aplicación debería configurar todos los objetos de escucha de instantáneas requeridos poco después de abrir una conexión a Cloud Firestore. Después de configurar tus objetos de escucha de instantáneas iniciales, debes evitar agregar o quitar rápidamente objetos de escucha de instantáneas en la misma conexión.

Para garantizar la coherencia de los datos, Cloud Firestore debe preparar cada objeto de escucha de instantáneas nuevo a partir de sus datos de origen y, luego, ponerse al día con los cambios recientes. Según la tasa de escritura de tu base de datos, esta puede ser una operación costosa.

Tus objetos de escucha de instantáneas pueden experimentar una latencia mayor si agregas o quitas objetos de escucha de instantáneas a las referencias de forma frecuente. En general, un objeto de escucha constantemente conectado funciona mejor que conectar y desconectar un objeto de escucha en esa ubicación para la misma cantidad de datos. Para obtener el mejor rendimiento, los objetos de escucha de instantáneas deben tener una vida útil de 30 segundos o más. Si ocurren problemas de rendimiento de los objetos de escucha en tu app, intenta hacer un seguimiento de las escuchas y las anulaciones de la aplicación para determinar si pueden estar ocurriendo con demasiada frecuencia.

Limita los objetos de escucha de instantáneas por cliente.

100

Mantén la cantidad de objetos de escucha de instantáneas por cliente por debajo de 100.

Limita la tasa de escritura de la colección.

1,000 operaciones por segundo

Mantén la tasa de operaciones de escritura para una colección individual por debajo de las 1,000 operaciones por segundo.

Limita la tasa de envíos a un cliente individual.

1 documento por segundo

Mantén la tasa de envío de documentos de la base de datos a un cliente individual por debajo de 1 documento por segundo.

Limita la tasa de envío global a los clientes.

1,000,000 de documentos por segundo

Mantén la tasa de envío de documentos de la base de datos a todos los clientes por debajo de 1,000,000 de documentos por segundo.

Este es un límite flexible. Cloud Firestore no te impide excederlo, pero hacerlo afectará el rendimiento de forma considerable.

Limita la carga útil de cada documento.

10 KiB por segundo

Mantén el tamaño máximo de documentos descargados por un cliente individual por debajo de los 10 KiB por segundo.

Limita la carga útil global de los documentos.

1 GiB por segundo

Mantén el tamaño máximo de documentos descargados en todos los clientes por debajo de 1 GiB por segundo.

Limita la cantidad de campos por documento.

100

Tus documentos deberían tener menos de 100 campos.

Comprende los límites estándar de Cloud Firestore.

Ten en cuenta los límites estándar de Cloud Firestore.

Presta especial atención al límite de 1 operación de escritura por segundo para los documentos y el límite de 1,000,000 de conexiones simultáneas por base de datos. Estos son límites flexibles, y Cloud Firestore no te impide superarlos. Sin embargo, hacerlo podría afectar el rendimiento en función de la frecuencia total de tus operaciones de lectura y escritura.

Diseña para el escalamiento

En las siguientes recomendaciones, se describe cómo evitar situaciones que generen problemas de contención.

Actualizaciones en un solo documento

Mientras diseñas tu app, ten en cuenta la rapidez con la que esta actualiza los documentos individuales. La mejor manera de definir el rendimiento de tu carga de trabajo es realizar pruebas de carga. La frecuencia máxima exacta con la que una app puede actualizar un solo documento depende en gran medida de la carga de trabajo. Los factores incluyen la tasa de escritura, la competencia entre las solicitudes y la cantidad de índices afectados.

Una operación de escritura de documento actualiza el documento y los índices asociados, y Cloud Firestore aplica de manera síncrona la operación de escritura en un quórum de réplicas. Con tasas de escritura lo suficientemente altas, la base de datos comenzará a encontrar contención, mayor latencia o cualquier otro error.

Tasas altas de lectura, escritura y eliminación en un rango pequeño de documentos

Evita las tasas altas de lectura o escritura en documentos que se encuentren cerca lexicográficamente. De lo contrario, tu aplicación experimentará errores de contención. Este problema se conoce como generación de hotspots, y tu aplicación puede sufrirlo si realiza alguna de las siguientes acciones:

  • Crea documentos nuevos a una tasa muy alta y asigna sus propios IDs que incrementan de forma monótona.

    Cloud Firestore asigna los IDs de documento con un algoritmo de dispersión. Si creas documentos nuevos con IDs automáticos, no deberías encontrar generación de hotspots durante las operaciones de escritura.

  • Crea documentos nuevos a una tasa alta en una colección que tiene pocos documentos.

  • Crea documentos nuevos con un campo que incrementa monótonamente, como una marca de tiempo, a una tasa muy alta.

  • Borra documentos de una colección a una tasa alta.

  • Escribe en la base de datos con una frecuencia muy alta sin aumentar el tráfico de forma gradual.

Evita omitir los datos borrados

Evita las consultas que omitan datos borrados recientemente. Es posible que una consulta deba omitir una gran cantidad de entradas de índice si los primeros resultados se borraron recientemente.

Por ejemplo, si una carga de trabajo busca los elementos más antiguos de la cola, seguramente deba omitir muchos datos borrados. La consulta podría verse de la siguiente manera:

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 se ejecuta esta consulta, se escanean las entradas de índice del campo created en los documentos borrados recientemente. Esto ralentiza las consultas.

Si deseas mejorar el rendimiento, usa el método start_at para encontrar el mejor punto de partida. Por ejemplo:

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: En el ejemplo anterior, se usa un campo que incrementa monótonamente, que es un antipatrón para tasas altas de escritura.

Acelera el tráfico

Debes acelerar el tráfico de manera gradual en las colecciones nuevas o en los documentos que se encuentren cerca lexicográficamente. Esto permite que Cloud Firestore tenga tiempo suficiente para preparar los documentos según el aumento de tráfico. Te recomendamos que empieces con un máximo de 500 operaciones por segundo en una colección nueva. Luego, puedes incrementar el tráfico un 50% cada 5 minutos. Asimismo, puedes acelerar el tráfico de escritura, pero ten en cuenta los límites estándar de Cloud Firestore. Asegúrate de que las operaciones se encuentren distribuidas de manera relativamente uniforme en todo el rango de claves. Esto se conoce como la regla “500/50/5”.

Migra el tráfico a una colección nueva

Una aceleración gradual es muy importante si migras el tráfico de la app de una colección a otra. Una forma sencilla de controlar esta migración es leer la colección antigua, y, si el documento no existe, leer la colección nueva. Sin embargo, esto podría causar un aumento repentino del tráfico de los documentos que se encuentran cerca lexicográficamente en la colección nueva. Es posible que Cloud Firestore no pueda preparar de manera eficiente la colección nueva para el aumento del tráfico, en especial si contiene pocos documentos.

Es posible que ocurra un problema similar si cambias los IDs de muchos documentos que están en la misma colección.

La mejor estrategia para migrar el tráfico a una colección nueva depende de tu modelo de datos. A continuación, se muestra un ejemplo de estrategia que se conoce como lecturas paralelas. Deberás determinar si esta estrategia es eficaz para tus datos y tener en cuenta el impacto del costo de las operaciones paralelas durante la migración.

Lecturas paralelas

Para implementar lecturas paralelas mientras migras el tráfico a una colección nueva, lee primero el documento de la colección antigua. Si no existe, léelo de la colección nueva. Una tasa alta de lecturas de documentos que no existen puede causar una generación de hotspots, por lo que debes asegurarte de aumentar la carga gradualmente en la colección nueva. Una estrategia mejor es copiar el documento antiguo a la colección nueva y, luego, borrarlo. Acelera las lecturas paralelas de manera gradual para asegurarte de que Cloud Firestore pueda controlar el tráfico hacia la colección nueva.

Una estrategia útil para acelerar gradualmente las lecturas o escrituras hacia una colección nueva es usar un hash determinista del ID de usuario a fin de seleccionar un porcentaje aleatorio de usuarios que tratan de escribir documentos nuevos. Asegúrate de que el resultado del hash del ID de usuario no se encuentre sesgado por tu función o el comportamiento del usuario.

Mientras tanto, ejecuta un trabajo por lotes que copie todos tus datos de los documentos antiguos a la colección nueva. Este trabajo debe evitar las operaciones de escritura en los IDs de documento secuenciales para prevenir la generación de hotspots. Cuando se complete el trabajo por lotes, solo podrás leer la colección nueva.

Una versión mejorada de esta estrategia consiste en migrar lotes pequeños de usuarios a la vez. Primero, agrega un campo al documento del usuario que realice un seguimiento del estado de la migración de ese usuario. Luego, selecciona un lote de usuarios para migrar en función de un hash del ID de usuario. Por último, usa un trabajo por lotes a fin de migrar los documentos de ese lote de usuarios y usa lecturas paralelas para los usuarios que estén en el proceso de migración.

Ten en cuenta que no es fácil revertir el proceso, a menos que realices operaciones de escritura dobles de las entidades antiguas y nuevas durante la fase de migración. Esto incrementará los costos incurridos por Cloud Firestore.

Evita el acceso no autorizado

Evita las operaciones no autorizadas en tu base de datos con las reglas de seguridad de Cloud Firestore. Por ejemplo, usar reglas permite evitar una situación en la que un usuario malicioso descargue reiteradamente toda tu base de datos.

Obtén más información sobre cómo usar las reglas de seguridad de Cloud Firestore.