Tema representativo de entrevista

Entrevista de Backend sobre Kafka: ¿Cuándo deben los Share Groups proporcionar semántica de colas?

BackendDifícil
Equipo editorial de Offer.ccPublicado Actualizado

Pregunta

Un servicio de procesamiento de órdenes requiere que varios consumidores reclamen trabajos independientes de un topic de Kafka con reconocimiento y reintentos por registro. Compara los Share Groups con los Consumer Groups, explica cuándo es seguro usar cada uno y describe cómo manejarías el ordenamiento, los duplicados y la migración.

Problema y alcance

Las notificaciones de órdenes, las transformaciones de imágenes y los cálculos de facturación suelen ser elementos de trabajo independientes. El equipo ya escribe eventos en Kafka, pero un Consumer Group tradicional asigna una partición a un solo miembro a la vez; agregar más workers que particiones no incrementa directamente el paralelismo. Diseña una forma para que múltiples consumidores cooperen en el trabajo, con reconocimiento por registro, reintentos e intentos de entrega observables, identificando al mismo tiempo los flujos de negocio que aún requieren ordenamiento por partición.

Esta pregunta utiliza el modelo de Share Group descrito en Apache Kafka KIP-932. El KIP describe un nuevo tipo de grupo para el consumo cooperativo en topics regulares; no hace que Kafka sea idéntico a RabbitMQ. Una respuesta sólida verifica la versión del broker desplegada, el soporte del cliente y la disponibilidad de la API antes de recomendar su uso en producción.

Qué evalúa el entrevistador

  • ¿Puedes contrastar la asignación exclusiva de particiones con la adquisición cooperativa de registros?
  • ¿Puedes mapear acknowledge, release, reject y la expiración de bloqueos a estados de procesamiento?
  • ¿Sabes que un Share Group puede tener más consumidores que particiones sin preservar la intuición habitual de orden por clave?
  • ¿Los reintentos, poison records, límites de tiempo de procesamiento y límites de concurrencia encajan en un único modelo de fallos en tu respuesta?
  • ¿Verificas detalles de cliente, broker, ACL, monitoreo y rollback en lugar de limitarte a nombrar un KIP?

Una respuesta débil dice: “Kafka también puede ser una cola”. Una respuesta sólida nombra el beneficio similar a una cola, las garantías que cambian y los controles requeridos antes del despliegue.

Preguntas clarificadoras para hacer primero

  1. ¿Son los trabajos verdaderamente independientes? Si los eventos de una orden deben aplicarse en el orden de la clave, los Share Groups pueden ser la primitiva incorrecta.
  2. ¿El fallo es transitorio, recuperable manualmente o permanentemente inválido? Eso determina el comportamiento de release, reject y cuarentena.
  3. ¿Cuáles son el tiempo de procesamiento p99, la concurrencia máxima y los efectos secundarios duplicados tolerados? Estos definen el bloqueo de adquisición y el diseño de idempotencia.
  4. ¿El negocio requiere transacciones de Kafka de extremo a extremo? No asumas que un Share Group hereda el plan de transacciones del Consumer Group existente.
  5. ¿El topic todavía atiende a consumidores de difusión o repetición (replay)? Cambiar un grupo no debe alterar el contrato de lectura de otro grupo.

Respuesta de 30 segundos

“Primero confirmaría si los trabajos pueden completarse fuera de orden y si el Kafka y los clientes desplegados admiten KIP-932. Un Share Group permite que los miembros adquieran registros cooperativamente de un topic, permite que el número de miembros supere el número de particiones y admite reconocimiento, liberación y rechazo por registro. Un Consumer Group sigue siendo más adecuado para el ordenamiento local por partición y el razonamiento basado en offsets. Haría que cada efecto secundario sea idempotente, definiría las políticas de bloqueo y reintento según la latencia de procesamiento, monitorearía los estados de acquire, acknowledge, release, reject y timeout, y pondría en cuarentena los poison records. Si el ordenamiento, los límites de transacción o el soporte del cliente no están resueltos, mantendría un Consumer Group y validaría un topic de trabajo separado con una pequeña cohorte antes de migrar”.

Razonamiento paso a paso

1. Dibujar los dos modelos de asignación

Un Consumer Group normalmente asigna particiones a miembros; un miembro lee una partición dada dentro de ese grupo, por lo que el paralelismo está limitado por el número de particiones. Un Share Group permite que los miembros adquieran registros cooperativamente de los topics suscritos. Múltiples miembros pueden procesar diferentes registros de una partición y el número de miembros puede exceder el número de particiones. Eso es útil para trabajos independientes, pero no implica un ordenamiento global.

text
Consumer Group:  partition-0 -> worker-A
                 partition-1 -> worker-B
                 extra workers wait for another partition

Share Group:     partition-0 records -> worker-A, worker-B, worker-C
                 each acquired record is locked for one consumer

La razón para elegir un Share Group debe ser la adquisición elástica de trabajo y la finalización por registro, no simplemente que “hay muy pocas particiones”. Si los eventos de un cliente deben aplicarse en orden, mantén un Consumer Group o añade una máquina de estados serializada a nivel de aplicación.

2. Modelar el ciclo de vida del registro

KIP-932 describe un bloqueo de adquisición por tiempo limitado. Después de adquirir un registro, un consumidor puede confirmar el éxito (acknowledge), liberarlo para otra entrega (release), rechazarlo como no procesable (reject) o no hacer nada hasta que el bloqueo expire. El KIP describe un valor predeterminado de 30 segundos, pero el comportamiento en producción debe usar la configuración del broker desplegado; un valor predeterminado no es un SLA.

text
available -> acquired -> acknowledged
                    -> released -> available
                    -> rejected  -> terminal or quarantine
                    -> lock timeout -> available

El handler debe registrar una clave de idempotencia antes de un efecto secundario externo. De lo contrario, una caída del cliente o la expiración del bloqueo pueden cobrar, enviar o notificar dos veces. Una confirmación (acknowledge) indica que esta adquisición se completó; no puede revertir un efecto secundario ya confirmado por otro sistema.

3. Delimitar reintentos, poison records y concurrencia

El conteo de intentos de entrega ayuda a separar los fallos transitorios de los registros permanentemente inválidos. Aplica backoff y release ante un fallo de red. Aplica reject para errores deterministas de esquema o validación hacia un topic de cuarentena o una cola manual. No liberes (release) indefinidamente: un solo poison record puede consumir bloqueos y capacidad posterior de forma indefinida.

Establece el bloqueo por encima del tiempo de procesamiento p99 normal con un margen de jitter explicable. Un tiempo demasiado corto provoca reentregas superpuestas; uno demasiado largo retrasa la recuperación. Además, limita los registros adquiridos por partición y coordina los semáforos de los workers, los pools de bases de datos y las cuotas de APIs externas. Monitorea en conjunto los bloqueos activos, los timeouts de bloqueo, la distribución de intentos, los rechazos y la latencia de finalización de extremo a extremo.

4. Reafirmar las garantías de orden y duplicados

Las explicaciones de Kafka a menudo transforman “ordenado dentro de una partición” en “el procesamiento de negocio está ordenado”. Los miembros de un Share Group pueden adquirir registros de forma concurrente, por lo que el orden de finalización para una clave puede diferir del orden de escritura; la liberación y la reentrega amplifican la diferencia. Si el orden importa, codifica serialización a nivel de clave, comprobaciones de versión o una máquina de estados en la aplicación. No respondas únicamente con “Kafka está ordenado”.

El procesamiento Exactly-once tampoco surge automáticamente del tipo de grupo. Traza los límites entre la adquisición de registros, las escrituras de negocio y el reconocimiento. Una base de datos externa o un servicio de pagos aún requiere claves de idempotencia, una restricción de deduplicación o un outbox transaccional. Si una combinación no está soportada, declara que el diseño es at-least-once con idempotencia en lugar de llamarlo exactly-once.

5. Planificar la migración y el rollback

Verifica la versión del broker, la API del cliente, la configuración del grupo, las ACL, las métricas y los comandos operativos. Luego, realiza pruebas de carga en un topic separado o con una carga de trabajo pequeña. Inyecta fallos: caídas tras la adquisición, procesamiento que supere el bloqueo, rechazos repetidos, reinicio del broker y movimiento del coordinator. Registra la clave de negocio, el intento, el estado y las marcas de tiempo para cada registro.

Si los consumidores antiguos dependen del orden o de transacciones, no cambies el mismo grupo in situ. Copia el trabajo a un topic dedicado y permite que un nuevo grupo asuma el tráfico gradualmente; mantén la ruta antigua reproducible (replayable) hasta que la tasa de errores, los efectos secundarios duplicados y la latencia cumplan los criterios de control. El rollback detiene las nuevas adquisiciones y deja la ruta antigua para consumir los registros no migrados. Dos rutas activas no deben ejecutar el mismo efecto secundario sin un límite de deduplicación explícito.

Ejemplo de respuesta de alta calidad

“Comenzaría preguntando si los trabajos pueden completarse fuera de orden, si el procesamiento es idempotente y si el broker y el cliente desplegados admiten KIP-932. Un Share Group trata los registros independientes de un topic como trabajo cooperativo: múltiples miembros pueden adquirir diferentes registros de una partición, el número de miembros puede superar el número de particiones y cada registro tiene rutas de acknowledge, release, reject y expiración de bloqueo. Cambia la intuición de asignación y ordenamiento de un grupo tradicional, por lo que mantendría un Consumer Group o agregaría comprobaciones de versión cuando una clave de negocio requiera orden.

Asignaría una clave de idempotencia a cada registro, establecería el bloqueo de adquisición a partir del tiempo de procesamiento p99 y limitaría los bloqueos activos y la concurrencia downstream. Los fallos transitorios se liberan (release) con backoff; los datos erróneos deterministas se rechazan (reject) a cuarentena; un umbral de intentos detiene el reintento automático. Monitorearía acquire, acknowledge, release, reject, timeouts, efectos secundarios duplicados y latencia de finalización. Antes de la migración verificaría versiones, ACL, comportamiento del cliente y fallos inyectados en un topic separado. A menos que la adquisición de registros, las escrituras de negocio y el reconocimiento compartan un límite de transacción comprobado, calificaría el diseño como at-least-once con idempotencia, no como exactly-once”.

Errores comunes

  • Llamar a un Share Group un clon de RabbitMQ → el almacenamiento, la repetición (replay) y la administración difieren → promete únicamente las semánticas de adquisición cooperativa y reconocimiento documentadas en KIP-932.
  • Limitar los workers al número de particiones → los Share Groups permiten que múltiples miembros procesen una partición → limita la concurrencia mediante bloqueos, capacidad posterior y latencia de extremo a extremo.
  • Asumir que el orden por clave permanece intacto → la adquisición concurrente y la reentrega cambian el orden de finalización → serializa claves o comprueba versiones cuando el orden sea un requisito.
  • Reconocer (acknowledge) sin idempotencia → una caída o expiración de bloqueo puede reentregar el registro → deduplica por clave de negocio antes del reconocimiento.
  • Liberar (release) poison records indefinidamente → los reintentos agotan los bloqueos y el presupuesto downstream → detén el reintento automático según el tipo de error, el conteo de intentos y la política de cuarentena.
  • Tratar 30 segundos como una garantía → la configuración del broker y la latencia de procesamiento difieren → prueba la configuración del bloqueo desplegado frente al p99.

Preguntas de seguimiento y respuestas

¿Qué pasa si los eventos de una orden deben estar estrictamente ordenados?

No cambies directamente a un Share Group. Mantén un Consumer Group particionado por ID de orden o utiliza una máquina de estados serializada a nivel de aplicación. Si la adquisición compartida es obligatoria, añade comprobaciones de versiones, validación de prerrequisitos y reordenamiento tras fallos, reconociendo la complejidad adicional.

¿Qué sucede si un consumidor se cuelga durante dos minutos tras la adquisición?

Configura un bloqueo ligeramente superior al p99 normal y activa alertas por timeout de bloqueo. Permite la reentrega tras la expiración, pero exige un manejo de negocio idempotente. Para tareas largas, divide el trabajo en pasos reanudables o utiliza un lease externo en lugar de extender el bloqueo indefinidamente.

¿Cómo manejas cinco fallos consecutivos de esquema?

Trátalos como errores deterministas: recházalos tras alcanzar un umbral y escribe el payload, la versión del esquema y el motivo en un topic de cuarentena. Después de corregir el consumidor, reprocesa bajo un procedimiento controlado. No permitas que el flujo de trabajo principal reintente indefinidamente.

El sistema actual depende de transacciones de Kafka. ¿Puede cambiar directamente?

Enumera los límites de lectura, procesamiento y escritura de la transacción, y luego verifica el soporte real de transacciones y clientes para Share Groups. Si un efecto secundario externo está fuera de la misma transacción, utiliza un outbox, clave de idempotencia y compensación. Mantén un Consumer Group cuando el soporte no esté comprobado.

¿Cómo demuestras que la migración no cobró dos veces a los clientes?

Registra cada ejecución bajo una clave de negocio única con una restricción de deduplicación. Inyecta caídas, expiración de bloqueos, reintentos y rollback, y luego compara los conteos de ejecución y reconocimiento. Incrementa el tráfico solo cuando los invariantes del conteo de efectos secundarios, latencia y tasa de errores se mantengan.

Fuentes públicas

Preguntas relacionadas