Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Con el commit manual de offsets, el número que confirmas indica desde qué punto retomará el grupo de consumidores tras una caída. Por eso el momento del commit decide qué trabajo puede repetirse y qué trabajo puede perderse. La regla práctica es confirmar cuando el procesamiento que quieres dar por hecho ya esté terminado, y aceptar que Kafka, por sí solo, no garantiza que cada efecto ocurra exactamente una vez.

Qué significa confirmar un offset

Cada registro de una partición tiene un offset, es decir, su posición dentro de esa partición. Al confirmar (hacer commit) un offset, el consumidor le indica a Kafka hasta dónde ha avanzado su grupo. Si el consumidor se reinicia, o si otro miembro del grupo toma esa partición, la lectura continúa desde el offset confirmado.

Leer un registro y confirmar su offset son dos acciones separadas. Esa separación es el origen de todo lo que sigue: el commit no describe lo que el consumidor leyó, sino lo que la aplicación declara terminado.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Dos caídas, dos resultados opuestos

Si el commit ocurre en un momento inadecuado, una caída produce uno de estos dos efectos:

  • Confirmas antes de terminar el trabajo. Si el proceso cae después, al reanudar el grupo parte de un offset posterior y el trabajo pendiente se omite.
  • Terminas el trabajo y confirmas después. Si el proceso cae antes del commit, al reanudar el registro vuelve a llegar y se procesa de nuevo.

Ninguno de los dos casos es un fallo de Kafka; son consecuencias de la posición que elegiste. El commit manual permite escoger qué riesgo aceptas según la semántica de tu aplicación. Sin embargo, no elimina los duplicados por sí solo ni coordina automáticamente una base de datos externa.

Cómo desactivar el commit automático

En la documentación de configuración de Apache Kafka 2.6, enable.auto.commit tiene por defecto el valor true, y auto.commit.interval.ms por defecto vale 5000 (5 segundos). Con el modo automático, el cliente confirma periódicamente en segundo plano, sin comprobar si tu código ha terminado el trabajo de esos registros. Si esa versión es la tuya, conviene revisar los valores de tu propia versión antes de dar por sentados estos defaults.

  1. Establece enable.auto.commit en false en las propiedades del consumidor. En Java: props.put("enable.auto.commit", "false");
  2. Confirma explícitamente con commitSync o commitAsync una vez completado el procesamiento.
  3. Comprueba que la propiedad llega al consumidor real. Un valor sobrescrito en otra capa de configuración, por ejemplo en un fichero de propiedades o en un framework que construya el cliente, anula la intención del cambio.

Qué offset confirmar

Al confirmar offsets explícitos, el valor representa el próximo mensaje que se consumirá, no el último procesado. Si el último registro procesado de una partición tiene offset 41, confirmas 42. Confirmar 41 haría que ese registro se vuelva a leer tras un reinicio.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Ejemplo en Java: procesar el lote y confirmar

El siguiente ejemplo, mínimo a propósito, usa la API de KafkaConsumer descrita en su Javadoc para la versión 4.2.0. Requiere Java 9 o posterior por el uso de List.of.

import java.time.Duration;
import java.util.*;
import org.apache.kafka.clients.consumer.*;
import org.apache.kafka.common.TopicPartition;

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "pedidos");
props.put("enable.auto.commit", "false");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(List.of("pedidos"));

try {
    while (true) {
        ConsumerRecords<String, String> registros = consumer.poll(Duration.ofMillis(500));
        Map<TopicPartition, OffsetAndMetadata> porConfirmar = new HashMap<>();
        for (ConsumerRecord<String, String> r : registros) {
            procesar(r); // trabajo que quieres dar por hecho
            porConfirmar.put(new TopicPartition(r.topic(), r.partition()),
                             new OffsetAndMetadata(r.offset() + 1));
        }
        if (!porConfirmar.isEmpty()) {
            consumer.commitSync(porConfirmar);
        }
    }
} finally {
    consumer.close();
}

Dentro de cada partición, los registros llegan en orden, así que la última asignación sobrescribe a las anteriores y queda el offset del registro más reciente más uno. El precio de esta ruta es claro: si el proceso cae a mitad del lote, los registros ya procesados de ese lote se repiten. Un lote más pequeño reduce esa repetición a costa de más commits.

commitSync o commitAsync

Ambos métodos confirman los mismos offsets; la diferencia está en cómo el flujo de tu código se entera del resultado.

Eje commitSync commitAsync
Espera Bloquea hasta que el commit termina, falla o expira el timeout. No bloquea el hilo de consumo.
Cómo se conoce el resultado Por el retorno o por una excepción, antes de continuar. Por el callback, si se proporciona. Sin callback, el error no se comunica.
Orden de envío Cada llamada espera a la anterior. Las llamadas sucesivas se envían en el orden en que se invocan, según el Javadoc de KafkaConsumer 4.2.0.
Encaje habitual Flujos donde la secuencia debe ser explícita y fácil de seguir. Flujos donde esperar en el hilo de consumo tiene un coste inaceptable.

Con commitAsync, que la llamada regrese no demuestra que el commit haya tenido éxito. El callback recibe el resultado y debe registrarlo. Reintentar un commit antiguo tras haber confirmado uno más reciente puede retrasar el punto de recuperación, así que el reintento necesita una decisión deliberada, no un bucle automático.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Rebalances y particiones que ya no son tuyas

Con subscribe y gestión automática del grupo, Kafka reparte las particiones entre los miembros. Un rebalance puede quitarle una partición a tu consumidor mientras procesa un lote. Desde ese momento, un offset de esa partición ya no se puede confirmar válidamente: el commit falla.

  • Rebalance durante el lote. Confirma primero el trabajo terminado en onPartitionsRevoked, implementado en un ConsumerRebalanceListener, antes de que la partición cambie de dueño.
  • Commit fallido por asignación inválida. commitSync puede lanzar una excepción. Captúrala, registra el error y decide si reprocesas los registros afectados.
  • Timeout de commitSync. El resultado queda incierto: el commit puede haberse aplicado o no. Asume que el registro podría repetirse y diseña el procesamiento para tolerarlo.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Lo que el commit no garantiza

Confirmar un offset es una escritura en Kafka; escribir en tu base de datos o en otro sistema es una segunda escritura. Si ambas no se coordinan, puede haber una ventana en la que una tenga efecto y la otra no. Hay dos caminos habituales: hacer el procesamiento idempotente, por ejemplo con una clave única por registro que impida insertar dos veces el mismo pedido, o guardar el offset en el mismo almacén externo dentro de una transacción, de modo que ambas escrituras se confirmen o se revierten juntas. Ninguno de los dos lo resuelve Kafka por sí mismo.

Versiones y alcance de esta guía

  • Configuración: los valores por defecto citados (enable.auto.commit=true y auto.commit.interval.ms=5000) corresponden a la documentación de Kafka 2.6. Verifica los de tu versión.
  • API Java: la descripción de commitSync, commitAsync y los offsets explícitos sigue el Javadoc de KafkaConsumer 4.2.0.
  • Otros lenguajes: Python, Go, .NET y otros clientes tienen nombres de métodos y garantías propias que no se transfieren desde Java. Consulta la documentación de cada cliente.
  • Procesamiento transaccional: no se trata aquí el patrón completo de transacciones de Kafka.

Lista para decidir

  • Si el procesamiento es idempotente, puedes confirmar después de completarlo y aceptar que algunos registros se repitan.
  • Si un duplicado causa daño real, asegura la escritura externa con clave única o transacción antes de activar el commit manual.
  • Si el hilo de consumo no puede esperar, usa commitAsync con un callback que registre el resultado.
  • Si las particiones pueden cambiar de dueño, confirma en onPartitionsRevoked y trata las excepciones de commit.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.