【发布时间】:2015-02-07 00:42:17
【问题描述】:
我正在为如何正确使用分区键机制而苦恼。我的逻辑是设置分区号为3,然后创建三个分区键为“0”、“1”、“2”,然后使用分区键创建三个KeyedMessage如
- KeyedMessage(主题,“0”,消息)
- KeyedMessage(主题,“1”,消息)
- KeyedMessage(主题,“2”,消息)
在此之后,创建一个生产者实例以发送所有 KeyedMessage。
我希望每个 KeyedMessage 应该根据不同的分区键进入不同的分区,这意味着
- KeyedMessage(topic, "0", message) 转到分区 0
- KeyedMessage(topic, "1", message) 转到分区 1
- KeyedMessage(topic, "2", message) 转到分区 2
我正在使用 Kafka-web-console 来查看主题状态,但结果与我期望的不一样。 KeyedMessage 仍然会随机进入分区,有时两个 KeyedMessage 会进入同一个分区,即使它们有不同的分区键。
为了让我的问题更清楚,我想发布一些我目前拥有的 Scala 代码,我正在使用 Kafka 0.8.2-beta 和 Scala 2.10.4。
这里是生产者代码,我没有使用自定义partitioner.class:
val props = new Properties()
val codec = if(compress) DefaultCompressionCodec.codec else NoCompressionCodec.codec
props.put("compression.codec", codec.toString)
props.put("producer.type", if(synchronously) "sync" else "async")
props.put("metadata.broker.list", brokerList)
props.put("batch.num.messages", batchSize.toString)
props.put("message.send.max.retries", messageSendMaxRetries.toString)
props.put("request.required.acks",requestRequiredAcks.toString)
props.put("client.id",clientId.toString)
val producer = new Producer[AnyRef, AnyRef](new ProducerConfig(props))
def kafkaMesssage(message: Array[Byte], partition: Array[Byte]): KeyedMessage[AnyRef, AnyRef] = {
if (partition == null) {
new KeyedMessage(topic,message)
} else {
new KeyedMessage(topic,partition,message)
}
}
def send(message: String, partition: String = null): Unit = send(message.getBytes("UTF8"), if (partition == null) null else partition.getBytes("UTF8"))
def send(message: Array[Byte], partition: Array[Byte]): Unit = {
try {
producer.send(kafkaMesssage(message, partition))
} catch {
case e: Exception =>
e.printStackTrace
System.exit(1)
}
}
下面是我如何使用生产者,创建一个生产者实例,然后使用这个实例发送三个消息。目前我将分区键创建为整数,然后将其转换为字节数组:
val testMessage = UUID.randomUUID().toString
val testTopic = "sample1"
val groupId_1 = "testGroup"
print("starting sample broker testing")
val producer = new KafkaProducer(testTopic, "localhost:9092")
val numList = List(0,1,2);
for (a <- numList) {
// Create a partition key as Byte Array
var key = java.nio.ByteBuffer.allocate(4).putInt(a).array()
//Here I give a Array[Byte] key
//so the second "send" function of producer will be called
producer.send(testMessage.getBytes("UTF8"), key)
}
不确定我的逻辑是否不正确,或者我没有正确理解分区键机制。任何人都可以提供一些示例代码或解释会很棒!
【问题讨论】:
-
我想你正在使用
stealthly/scala-kafka库?它看起来像一个错误,你能在 github 上为此打开一个问题吗?我会尽量在本周末左右解决这个问题。 -
@serejja 是的,代码来自该存储库。我猜应该定义生产者链接这个“新生产者[String,String](someConfig)”,然后内部默认分区器应该可以工作。今天我将在 github 上打开这个问题。谢谢
标签: scala apache-kafka