Prácticas recomendadas

Usa estas prácticas recomendadas como una referencia rápida cuando compiles una aplicación que use 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 la 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.

ID de documento

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

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

    Estos ID 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, es posible que quieras 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 práctico 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 grandes de arreglo o de mapa

Los campos grandes de arreglo 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 arreglo o de mapa, debes excluir el campo de la indexación.

Operaciones de escritura y lectura

  • No escribas en un documento más de una vez por segundo. 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 el primer proceso para iniciar el segundo.

  • No uses compensaciones. En su lugar, usa cursores. Usar un desplazamiento solo evita que se muestren los documentos omitidos 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 Firestore vuelven a intentar realizar de forma automática las transacciones fallidas para lidiar con los errores transitorios. Si tu aplicación accede a Firestore a través de las API de REST o RPC directamente 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 los documentos y controla la tasa de lectura de los 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.

Lo ideal es que tu aplicación configure todos los objetos de escucha de instantáneas requeridos poco después de abrir una conexión a Firestore. Después de configurar tus objetos de escucha de instantáneas iniciales, debes evitar agregar o quitar con rapidez objetos de escucha de instantáneas en la misma conexión.

Para garantizar la coherencia de los datos, 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 nuevos. 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 documentos que la base de datos envía a un cliente individual por debajo de 1 documento por segundo.

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

1,000,000 documentos por segundo

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

Limita la carga útil del documento individual.

10 KiB por segundo

Mantén el tamaño máximo de un documento descargado 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 un documento descargado 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.

Información sobre los límites estándar de Firestore

Ten en cuenta los límites estándar para Firestore, en especial el límite de 1 escritura por segundo para los documentos y el límite de 1,000,000 de conexiones simultáneas por base de datos.

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

No debes actualizar un solo documento más de una vez por segundo. De lo contrario, tu app experimentará problemas de contención, como aumentos de latencia y tiempos de espera, entre otros errores.

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 sufrirlos si realiza alguna de las siguientes acciones:

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

    Firestore asigna los ID de documento con un algoritmo de dispersión. Si creas documentos nuevos con ID automáticos, no deberías encontrar 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 a una tasa muy alta sin aumentar el tráfico de forma gradual.

Acelera el tráfico

Debes acelerar el tráfico de manera gradual en las colecciones nuevas o en los documentos que se encuentren cerca de manera lexicográfica. Esto permite que 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. Por ejemplo, puedes usar este programa de aceleración para incrementar tu tráfico de lectura a 740,000 operaciones por segundo después de 90 minutos. Asimismo, puedes acelerar el tráfico de escritura, pero ten en cuenta los límites estándar de Firestore. Asegúrate de que las operaciones se encuentren distribuidas de manera 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 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 ID 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 mejor estrategia es copiar el documento antiguo a la colección nueva y, luego, borrarlo. Acelera las lecturas paralelas de manera gradual para asegurarte de que Firestore pueda controlar el tráfico hacia la colección nueva.

Una estrategia útil para acelerar de forma gradual 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 ID 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. 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 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 aumentaría los costos generados en Firestore.