tutorial kafka español java apache-kafka kafka-producer-api

java - español - KafkaProducer: ¿Diferencia entre `callback` y retornado` Future`?



apache kafka tutorial español (4)

El enfoque asíncrono.

producer.send(record, new Callback(){ @Override onComplete(RecordMetadata rm, Exception ex){...} })

Te da un mejor rendimiento en comparación con síncrono

RecordMetadata rm = producer.send(record).get();

ya que no se esperan acuses de recibo en el primer caso.

Además, de forma asíncrona, el pedido no está garantizado, mientras que en forma síncrona, el mensaje se envía solo después de recibir el acuse de recibo.

Otra diferencia podría ser que en la llamada síncrona en caso de excepción, puede dejar de enviar mensajes inmediatamente después de que se produce la excepción , mientras que en el segundo caso, se enviarán algunos mensajes antes de descubrir que algo está mal y realizar algunas acciones.

También tenga en cuenta que en el enfoque asíncrono el número de mensajes que están "en vuelo" está controlado por el parámetro max.in.flight.requests.per.connection .

Además de los enfoques síncronos y asíncronos, puede usar el método de Disparar y olvidar , que es casi lo mismo que el síncrono, pero sin procesar los metadatos devueltos, solo envíe el mensaje y espere que llegue al intermediario (sabiendo que lo más probable es que suceda, y el productor volverá a intentarlo en caso de errores recuperables), pero existe la posibilidad de que algunos mensajes se pierdan:

RecordMetadata rm = producer.send(record);

Para resumir:

  • Dispara y olvida: el más rápido, pero algunos mensajes podrían perderse;
  • Sincrónico: más lento, úselo si no puede darse el lujo de perder mensajes;
  • Asíncrono - algo intermedio.

El método de envío de KafkaProducer devuelve un futuro y acepta una devolución de llamada.

¿Hay alguna diferencia fundamental entre usar un mecanismo sobre el otro para ejecutar una acción al completar el envío?


La principal diferencia es si desea bloquear el subproceso de llamada a la espera de la confirmación.

Lo siguiente utilizando el método Future.get() bloquearía el hilo actual hasta que se complete el envío antes de realizar alguna acción.

producer.send(record).get() // Do some action

Cuando se utiliza una devolución de llamada para realizar alguna acción, el código se ejecutará en el subproceso de E / S para que no se bloquee para el subproceso de llamada.

producer.send(record, new Callback() { // Do some action } });

Aunque la documentación dice que ''generalmente'' se ejecuta en el productor:

Tenga en cuenta que las devoluciones de llamada generalmente se ejecutarán en el subproceso de E / S del productor y, por lo tanto, deberían ser razonablemente rápidos o demorarán el envío de mensajes desde otros subprocesos. Si desea ejecutar bloqueos o devoluciones de llamada costosas computacionalmente, se recomienda utilizar su propio Ejecutor en el cuerpo de la devolución de llamada para paralelizar el procesamiento.


Mis observaciones basadas en la documentación de The Kafka Producer :

  • Future te da acceso al procesamiento síncrono.
  • Future podría no garantizar el reconocimiento. Mi entendimiento es que una Callback se ejecutará después del reconocimiento
  • Callback le da acceso a un procesamiento asíncrono completamente sin bloqueo .
    • También hay garantías en el orden de ejecución para una devolución de llamada en la misma partición

Se garantiza que las devoluciones de llamada para los registros que se envían a la misma partición se ejecutan en orden.

Mi otra opinión es que el objeto de retorno Future y el ''patrón'' de devolución de Callback representan dos estilos de programación diferentes y creo que esta es la diferencia fundamental:

  • El Future representa el estilo de modelo de concurrencia de Java.
  • La Callback representa el estilo de programación Lambda de Java (porque la Callback realmente cumple el requisito de una interfaz funcional)

Probablemente pueda terminar codificando comportamientos similares con los estilos Future y Callback , pero en algunos casos de uso parece que un estilo podría ser más ventajoso que el otro.


Ver la documentación a la que se vincula parece que la principal diferencia entre el futuro y la devolución de llamada radica en quién inicia la "solicitud finalizada, ¿y ahora qué?" pregunta.

Digamos que tenemos un cliente C y un panadero B Y C está pidiendo a B que le haga una buena galleta. Ahora hay 2 formas posibles en que el panadero puede devolver la deliciosa galleta al cliente.

Futuro

El panadero acepta la solicitud y le dice al cliente: Ok, cuando termine, colocaré su cookie aquí en el mostrador. (Este acuerdo es el Future .)

En este escenario, el cliente es responsable de verificar el contador ( Future ) para ver si el panadero ha terminado su cookie o no.

bloqueo El cliente se queda cerca del mostrador y lo mira hasta que la cookie se coloca allí (Future.get ()) o el panadero pone una disculpa en su lugar (Error: Fuera de la masa de la cookie).

Sin bloqueo El cliente realiza algún otro trabajo y, de vez en cuando, comprueba si la cookie lo está esperando en el mostrador (Future.isDone ()). Si la cookie está lista, el cliente la toma (Future.get ()).

Llamar de vuelta

En este caso, el cliente, después de ordenar su galleta, le dice al panadero: Cuando mi galleta esté lista, dásela a mi perro robot mascota aquí, él sabrá qué hacer con ella (este robot es el Callback).

Ahora el panadero, cuando la galleta está lista, le da la galleta al perro y le dice que vuelva a su dueño. El panadero puede continuar horneando la siguiente galleta para otro cliente.

El perro vuelve corriendo hacia el cliente y comienza a mover su cola artificial para avisar al cliente que su galleta está lista.

Observe cómo el cliente no tenía idea de cuándo se le entregaría la cookie, ni tampoco estaba encuestando activamente al panadero para ver si estaba lista.

Esa es la principal diferencia entre los 2 escenarios. ¿Quién es responsable de iniciar "su cookie está lista, qué desea hacer con ella?" pregunta. Con el futuro, el cliente es responsable de verificar cuándo está listo, ya sea esperando activamente o haciendo encuestas de vez en cuando. En el caso de la devolución de llamada, el panadero devolverá la llamada a la función proporcionada.

Espero que esta respuesta le brinde una mejor idea de lo que realmente son un Future y Calback. Una vez que tenga la idea general, podría intentar averiguar en qué hilo se maneja cada cosa específica. Cuando se bloquea un hilo, o en qué orden se completa todo. Escribir algunos programas simples que impriman declaraciones como: "hilo principal del cliente: cookie recibida" podría ser una forma divertida de experimentar con esto.