Kafka-node: Key in KeyedMessage ignored when deciding partition

Created on 13 Apr 2017  路  9Comments  路  Source: SOHU-Co/kafka-node

From personal testing and looking at the code for baseProducer, it looks like the key in KeyedMessage is not used for determining the partition of each message.

Is this correct? If so, what is the purpose of this key if it is not for determining the partition of a message?

Thanks in advance!

Most helpful comment

Hi @michallevin,
you could achieve deterministic partition production per topic very very easily.
As @hyperlink said it should be up to the producer to deal with this.

Checkout this example to achieve a key-to-partition-determination:

getPartitionForKey(key, partitionCount = 0){

        if(typeof key !== "string"){
            return Promise.reject("key must be a valid string");
        }

        if(partitionCount === 0){
            partitionCount = this.partitionCount;
        }

        return Promise.resolve(murmur(key) % partitionCount);
    }

note that I am using const murmur = require("murmurhash").v3;

All 9 comments

Can anyone confirm this:

const payload = { topic: 'Test', messages: new KeyedMessage('key_in_message','message1'), key: 'key_in_payload' };

The key_in_payload is used to decide the partition, but this key is ignored afterwards and is not sent on as part of the message.
The key_in_message is ignored when deciding the partition, but IS sent on as part of the message to the Kafka topic.

So essentially both need to be used.

I could be wrong on this but I think of the key as metadata about the message. In the kafka world it's optional but it can be used for partitioning-- it's up the implementer of the partitioner.

Hi @michallevin,
you could achieve deterministic partition production per topic very very easily.
As @hyperlink said it should be up to the producer to deal with this.

Checkout this example to achieve a key-to-partition-determination:

getPartitionForKey(key, partitionCount = 0){

        if(typeof key !== "string"){
            return Promise.reject("key must be a valid string");
        }

        if(partitionCount === 0){
            partitionCount = this.partitionCount;
        }

        return Promise.resolve(murmur(key) % partitionCount);
    }

note that I am using const murmur = require("murmurhash").v3;

@hyperlink - I faced the same issue, on more analysis I found the key must be a string only but earlier I was using integer value as a key, in that case "hashCode" function was always returning the same hash and due to which Keyed partition was not working for me.

I have created a PR, in which a key can always be converted to string to get the hash code for a given value. please check that out here - https://github.com/SOHU-Co/kafka-node/pull/870

My testing revealed that the key in keyedMessage is not used.
I had to set the key and partitioner in payload.
However we just discovered that it doesn't appear to be keying the same as murmur2 with partitioner 3.

Partitioner 0 (default) and partitioner 3 (keyed) are not partitioning the same as Kafka Java.

I am having the same problem. So should we set the key even in the payload and not only in the keyedMessage ?

That worked for us.

for use as well!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

quorak picture quorak  路  5Comments

harshitgupta30 picture harshitgupta30  路  4Comments

ghinks picture ghinks  路  6Comments

aamitsharma2705 picture aamitsharma2705  路  4Comments

Sonivaibhav26 picture Sonivaibhav26  路  5Comments