我有一个spout类,它有几个整数和字符串属性,按预期序列化/反序列化。该类还有1个LinkedList保存字节数组。当反序列化对象时,此LinkedList始终为空。
我已将日志语句添加到所有spout方法中,并且可以看到spout'激活'调用方法,之后,LinkedList为空。当发生这种情况时,我没有看到任何记录,以便停用'方法
喷口“激活”似乎很奇怪。在没有“停用”的情况下调用方法。被称为的方法。当'激活'调用方法时,没有重新提交拓扑。
我在spout构造函数中也有一个日志语句,它在清空LinkedList之前不会被调用。
我还反复验证,spout类中的任何地方都没有调用任何完全清空LinkedList的方法。有一个使用poll方法的点,后面紧跟一个日志语句来记录新的LinkedList大小。
我找到了这个引用,它指向Kryo用于序列化,但它可能仅用于序列化元组数据。 http://storm.apache.org/documentation/Serialization.html
Storm使用Kryo进行序列化。 Kryo是一个灵活而快速的人 生成小序列化的序列化库。
默认情况下,Storm可以序列化基本类型,字符串,字节数组, ArrayList,HashMap,HashSet和Clojure集合类型。如果你 想要在你的元组中使用其他类型,你需要注册一个 自定义序列化器。
这篇文章听起来像Kryo可能只是用于序列化和传递元组,但如果它也适用于Spout对象,我无法弄清楚如何使用LinkedList作为ArrayLists和HashMaps并不是&# 39;对于FIFO队列来说,它确实是一个很好的选择。我是否必须滚动自己的LinkedList?
public class MySpout extends BaseRichSpout
{
private SpoutOutputCollector _collector;
private LinkedList<byte[]> messages = new LinkedList<byte[]>();
public MyObject()
{
queue = new LinkedList<ObjectType>();
}
public void add(byte[] message)
{
messages.add(message);
}
@Override
public void open( Map conf, TopologyContext context,
SpoutOutputCollector collector )
{
_collector = collector;
try
{
Logger.getInstance().addMessage("Opening Spout");
// ####### Open client connection here to read messages
}
catch (MqttException e)
{
e.printStackTrace();
}
}
@Override
public void close()
{
Logger.getInstance().addMessage("Close Method Called!!!!!!!!!!!!!!!!!");
}
@Override
public void activate()
{
Logger.getInstance().addMessage("Activate Method Called!!!!!!!!!!!!!!!!!");
}
@Override
public void nextTuple()
{
if (!messages.isEmpty())
{
System.out.println("Tuple emitted from spout");
_collector.emit(new Values(messages.poll()));
Logger.getInstance().addMessage("Tuple emitted from spout. Remaining in queue: " + messages.size());
try
{
Thread.sleep(1);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
Logger.getInstance().addMessage("Sleep thread interrupted in nextTuple(). " + Logger.convertStacktraceToString(e));
e.printStackTrace();
}
}
}
}
编辑:
Java Serialization of referenced objects is "losing values"? http://www.javaspecialists.eu/archive/Issue088.html
上面的SO链接和java专家文章提出了类似于我所看到的具体示例,问题是进行序列化/反序列化缓存。但由于Storm正在开展这项工作,我不确定该怎么办。
在一天结束时,似乎更大的问题是Storm首先突然序列化/反序列化数据。
编辑:
在Spout被激活之前,在不到一秒的时间内就可以看到很多日志消息:
执行官MyTopology-1-1447093098:[X Y]不活着
在这些消息之后,有一个日志:
为拓扑ID设置新的分配MyTopology-1-1447093098:#backtype.storm.daemon.common.Assignment {:master-code-dir ...
答案 0 :(得分:0)
如果我正确理解您的问题,您可以在客户端实例化您的spout,通过addMessage()
添加消息,通过addSpout()
将spout提供给TopologyBuilder,然后将拓扑提交到您的群集?拓扑启动时,您希望spout消息列表包含您添加的消息吗?如果这是正确的,你的使用模式很奇怪......
我猜这个问题与Thrift有关,Thrift用于将拓扑提交给集群。没有使用Java序列化,我假设,Thrift代码不会序列化实际对象。据我所知,代码中,拓扑jar是二进制的,拓扑 structure 是通过Thrift发布的。在执行拓扑的工作人员上,通过new
创建新的spout / bolt对象。因此,不会发生Java序列化/反序列化,并且您的LinkedList为空。由于new
的调用,它当然不是null
。
作为解决方法,您可以将LinkedList
添加到Map
的{{1}}。在StormSubmitter.submitTopology(...)
中,您应该从Spout.open(...)
参数中获取正确的邮件副本。但是,正如我已经提到的,你的使用模式很奇怪 - 你可能想重新考虑一下。通常,应该以某种方式实现spout,即可以从外部数据源获取Map
中的数据。