Apache kafka 为什么要在ApacheStorm中使用Kryo序列化框架来覆盖blot获取值时的数据

Apache kafka 为什么要在ApacheStorm中使用Kryo序列化框架来覆盖blot获取值时的数据,apache-kafka,apache-storm,kryo,bigdata,Apache Kafka,Apache Storm,Kryo,Bigdata,在卡夫卡和ApacheStorm方案中,可能主要开发的是使用AVRO作为序列化框架。但我需要处理最复杂的数据,然后我发现序列化框架也成功地将其集成到我们的项目中,该项目遵循Kafka和ApacheStorm环境。但当想要进一步操作时,却出现了一种奇怪的状态 我已经向卡夫卡发送了5次消息,Storm job也可以读取这5条消息并反序列化成功。但是下一个blot得到的数据值是错误的。打印出与上一条消息相同的值。然后在完成反序列化代码后添加打印输出。实际上它打印出来的是真的,有不同的5条信息。为什么下

在卡夫卡和ApacheStorm方案中,可能主要开发的是使用AVRO作为序列化框架。但我需要处理最复杂的数据,然后我发现序列化框架也成功地将其集成到我们的项目中,该项目遵循Kafka和ApacheStorm环境。但当想要进一步操作时,却出现了一种奇怪的状态

我已经向卡夫卡发送了5次消息,Storm job也可以读取这5条消息并反序列化成功。但是下一个blot得到的数据值是错误的。打印出与上一条消息相同的值。然后在完成反序列化代码后添加打印输出。实际上它打印出来的是真的,有不同的5条信息。为什么下一个污点不能改变这些值?请参见下面的我的代码:

KryoScheme.java

公共抽象类KryoScheme实现Scheme{
私有静态最终长serialVersionUID=6923985190833960706L;
私有静态最终记录器Logger=LoggerFactory.getLogger(KryoScheme.class);
私人课堂;
专用序列化程序;
公共KryoScheme(类clazz,序列化程序){
this.clazz=clazz;
this.serializer=序列化程序;
}
@凌驾
公共列表反序列化(字节[]缓冲区){
Kryo Kryo=新Kryo();
寄存器(clazz,序列化器);
T方案=null;
试一试{
scheme=kryo.readObject(新输入(新的ByteArrayInputStream(buffer)),this.clazz);
logger.info(“{}”,scheme);
}捕获(例外e){
String errMsg=String.format(“Kryo方案无法将数据从Kafka反序列化到%s。原始:%s”,
clazz.getName(),
新字符串(缓冲区));
记录器错误(errMsg,e);
抛出新的FailedException(errMsg,e);
}
返回新值(方案);
}}
PrintFunction.java

公共类PrintFunction扩展了BaseFunction{
私有静态最终记录器Logger=LoggerFactory.getLogger(PrintFunction.class);
@凌驾
public void execute(TridentTuple元组、TridentCollector收集器){
列表数据=tuple.getValues();
如果(数据!=null){
info(“方案数据大小:{}”,data.size());
用于(对象值:数据){
打印输出=(打印输出)值;
logger.info(“{}.{}--value:{}”,
Thread.currentThread().getName(),
Thread.currentThread().getId(),
out.toString());
emit(新值(out));
}
}
}}
StormLocalTopology.java

公共类StormLocalTopology{
公共静态void main(字符串[]args){
........
BrokerHosts zk=新的ZkHosts(“xxxxxx”);
Config stormConf=new Config();
stormConf.put(Config.TOPOLOGY_DEBUG,false);
stormConf.put(Config.TOPOLOGY\u TRIDENT\u BATCH\u EMIT\u INTERVAL\u MILLIS,1000*5);
stormConf.put(Config.TOPOLOGY\u WORKERS,1);
stormConf.put(Config.TOPOLOGY\u MESSAGE\u TIMEOUT\u SECS,5);
stormConf.put(Config.TOPOLOGY_TASKS,1);
TridentKafkanconfig ACTPAUTCONF=新的TridentKafkanconfig(zk,主题);
actSpoutConf.fetchSizeBytes=5*1024*1024;
actSpoutConf.bufferSizeBytes=5*1024*1024;
actSpoutConf.scheme=新方案多方案(方案);
actSpoutConf.startOffsetTime=kafka.api.OffsetRequest.LatestTime();
TridentTopology=新的TridentTopology();
TransactionalTridentKafkaSpout actSpout=新的TransactionalTridentKafkaSpout(actSpoutConf);
topology.newStream(topic,actSpout).parallelismHint(4.shuffle())
.each(新字段(“act”)、新打印函数()、新字段());
LocalCluster cluster=新的LocalCluster();
submitTopology(主题+“拓扑”,stormConf,Topology.build());
}}
还有另一个问题,为什么kryo方案只能读取一个消息缓冲区。是否有其他方法获得多个消息缓冲区,然后可以批量发送数据到下一个blot

另外,如果我发送1条消息,则整个流程似乎成功

然后发送2条消息是错误的。打印出的消息如下所示:


对不起,这是我的错误。刚刚在Kryo反序列化类中发现了一个bug,存在一个局部作用域参数,所以在多线程环境中可能会被过度写入。不更改参与方作用域中的参数,代码运行良好

参考代码见:

public class KryoSerializer<T extends BasicEvent> extends Serializer<T> implements Serializable {

private static final long serialVersionUID = -4684340809824908270L;

// It's wrong set

//private T event; 

public KryoSerializer(T event) {
    this.event = event;
}

@Override
public void write(Kryo kryo, Output output, T event) {
    event.write(output);
}

@Override
public T read(Kryo kryo, Input input, Class<T> type) {
    T event = new T();
    event.read(input);
    return event;
}
}
公共类KryoSerializer扩展序列化程序实现可序列化{
私有静态最终长serialVersionUID=-4684340898249082070L;
//这是错误的一套
//私人T事件;
公共KryoSerializer(T事件){
this.event=事件;
}
@凌驾
公共无效写入(Kryo-Kryo,输出,T事件){
事件写入(输出);
}
@凌驾
公共T读(Kryo-Kryo,输入,类类型){
T事件=新的T();
事件读取(输入);
返回事件;
}
}
public class KryoSerializer<T extends BasicEvent> extends Serializer<T> implements Serializable {

private static final long serialVersionUID = -4684340809824908270L;

// It's wrong set

//private T event; 

public KryoSerializer(T event) {
    this.event = event;
}

@Override
public void write(Kryo kryo, Output output, T event) {
    event.write(output);
}

@Override
public T read(Kryo kryo, Input input, Class<T> type) {
    T event = new T();
    event.read(input);
    return event;
}
}