Saltar al contenido

Implementación de contador idempotente con Firebase Firestore

Te recomendamos que pruebes esta solución en un entorno controlado antes de pasarlo a producción, un saludo.

Solución:

La respuesta a esta pregunta dependerá de los diferentes aspectos de cómo está utilizando la colección, así como de lo que significa “contar perfectamente” para usted.

Preámbulo

Para empezar, dado que las invocaciones de Cloud Function son asincrónicas con la escritura, el contador estará ligeramente por detrás del true recuento de la colección. Asumo que esto está bien.

Incluso si contó la colección leyendo todos los documentos, el recuento aún podría estar obsoleto, ya que es posible que se hayan insertado o eliminado documentos mientras estaba contando.

Costos

Mencionas “sin ser demasiado caro”. Aquí debemos comprender la frecuencia con la que lee el recuento y la frecuencia con la que agrega o elimina documentos. Para mantener un contador separado, lo leerá / escribirá para cada cambio en el recuento de documentos. Dado que las escrituras son 3 veces el precio de las lecturas, esto significa que deberá contar cada documento 4 o más veces para recuperar el costo de llevar la cuenta. Aquí hay una fórmula en alguna parte que tiene en cuenta el número promedio de recuentos durante la vida útil de un documento, pero lo dejo como un ejercicio para el lector.

Contadores idempotentes

Este es un problema interesante, que es otro familiar para los sistemas distribuidos. Si un solicitudes de clientes para agregar +1 a un contador, y la solicitud se agota (el servidor nunca responde), ¿es seguro volver a solicitar? ¿Qué pasa si el servidor aplicó el incremento pero luego experimentó un problema de red? ¿Y si no fuera así?

A continuación, responderé algunos métodos para lidiar con esta situación.

Contadores idempotentes: ID de transacción

Una forma de lidiar con esto es enviar una identificación de transacción única (txid) con la solicitud de incremento. Si el servidor ya ha procesado el txid antes, sabe que es una solicitud duplicada y puede responder que ya lo ha hecho.

En su caso de uso, si nunca elimina documentos, puede usar la identificación del documento como txid. En el mostrador, agregue la identificación del documento a un array de incrementos procesados ​​cuando haces +1. Antes de hacer esto, verifique que no exista ya en el array (indicando que ya ha sido procesado).

Un problema obvio con lo anterior es la array continuará creciendo y eventualmente se volverá demasiado grande. Por lo tanto, querremos limitar cuánto tiempo hacemos un seguimiento de los identificadores antiguos. Puede usar una marca de tiempo y eliminar todo lo que sea anterior a ‘X’, o simplemente podría tratar array como un búfer circular para mantenerlo en un tamaño máximo fijo.

Ambos enfoques son razonables para velocidades de escritura lentas, pero no serían suficientes para una escritura más rápida. Por ejemplo, a 1000 escrituras / segundo, serían 5000 ID de documentos solo para cubrir 5 segundos (mencionamos en nuestra documentación de límites que una función puede tardar más de 5 segundos en ejecutarse).

Introduzca los filtros de floración olvidadiza

Contadores idempotentes – Filtros de floración olvidadiza

Esta el método da usted admite una tasa de escritura mucho más alta a cambio de una posibilidad muy pequeña de pensar que ha visto una identificación de documento antes.

No detallaré la implementación aquí, pero hay una excelente descripción general de la misma en este blog: Contadores, filtros de idempotencia y floración olvidadiza

Contadores idempotentes – Eliminando

Una complejidad adicional es el manejo de eliminaciones. Si usa identificadores únicos y está seguro de que no se reutilizará (por ejemplo, nuestro soporte nativo de identificación automática), esto no es demasiado difícil de agregar. Simplemente repita lo que hizo para las adiciones, pero en una lista / campo separado y asegúrese de verificar ambas listas.

Una cosa menor en la que pensar es que Cloud Functions no tiene un orden de ejecución garantizado. Esto significa que es posible que vea una eliminación antes de una inserción si ocurren lo suficientemente cerca.

Mi recomendación es que si ve una eliminación antes de una inserción, disminuya el contador de antemano sabiendo que se ajustará pronto, y si ve una inserción después de una eliminación, realice el incremento. Esto se debe a que solo mantiene una cierta cantidad de historial, por lo que no puede saber si la inserción y la eliminación están fuera de orden, o si la eliminación es demasiado posterior a la inserción.

Otros metodos

Según el tamaño de la colección, la precisión que debe tener y la frecuencia con la que se usa el recuento, puede llamar periódicamente a una función en la nube para calcular el recuento y almacenarlo en un documento. Puede escalar dinámicamente esto en función del tamaño de la colección para minimizar el retraso. Para colecciones realmente pequeñas, hágalo con frecuencia, para colecciones más grandes, hágalo con menos frecuencia.

También puede aplicar optimizaciones de costos aquí si tiene un mecanismo para determinar los documentos que ya ha contado (por lo que solo necesita contar los nuevos). Si las eliminaciones son poco frecuentes, puede agregar un evento para disminuir el contador de eliminaciones.

En este momento, debido a la falta de garantías en torno a la integración de Cloud Firestore + Cloud Functions, la única forma de estar 100% seguro de que su recuento es exacto es leer la colección completa cada vez que escribe el recuento.

Como dijiste, eso no es terriblemente eficiente (en términos de velocidad o costo).

Si desea intentar mantener el recuento a medida que ingresa cada escritura sin leer repetidamente toda la colección, considere agregar un counted booleano para cada documento.

Luego, cuando ingresa un documento, usted hace lo siguiente en una transacción:

  1. Lea el documento. Si counted == true, Salida
  2. Incrementa el recuento.
  3. Marcos counted como true.

Para obtener más información sobre las transacciones en Cloud Firestore, consulte los documentos: https://firebase.google.com/docs/firestore/manage-data/transactions

valoraciones y reseñas

Si te gusta el asunto, tienes la habilidad dejar un tutorial acerca de qué le añadirías a esta reseña.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *