Actualización_2024-11-13
- En el informe inicial se afirmaba que un consumidor con auto-commit habilitado podía provocar pérdida de datos al confirmar automáticamente el offset devuelto por el poll más reciente.
- Sin embargo, varios lectores refutaron esto señalando que un consumidor con auto-commit en realidad confirma el offset del poll anterior, no del más reciente.
- Los resultados de experimentos con el cliente Java de Kafka también respaldan esto, aunque el comportamiento puede variar según el cliente.
- Se eliminó del informe la afirmación específica sobre auto-commit, y hace falta investigación adicional.
Antecedentes
- Kafka es un sistema de streaming popular que ofrece replicación, sharding y logs append-only.
- Bufstream es una solución alternativa a Kafka que prioriza la gobernanza de datos y la eficiencia de costos en entornos de nube.
- Al igual que Kafka, Bufstream ofrece colecciones de logs parcialmente ordenados llamadas topics, y cada topic se divide en partitions.
- Bufstream es compatible con clientes estándar de Kafka y está compuesto por agentes, un servicio sin estado que expone la API de Kafka, un object store que almacena los datos, y un servicio de coordinación.
- Bufstream reduce costos escribiendo el almacenamiento de datos directamente en servicios de object storage, y puede operar sobre VM sin estado con autoescalado.
Seguridad del cliente
- Bufstream está diseñado para distintas aplicaciones de streaming y establece varias opciones de configuración del cliente para un funcionamiento seguro.
- Igual que Kafka, usa
acks = all por defecto y establece enable.auto.commit = false para evitar pérdida de datos.
- Usa
auto.offset.reset = earliest para que los consumidores puedan observar el log completo.
Transacciones
- Bufstream soporta el sistema de transacciones de Kafka y ofrece una forma débil de atomicidad mediante una configuración compleja.
- Los consumidores pueden ejecutarse con niveles de aislamiento
read_uncommitted o read_committed, y read_committed evita algunos fenómenos (G1a, G1c).
- En Kafka, Redpanda y Bufstream ocurre el fenómeno G0, lo que no coincide con los niveles de aislamiento documentados.
Diseño de pruebas
- Se probó desde Bufstream 0.1.0 hasta 0.1.3 usando la librería de pruebas de Jepsen y Java Kafka Client.
- Las pruebas evalúan la seguridad de Bufstream inyectando distintos tipos de fallas.
Cola
- Se diseñó una carga de trabajo de cola ajustada al modelo de datos de Kafka para usarla en Bufstream.
- Cada proceso lógico ejecuta clientes de productor, consumidor y administrador, y envía registros para distintas claves.
Abortos
- A partir de resultados inesperados, se diseñó una carga de trabajo que aborta transacciones y rastrea offsets.
- Los offsets posteriores a transacciones abortadas se clasificaron en cuatro categorías: avance, rebobinado, más rebobinado, y otros.
Resultados de Bufstream
Consumidor detenido (#1)
- Desde 0.1.0 hasta 0.1.3-rc.8 ocurrió un problema en el que las llamadas a
consumer.poll() devolvían inmediatamente sin retornar registros.
- Bufstream resolvió el problema en 0.1.3-rc.6 actualizando la caché.
Productor y consumidor detenidos (#2)
- Incluso en 0.1.3-rc.6 ocurrieron problemas en los que fallaba la llamada
InitProducerId o la llamada listOffsets.
- Bufstream resolvió el problema agregando lógica adicional de polling.
Offset 0 incorrecto (#3)
- Desde 0.1.0 hasta 0.1.3-rc.2 ocurrió un problema en el que se asignaba incorrectamente el offset 0.
- Bufstream resolvió este problema en 0.1.3-rc.6.
Pérdida de escrituras transaccionales (#4)
- En 0.1.2 ocurrió un problema en el que desaparecían registros de transacciones confirmadas.
- Bufstream resolvió el problema en 0.1.3-rc2.
Pérdida de escrituras por filtrado del lado del servidor (#5)
- En 0.1.3-rc.8 ocurrió pérdida de escrituras como respuesta a fallas menores.
- Bufstream resolvió el problema en 0.1.3-rc.12.
Resultados de Kafka
Mensaje de error engañoso (KIP-588)
- Existe un problema en el que
ProducerFencedException también ocurre con timeouts transaccionales.
- Se recomienda al equipo de Kafka cambiar el mensaje de error.
Posibilidad de espera infinita al cerrar el consumidor (KAFKA-17734)
- Existe un problema en el que la llamada
Consumer.close() puede quedarse esperando indefinidamente en network IO.
- El problema se rastrea mediante KAFKA-17734.
Offsets de consumidor impredecibles tras un fallo de transacción (KAFKA-17582)
- Falta documentación sobre el comportamiento esperado de los offsets del consumidor cuando falla una transacción.
- Después de una transacción abortada, el consumidor puede rebobinar su offset o seguir avanzando.
1 comentarios
Comentarios en Hacker News
Mientras investigaban problemas en Kafka, se descubrieron escrituras invisibles. Esto plantea la posibilidad de que mensajes
Produceretrasados queden incluidos en transacciones futuras y violen las garantías transaccionales. También existe la sospecha de que el cliente Java de Kafka podría reutilizar números de secuencia cuando una solicitud expira por timeout. Hacen falta más pruebas sobre KafkaAl ver la página del producto de Bufstream, surge la duda de cómo pueden ser compatibles estas dos afirmaciones
Sorprende la función de auto-commit de Kafka
El protocolo de transacciones de Kafka tiene problemas fundamentales y necesita corregirse
Me pregunto si Kyle ha revisado NATS Jetstream
No pude encontrar el proyecto de bufstream en GitHub. Me pregunto si alguien tiene alguna pista
Después de leer las publicaciones de blog y la documentación relacionadas, Kafka define "exactly-once delivery" como una propiedad de la operación de "leer-procesar-escribir". Parece que sería mejor describirlo como una transacción
La frase "las transacciones pueden observarse parcialmente o por completo" parece que debería leerse como "los consumidores pueden observarlas parcial o completamente"
Me pregunto para qué se usa este software. ¿Instrumentación? ¿Caja negra?