Free tools Windows power users keep installed
One-click scans. No signup required.
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.
Dos caídas, dos resultados opuestos
Si el commit ocurre en un momento inadecuado, una caída produce uno de estos dos efectos:
#1 Best Overall
- 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.
- Establece
enable.auto.commitenfalseen las propiedades del consumidor. En Java:props.put("enable.auto.commit", "false"); - Confirma explícitamente con
commitSyncocommitAsyncuna vez completado el procesamiento. - 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.
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.
Rank #3
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.
Rank #4
| 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.
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.
Best Value
- Rebalance durante el lote. Confirma primero el trabajo terminado en
onPartitionsRevoked, implementado en unConsumerRebalanceListener, antes de que la partición cambie de dueño. - Commit fallido por asignación inválida.
commitSyncpuede 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.
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.
Quick Recap
Versiones y alcance de esta guía
- Configuración: los valores por defecto citados (
enable.auto.commit=trueyauto.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,commitAsyncy 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
commitAsynccon un callback que registre el resultado. - Si las particiones pueden cambiar de dueño, confirma en
onPartitionsRevokedy 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.

