En esta página, se describen las prácticas recomendadas para leer desde Pub/Sub en Dataflow.
Apache Beam proporciona una implementación de referencia del conector de E/S de Pub/Sub para que lo usen ejecutores que no sean de Dataflow. Sin embargo, el ejecutor de Dataflow usa su propia implementación personalizada del conector. Además, aprovecha las APIs y los servicios internos de Google Cloud para ofrecer marcas de agua de baja latencia, alta precisión de marcas de agua y anulación de duplicación eficiente para el procesamiento de mensajes del tipo “exactamente una vez”. El conector está disponible para Java, Python y Go.
Procesamiento “exactamente una vez”
Pub/Sub separa los publicadores de eventos de los consumidores de eventos. La aplicación publica mensajes en un tema, y Pub/Sub entrega los mensajes a los suscriptores de forma asíncrona.
Pub/Sub asigna un ID de mensaje único a cada mensaje que se publica con éxito en un tema. De forma predeterminada, Pub/Sub realiza la entrega de mensajes al menos una vez. Para lograr una semántica de “al menos una vez”, Pub/Sub vuelve a intentar la entrega si no recibe la confirmación de recepción del suscriptor dentro del plazo de confirmación. Los reintentos pueden hacer que un mensaje se entregue más de una vez. Por ejemplo, la entrega puede ocurrir si el suscriptor confirma la recepción después de la fecha límite o si la confirmación de recepción se pierde debido a problemas transitorios de la red.
Si ejecutas la canalización de Dataflow con el modo de transmisión “exactamente una vez”, Dataflow anula el duplicado de los mensajes para lograr una semántica del tipo “exactamente una vez”. Si tu canalización puede tolerar algunos registros duplicados, considera usar el modo de transmisión “al menos una vez”. Este modo puede reducir la latencia y el costo total de la canalización de forma significativa. La desventaja es que algunos mensajes pueden procesarse dos veces. Para obtener más información, consulta Elige qué modo de transmisión usar.
Anula duplicados por atributo de mensaje
De forma predeterminada, Dataflow anula los duplicados según el ID del mensaje. Sin embargo, una aplicación puede enviar el mismo registro dos veces como dos mensajes de Pub/Sub distintos. Por ejemplo, los datos fuente originales podrían contener registros duplicados, o la aplicación podría publicar el mismo mensaje dos veces de forma incorrecta. Esto último puede suceder debido a reintentos, si la confirmación de recepción se descartó debido a problemas de red o a otras interrupciones. En estos casos, los mensajes duplicados tienen ID de mensaje diferentes.
Según tu situación, tus datos pueden contener un campo único que se puede usar para anular la duplicación. Por ejemplo, los registros pueden contener un ID de transacción único. Puedes configurar el conector de E/S de Pub/Sub para anular los mensajes duplicados según el valor de un atributo de mensaje, en lugar de usar el ID de mensaje de Pub/Sub. Siempre que el publicador establezca este atributo de forma coherente durante los reintentos, Dataflow puede detectar los duplicados. Los mensajes se deben publicar en Pub/Sub en un plazo de 10 minutos entre sí para anular la duplicación.
Para obtener más información sobre el uso de atributos de ID, consulta los siguientes temas de referencia del SDK:
withIdAttribute
(Java)ReadFromPubSub
(Python)ReadOptions
(Go)
Suscripciones
Cuando configuras tu canalización, especificas un tema de Pub/Sub o una suscripción de Pub/Sub desde la cual leer. Si especificas una suscripción, no uses la misma suscripción de Pub/Sub para varias canalizaciones. Si dos canalizaciones leen desde una sola suscripción, cada canalización recibe parte de los datos de una manera no determinista, lo que puede causar mensajes duplicados, un retraso de marca de agua y un ajuste de escala automático ineficiente. En su lugar, crea una suscripción independiente para cada canalización.
Si especificas un tema, el conector crea una suscripción temporal nueva. Esta suscripción es única por canalización.
Marcas de tiempo y marcas de agua
Todos los mensajes de Pub/Sub tienen una timestamp, que representa la hora en que Pub/Sub recibe el mensaje. Tus datos también pueden tener una marca de tiempo de evento, que es la hora en la que la fuente generó el registro.
Puedes configurar el conector para que lea la marca de tiempo del evento de un atributo en el mensaje de Pub/Sub. En ese caso, el conector usa la marca de tiempo del evento para la marca de agua. De lo contrario, de forma predeterminada, usa la marca de tiempo del mensaje de Pub/Sub.
Para obtener más información sobre el uso de marcas de tiempo de eventos, consulta los siguientes temas de referencia del SDK:
withTimestampAttribute
(Java)ReadFromPubSub
(Python)ReadOptions
(Go)
El conector de Pub/Sub tiene acceso a la API privada de Pub/Sub que proporciona la antigüedad del mensaje no confirmado más antiguo de una suscripción. Esta API proporciona una latencia menor que la disponible en Cloud Monitoring. Permite que Dataflow avance las marcas de agua de la canalización y emita resultados de procesamiento con ventanas con latencias bajas.
Si configuras el conector para usar marcas de tiempo de eventos, Dataflow crea una segunda suscripción a Pub/Sub. Usa esta suscripción para inspeccionar los tiempos de los eventos de los mensajes que aún están en las tareas pendientes. Este enfoque permite que Dataflow calcule con precisión las tareas pendientes de tiempo del evento. Para obtener más información, consulta la página de Stack Overflow que trata sobre cómo calcula Dataflow las marcas de agua de Pub/Sub.
Búsqueda de Pub/Sub
Con la búsqueda de Pub/Sub, los usuarios pueden volver a reproducir mensajes ya confirmados. Puedes usar Pub/Sub Seek con Dataflow para volver a procesar los mensajes en una canalización.
Sin embargo, no se recomienda usar Pub/Sub Seek en una canalización en ejecución. Buscar hacia atrás en una canalización en ejecución puede hacer que los mensajes o los mensajes duplicados se descarten. También invalida la lógica de la marca de agua de Dataflow y entra en conflicto con el estado de una canalización que incorpora datos procesados.
Para volver a procesar mensajes con Pub/Sub Seek, se recomienda el siguiente flujo de trabajo:
- Crea una instantánea de la suscripción:
- Crea una suscripción para el tema de Pub/Sub La suscripción nueva hereda la instantánea.
- Desvía o cancela el trabajo actual de Dataflow.
- Vuelve a enviar la canalización con la suscripción nueva.
Para obtener más información, consulta Reprocesamiento de mensajes con la instantánea de Pub/Sub y la búsqueda de Pub/Sub.
Características de Pub/Sub no compatibles
Las siguientes funciones de Pub/Sub no son compatibles con la implementación del ejecutor de Dataflow del conector de E/S de Pub/Sub.
Retirada exponencial
Cuando creas una suscripción de Pub/Sub, puedes configurarla para usar una política de reintentos de retirada exponencial. Sin embargo, la retirada exponencial no funciona con Dataflow.
La retirada exponencial se activa mediante una confirmación negativa o cuando vence el plazo de confirmación. Sin embargo, Dataflow no envía confirmaciones negativas cuando falla el código de canalización. En su lugar, vuelve a intentar el procesamiento del mensaje de forma indefinida, mientras extiende el plazo de confirmación para el mensaje de forma continua.
Temas de mensajes no entregados
No se recomienda usar temas de mensajes no entregados de Pub/Sub con Dataflow por los siguientes motivos:
Dataflow envía confirmaciones negativas por varios motivos internos (por ejemplo, si un trabajador se apaga). Como resultado, los mensajes se pueden entregar al tema de mensajes no entregados, incluso cuando no se producen fallas en el código de la canalización.
Dataflow puede confirmar mensajes antes de que la canalización procese los datos por completo. En particular, Dataflow reconoce los mensajes después de que se procesaron de forma correcta en la primera etapa fusionada y los efectos secundarios de ese procesamiento se escribieron en el almacenamiento continuo. Si la canalización tiene varias etapas fusionadas y se producen fallas en cualquier momento después de la primera etapa, los mensajes ya se confirmaron y no van al tema de mensajes no entregados.
En su lugar, implementa el patrón de mensajes no entregados de forma explícita en la canalización. Algunos receptores de E/S tienen compatibilidad integrada con las colas de mensajes no entregados. En los siguientes ejemplos, se implementan patrones de mensajes no entregados:
Entrega de Pub/Sub “exactamente una vez”
Debido a que Dataflow tiene sus propios mecanismos de procesamiento “exactamente una vez”, no se recomienda usar la entrega de Pub/Sub “exactamente una vez” con Dataflow. Habilitar la entrega “exactamente una vez” de Pub/Sub reduce el rendimiento de la canalización, ya que limita la cantidad de mensajes disponibles para el procesamiento paralelo.
Pub/Sub: ordenamiento de mensajes
El orden de mensajes es una función de Pub/Sub que permite a un suscriptor recibir mensajes en el orden en que fueron publicados.
No se recomienda usar el orden de mensajes con Dataflow por los siguientes motivos:
- Es posible que el conector de E/S de Pub/Sub no conserve el orden de los mensajes.
- Apache Beam no define lineamientos estrictos con respecto al orden en el que se procesan los elementos. Por lo tanto, es posible que el orden no se conserve en las transformaciones descendentes.
- El uso del orden de mensajes de Pub/Sub con Dataflow puede aumentar la latencia y disminuir el rendimiento.
¿Qué sigue?
- Procesamiento de transmisión con Pub/Sub y Dataflow: Qwik Start (lab de autoaprendizaje)
- Transmite de Pub/Sub a BigQuery
- Transmite mensajes desde Pub/Sub con Dataflow
- Canalizaciones de transmisión
- “Exactamente una vez” en Dataflow
- After Lambda: Exactly-once processing in Dataflow (Después de lambda: Procesamiento de tipo “exactamente una vez” en Dataflow), parte 1 y parte 3: Sources and Sinks (Fuentes de datos y receptores) (blog)