Apache kafka Apache Kafka默认编码器不工作

Apache kafka Apache Kafka默认编码器不工作,apache-kafka,Apache Kafka,我使用的是Kafka 0.8 beta,我只是在尝试发送不同的对象,使用我自己的编码器序列化它们,然后将它们发送到现有的代理配置。现在我正努力让它工作起来 我已经为StringEncoder设置了代理和所有内容,但我无法获得代理发送和接收的任何其他数据类型,包括纯字节[] 我的制作人代码是: import kafka.javaapi.producer.Producer; import kafka.producer.KeyedMessage; import kafka.producer.Produ

我使用的是Kafka 0.8 beta,我只是在尝试发送不同的对象,使用我自己的编码器序列化它们,然后将它们发送到现有的代理配置。现在我正努力让它工作起来

我已经为StringEncoder设置了代理和所有内容,但我无法获得代理发送和接收的任何其他数据类型,包括纯字节[]

我的制作人代码是:

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;

import java.util.Date;
import java.util.Properties;
import java.util.Random;


public class ProducerTest {
    public static void main(String[] args) {
        long events = 5;
        Random rnd = new Random();
        rnd.setSeed(new Date().getTime());
        Properties props = new Properties();
        props.setProperty("metadata.broker.list", "localhost:9093,localhost:9094");
        props.setProperty("serializer.class", "kafka.serializer.DefaultEncoder");
        props.setProperty("partitioner.class", "example.producer.SimplePartitioner");
        props.setProperty("request.required.acks", "1");
        props.setProperty("producer.type", "async");
        props.setProperty("batch.num.messages", "4");

        ProducerConfig config = new ProducerConfig(props);
        Producer<byte[], byte[]> producer = new Producer<byte[], byte[]>(config);
        for (long nEvents = 0; nEvents < events; nEvents++) {
            byte[] a = "Hello".getBytes();
            byte[] b = "There".getBytes();

            KeyedMessage<byte[], byte[]> data = new KeyedMessage<byte[], byte[]>("page_visits", a, b);
            producer.send(data);
        }
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        producer.close();
    }
}
导入kafka.javaapi.producer.producer;
导入kafka.producer.KeyedMessage;
导入kafka.producer.ProducerConfig;
导入java.util.Date;
导入java.util.Properties;
导入java.util.Random;
公共类产品测试{
公共静态void main(字符串[]args){
长事件=5;
随机rnd=新随机();
rnd.setSeed(new Date().getTime());
Properties props=新属性();
setProperty(“metadata.broker.list”,“localhost:9093,localhost:9094”);
setProperty(“serializer.class”、“kafka.serializer.DefaultEncoder”);
setProperty(“partitioner.class”、“example.producer.SimplePartitioner”);
props.setProperty(“request.required.acks”、“1”);
props.setProperty(“producer.type”、“async”);
props.setProperty(“batch.num.messages”,“4”);
ProducerConfig config=新的ProducerConfig(道具);
生产者生产者=新生产者(配置);
for(long-nEvents=0;nEvents
我使用了与示例中相同的SimplePartitioner,用字符串替换所有字节数组,并将序列化程序更改为kafka.serializer.StringEncoder,效果非常好

作为参考,SimplePartitioner:

import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties;

public class SimplePartitioner implements Partitioner<String> {
    public SimplePartitioner (VerifiableProperties props) {

    }

    public int partition(String key, int a_numPartitions) {
        int partition = 0;
        int offset = key.lastIndexOf('.');
        if (offset > 0) {
           partition = Integer.parseInt( key.substring(offset+1)) % a_numPartitions;
        }
       return partition;
  }

}
导入kafka.producer.Partitioner;
导入kafka.utils.VerifiableProperties;
公共类SimplePartitioner实现了分区器{
公共SimplePartitioner(可验证属性道具){
}
公共整数分区(字符串键、整数分区){
int分区=0;
int offset=key.lastIndexOf('.');
如果(偏移量>0){
partition=Integer.parseInt(key.substring(offset+1))%a\u numPartitions;
}
返回分区;
}
}

我做错了什么?

答案是分区类
SimplePartitioner
仅适用于字符串。当我尝试异步运行Producer时,它会创建一个单独的线程,在发送到代理之前处理编码和分区。当该线程意识到SimplePartitioner仅适用于字符串时,它遇到了一个障碍,但由于它是一个单独的线程,因此不会抛出异常,因此该线程只是在没有任何错误迹象的情况下退出

如果我们将SimplePartitioner更改为接受字节[],例如:

import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties;

public class SimplePartitioner implements Partitioner<byte[]> {
    public SimplePartitioner (VerifiableProperties props) {

    }

    public int partition(byte[] key, int a_numPartitions) {
        int partition = 0;
        return partition;
    }

}
导入kafka.producer.Partitioner;
导入kafka.utils.VerifiableProperties;
公共类SimplePartitioner实现了分区器{
公共SimplePartitioner(可验证属性道具){
}
公共整数分区(字节[]键,整数分区){
int分区=0;
返回分区;
}
}

这现在可以很好地工作。

对于partitioner.class属性,您可能应该坚持使用kafka.producer.DefaultPartitioner的默认值,而不是硬编码partitioner的特定返回值。这是一种试驾。但是,这里有一个默认分区器不起作用的场景:假设您希望消息的特定子序列严格按照它们产生的顺序使用。如果使用默认的分区器,这将非常失败,因为默认的分区器只使用密钥的散列,这是不可预测的。相反,如果您编写自己的自定义分区器,并且有某种方法来检测子序列,那么我们可以将它们分配给同一个分区。我的应用程序中出现了这个确切的用例。