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 a 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”, 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 provocar que un mensaje se entregue más de una vez. Por ejemplo, la reenvío puede ocurrir si el suscriptor confirma después de la fecha límite o si se pierde la confirmación debido a problemas transitorios de red.
Si ejecutas tu canalización de Dataflow con el modo de transmisión exactamente una vez, Dataflow anula la duplicación de los 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 algunos mensajes pueden procesarse dos veces. Para obtener más información, consulta Elige qué modo de transmisión usar.
Cómo anular la duplicación por atributo de mensaje
De forma predeterminada, Dataflow anula los duplicados en función del ID de mensaje. Sin embargo, una aplicación puede enviar el mismo registro dos veces como dos mensajes de Pub/Sub distintos. Por ejemplo, los datos de la fuente original pueden contener registros duplicados, o la aplicación puede publicar incorrectamente el mismo mensaje dos veces. Esto último puede suceder debido a reintentos, si se descartó el acuse de recibo debido a problemas de red o a otras interrupciones. En estas situaciones, los mensajes duplicados tienen diferentes IDs de mensaje.
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 la duplicación de los mensajes 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 manera coherente durante las reintentos, Dataflow puede detectar los duplicados. Para anular la duplicación, los mensajes deben publicarse en Pub/Sub en un plazo de 10 minutos entre sí.
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 para 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 forma no determinista, lo que podría causar mensajes duplicados, un retraso en la 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 creará 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 marca de tiempo, que representa el momento en que Pub/Sub recibe el mensaje. Es posible que tus datos también tengan una marca de tiempo de 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 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 más baja que la disponible en Cloud Monitoring. Permite que Dataflow avance las marcas de agua de la canalización y emita resultados de procesamiento en 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 la lista de tareas pendientes. Este enfoque permite que Dataflow estime el retraso del tiempo de evento con precisión. Para obtener más información, consulta la página de StackOverflow 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. El salto hacia atrás en una canalización en ejecución puede generar mensajes duplicados o la eliminación de mensajes. 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.
- 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 reintento Retry immediately.
La retirada exponencial se activa con una confirmación de recepció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 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 se cierra un trabajador). 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 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 receptor de mensajes no entregados de forma explícita en la canalización. Algunos disipadores 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 en 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 descendentes.
- El uso del ordenamiento 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)