最近在学kafka,发现kakfa生产者的key.serializer.class属性居然没有IntegerSerializer可选。这对于经常把int作为键值的我来说,感到有点难以理解。于是,在网上找了些资料,实现了整型做key的自定义序列化类。
1、开发环境
broker:三个,操作系统为Redhat 6.4 64位操作系统
producer:win10 64位,开发语言java
kafka版本:0.8.2
2、方法一(使用kafka.javaapi.producer.Producer)
在生产者客户端中,基于kafka.java.api.producer.Producer类来实现消息的发送,在生产者属性中,配置key.serializer.class属性为自定义的序列化类。这里需要强调的是,指定的序列化类必须带上包名。开始以为都在同一个包下就只写了类名,结果调试时报找不到类。
自定义消息键序列化/反序列化类的代码如下所示,这是根据网上代码修改的,也是实现了Encoder和Decoder两个接口类。这里,带参数的构造函数必须有,否则报错,接口只需要实现toMessage和toEvent即可。至于序列化方法,这里只是示意,没考虑效率。如要使用用该类序列化的消息,消费者需要指定消息key解码器,定义该类的实例即可。
import kafka.message.Message;
import kafka.serializer.Decoder;
import kafka.serializer.Encoder;
import kafka.utils.VerifiableProperties;
public class IntegerSerializer implements Encoder<Integer>, Decoder<Integer> {
public IntegerSerializer(VerifiableProperties prop) {
}
public Message toMessage(Integer eventDetails) {
byte[] serialized = eventDetails.toString().getBytes();
return new Message(serialized);
}
public Integer toEvent(Message message) {
// new Integer();
int v = Integer.parseInt(message.payload().array().toString());
return new Integer(v);
}
public byte[] toBytes(Integer arg0) {
// TODO Auto-generated method stub
return null;
}
public Integer fromBytes(byte[] arg0) {
// TODO Auto-generated method stub
return null;
}
}
3、方法二(使用KafkaProducer类)
kafka0.8.2中,提供了一个易用的生产者类KafkaProducer。在试用时,发现配置的属性与方法一不太一样:指定key和消息的序列化类时,分别使用key.serializer和value.serializer,而方法一中,后面还有.class。当我将key.serializer属性设置为方法一的自定义序列化类时,运行报错,调试后发现该属性应该配置为 kafka.common.serialization.Serializer接口的实现类。
代码如下所示,序列化方法也只是简单示意,实际使用时可采用高效的方法。另外,反序列化方法实现了Deserializer接口,但在消费者中,使用createMessageStreams函数获取消息流列表时,貌似只能设置Decoder接口的实现类。暂时没找到解决办法,因此我只能用方法一中的类来做解码器了,希望后续能找到合适的方法。
import java.util.Map;
import org.apache.kafka.common.serialization.Deserializer;
import org.apache.kafka.common.serialization.Serializer;
public class IntegerSerializer implements Serializer<Integer>, Deserializer<Integer> {
public void configure(Map<String, ?> configs, boolean isKey) {
}
public byte[] serialize(String topic, Integer data) {
return data.toString().getBytes();
}
public Integer deserialize(String topic, byte[] data) {
int v = Integer.parseInt(data.toString());
return new Integer(v);
}
public void close() {
// nothing to do
}
}
4、问题
1、kafka不同版本,变化相对来说还是有点大。貌似0.9.0以上不错,0.8.2只提供了KafkaProducer类,没有KafkaConsumer类,0.9好像就有了。用后面这俩类开发简单
2、kafka simple api还挺麻烦,一般使用high api就够了
3、诸多属性如何设置,在有实际项目前,暂时没动力去测试了
4、kafka技术原理还没来得及看,找时间看看