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 Cloudpara 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 los entrega de forma asíncrona a los suscriptores.
Pub/Sub asigna un ID de mensaje único a cada mensaje que se publica correctamente 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”, si Pub/Sub no recibe la confirmación de recepción del suscriptor dentro del plazo de confirmación, vuelve a intentar la entrega del mensaje. También es posible que se realicen reintentos antes de la fecha límite de confirmación o después de que se haya confirmado un mensaje.
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 persistente. Para reducir la cantidad de mensajes duplicados, Dataflow extiende continuamente el plazo de confirmación mientras se procesa un lote de mensajes en esta etapa.
Dado que Pub/Sub podría volver a entregar un mensaje, es posible que lleguen mensajes duplicados a la canalización. Si tu canalización de Dataflow usa el modo de transmisión exactamente una vez, Dataflow anula la duplicación de estos mensajes para lograr la semántica de 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 significativamente la latencia y el costo total de tu canalización. La desventaja es que los mensajes duplicados podrían procesarse dos veces. Para obtener más información, consulta Cómo elegir el modo de transmisión que se usará.
Anula la duplicación por atributo de mensaje
De forma predeterminada, Dataflow anula los duplicados según el ID del mensaje. Sin embargo, una aplicación podría enviar el mismo registro dos veces como dos mensajes de Pub/Sub distintos. Por ejemplo, los datos de origen originales pueden contener registros duplicados, o la aplicación puede publicar incorrectamente el mismo mensaje dos veces. Esto último puede ocurrir debido a reintentos, si se descartó la confirmación de recepción debido a problemas de red o a otras interrupciones. En estas situaciones, los mensajes duplicados tienen IDs diferentes.
Según tu situación, es posible que tus datos contengan un campo único que se pueda usar para quitar duplicados. Por ejemplo, los registros pueden contener un ID de transacción único. Puedes configurar el conector de E/S de Pub/Sub para anular la duplicación de mensajes según el valor de un atributo de mensaje, en lugar de usar el ID del mensaje de Pub/Sub. Siempre y cuando el editor configure este atributo de forma coherente durante los reintentos, Dataflow podrá detectar los duplicados. Los mensajes deben publicarse en Pub/Sub con un intervalo de 10 minutos entre sí para la anulación de 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 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 manera no determinística, lo que puede causar mensajes duplicados, retraso de marcas de agua y 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 para cada canalización.
Marcas de tiempo y marcas de agua
Todos los mensajes de Pub/Sub tienen una marca de tiempo, que representa el momento en que Pub/Sub recibe el mensaje. Tus datos también pueden tener una marca de tiempo del evento, que es la hora en que la fuente generó el registro.
Puedes configurar el conector para que lea la marca de tiempo del evento desde un atributo del 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, se 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 en una suscripción. Esta API proporciona una latencia más baja que la que está 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 que use marcas de tiempo de eventos, Dataflow creará una segunda suscripción de Pub/Sub, llamada suscripción de seguimiento. Dataflow usa la suscripción de seguimiento para inspeccionar los tiempos de los eventos de los mensajes que aún están en la lista de tareas pendientes. Este enfoque permite que Dataflow estime con precisión la acumulación de tareas pendientes de tiempo del evento. La cuenta de servicio del trabajador debe tener, al menos, los siguientes permisos en el proyecto que contiene la suscripción de seguimiento:
pubsub.subscriptions.create
pubsub.subscription.consume
pubsub.subscription.delete
Además, necesita el permiso pubsub.topics.attachSubscription
en el tema de Pub/Sub. Se recomienda crear un rol personalizado de Identity and Access Management que contenga solo estos permisos.
Para obtener más información sobre las marcas de agua, consulta la página de Stack Overflow que trata sobre cómo Dataflow calcula las marcas de agua de Pub/Sub.
Si una canalización tiene varias fuentes de Pub/Sub y una de ellas tiene un volumen muy bajo o está inactiva, se retrasa el avance de toda la marca de agua, lo que aumenta la latencia general de la canalización. Si hay temporizadores o agregaciones de ventanas en la canalización basados en la marca de agua, estos también se retrasan.
Pub/Sub Seek
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 mensajes en una canalización.
Sin embargo, no se recomienda usar Pub/Sub Seek en una canalización en ejecución. Si se busca hacia atrás en una canalización en ejecución, se pueden generar mensajes duplicados o descartados. También invalida la lógica de marcas 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.
- Vacía o cancela el trabajo de Dataflow actual.
- 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 a Pub/Sub, puedes configurarla para que use una política de reintentos de retirada exponencial. Sin embargo, la retirada exponencial no funciona con Dataflow. En su lugar, crea la suscripción con la política de reintentos Retry immediately.
La retirada exponencial se activa por una confirmación de recepción negativa o cuando vence el plazo de confirmación de recepción. Sin embargo, Dataflow no envía confirmaciones negativas cuando falla el código de la 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 uses 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 está apagando). Como resultado, es posible que los mensajes se entreguen al tema de mensajes no entregados incluso cuando no se produzcan fallas en el código de la canalización.
Dataflow reconoce los mensajes después de que la primera etapa fusionada procesa correctamente un paquete de mensajes. 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 se envían al tema de mensajes no entregados.
En su lugar, implementa el patrón de mensajes sin entregar de forma explícita en la canalización, ya que enruta los mensajes con errores a un destino para su procesamiento posterior. Algunos receptores de E/S tienen compatibilidad integrada con las filas de buzón de destino. 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 para el procesamiento “exactamente una vez”, no se recomienda usar la entrega “exactamente una vez” de Pub/Sub 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 los mensajes es una función de Pub/Sub que permite que un suscriptor reciba mensajes en el orden en que se publicaron.
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 posteriores.
- Usar el ordenamiento de mensajes de Pub/Sub con Dataflow puede aumentar la latencia y disminuir el rendimiento.
Transformaciones de mensaje único de Pub/Sub
Las transformaciones de mensajes individuales (SMT) te permiten manipular, validar y filtrar mensajes según sus atributos o datos a medida que se transmiten por el sistema. Las suscripciones que alimentan Dataflow no deben usar SMT que filtren mensajes, ya que pueden interferir con el ajuste de escala automático. Esto sucede porque el filtrado del SMT de suscripción puede hacer que la acumulación parezca más grande de lo que se entrega a Dataflow hasta que el SMT procese los mensajes filtrados. Los SMT de temas que filtran mensajes no causarán problemas con el ajuste de escala automático.
¿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)