Te recomendamos que revises esta respuesta en un entorno controlado antes de pasarlo a producción, un saludo.
Solución:
Las claves son en su mayoría útiles/necesarias si necesita un orden fuerte para un key y están desarrollando algo así como una máquina de estado. Si requieres que los mensajes con el mismo key (por ejemplo, una identificación única) siempre se ven en el orden correcto, adjuntando un key a los mensajes asegurará mensajes con el mismo key ir siempre a la misma partición en un tema. Kafka garantiza el orden dentro de una partición, pero no entre particiones en un tema, por lo que alternativamente no proporciona un key – que dará como resultado una distribución por turnos entre particiones – no mantendrá dicho orden.
En el caso de una máquina de estados, keys se puede usar con registro.limpiador.habilitar para deduplicar entradas con el mismo key. En ese caso, Kafka asume que su aplicación solo se preocupa por la instancia más reciente de un determinado key y el limpiador de registros elimina los duplicados anteriores de un determinado key solo si el key no es null. Esta forma de compactación de troncos está controlada por el log.cleaner.delete.retención propiedad y requiere keys.
Alternativamente, la propiedad más común registro.retención.horas, que está habilitado de forma predeterminada, funciona eliminando segmentos completos del registro que están desactualizados. En este caso keys no tiene que ser proporcionado. Kafka simplemente eliminará fragmentos del registro que sean más antiguos que el período de retención dado.
Eso es todo para decir, si ha habilitado la compactación de registros o requiere un orden estricto para los mensajes con el mismo key entonces definitivamente deberías estar usando keys. De lo contrario, null keys puede proporcionar una mejor distribución y evitar posibles problemas de puntos calientes en los casos en que algunos keys puede aparecer más que otros.
tl; dr
No, un key no se requiere como parte del envío de mensajes a Kafka. Pero…
Además de la respuesta aceptada muy útil, me gustaría agregar algunos detalles más
Fraccionamiento
De forma predeterminada, Kafka utiliza el key del mensaje para seleccionar la partición del tema en el que escribe. Esto se hace en el DefaultPartitioner
por
kafka.common.utils.Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
Si no hay key proporcionado, entonces Kafka dividirá los datos de forma rotativa.
En Kafka, es posible crear su propio particionador extendiendo el Partitioner
clase. Para esto, necesita anular el partition
método que tiene la firma:
int partition(String topic,
Object key,
byte[] keyBytes,
Object value,
byte[] valueBytes,
Cluster cluster)
Por lo general, el key de un mensaje de Kafka se utiliza para seleccionar la partición y el valor de retorno (de tipo int
) es el número de partición. Sin un keydebe confiar en el valor, que puede ser mucho más complejo de procesar.
ordenar
Como se indica en la respuesta dada, Kafka tiene garantías sobre el orden de los mensajes solo a nivel de partición.
Supongamos que desea almacenar transacciones financieras para sus clientes en un tema de Kafka con dos particiones. Los mensajes podrían verse como (key:valor)
null:"customerId": 1, "changeInBankAccount": +200
null:"customerId": 2, "changeInBankAccount": +100
null:"customerId": 1, "changeInBankAccount": +200
null:"customerId": 1, "changeInBankAccount": -1337
null:"customerId": 1, "changeInBankAccount": +200
Como no tenemos definido un key presumiblemente, las dos particiones se verán como
// partition 0
null:"customerId": 1, "changeInBankAccount": +200
null:"customerId": 1, "changeInBankAccount": +200
null:"customerId": 1, "changeInBankAccount": +200
// partition 1
null:"customerId": 2, "changeInBankAccount": +100
null:"customerId": 1, "changeInBankAccount": -1337
Su consumidor leyendo ese tema podría terminar diciéndole que el saldo en la cuenta es de 600 en un momento determinado, ¡aunque ese nunca fue el caso! Solo porque estaba leyendo todos los mensajes en la partición 0 antes de los mensajes en la partición 1.
con sentido key (como ID de cliente) esto podría evitarse ya que la partición sería así:
// partition 0
1:"customerId": 1, "changeInBankAccount": +200
1:"customerId": 1, "changeInBankAccount": +200
1:"customerId": 1, "changeInBankAccount": -1337
1:"customerId": 1, "changeInBankAccount": +200
// partition 1
2:"customerId": 2, "changeInBankAccount": +100
Compactación de troncos
Sin un key como parte de sus mensajes, no podrá establecer la configuración del tema cleanup.policy
para compacted
. Según la documentación, “la compactación de registros garantiza que Kafka siempre retendrá al menos el último valor conocido para cada mensaje key dentro del registro de datos para una sola partición de tema”.
Esta agradable y útil configuración no estará disponible sin ningún key.
Uso de claves
En casos de uso de la vida real, el key de un mensaje de Kafka puede tener una gran influencia en el rendimiento y la claridad de la lógica empresarial.
UN key puede, por ejemplo, usarse de forma natural para particionar sus datos. Como puede controlar a sus consumidores para que lean desde particiones particulares, esto podría servir como un filtro eficiente. También el key puede incluir algunos metadatos sobre el valor real del mensaje que le ayudan a controlar el procesamiento posterior. Las claves suelen ser más pequeñas que los valores y, por lo tanto, es más conveniente analizar un key en lugar del valor total. Al mismo tiempo, puede aplicar todas las serializaciones y el registro de esquema como se hizo con su valor también con el key.
Como nota, también existe el concepto de Encabezamiento que se puede utilizar para almacenar información, consulte la documentación.
valoraciones y reseñas
Si te ha sido útil este artículo, nos gustaría que lo compartas con más juniors y nos ayudes a dar difusión a este contenido.