我需要在apache storm中设计一个拓扑,它可以读取多个属性文件。在我的原始设计中,将在创建拓扑时加载属性,并且每个螺栓将通过使用参数(例如builder.setBolt("Bolt1", new Bolt1(param1, param2, ...), 3)...
)获得所需的属性。但是,每次我想更新属性文件时,我都必须重新启动拓扑,此操作将清除内存中的数据。我不想得到这个结果,但是,在每个螺栓中加载属性文件的成本很高,并且它不是一个好的设计。
我有另一个想法。我使用bolt来加载属性文件并将其保存在parameter object
中。这个螺栓在喷口之后,它会将parameter object
发射到下一个螺栓。在此设计中,parameter object
将被发送到需要它的螺栓,并且它可以防止多次访问属性文件。
但是,我不确定它是好的设计还是存在更好的设计。请给我一些建议。非常感谢!
答案 0 :(得分:0)
一个选项是将配置文件存储在HDFS中,并使用tick tuples定期将其重新加载到您的螺栓内(免责声明:我关于使用tick元组的博客文章)。
例如:
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
try {
if (isTickTuple(tuple)) {
// refresh our configs from HDFS
_fileLoader.load(_configs);
return;
}
// do your bolt stuff
// use configs you loaded earlier
// ...
} catch (Exception e) {
LOG.error("Bolt execute error: {}", e);
collector.reportError(e);
}
}
我之所以选择HDFS,是因为API很简单,适用于parsing libraries like jackson。例如:
FileSystem fs = FileSystem.get(URI.create(_hdfsUrl), new Configuration());
String path = "hdfs://server/folder/something.json";
Path p = new Path(path);
if (fs.exists(p)) {
InputStreamReader istream = new InputStreamReader(fs.open(p))
Map<String, Set<String>> map = new HashMap<String, Set<String>>();
ObjectMapper mapper = new ObjectMapper();
map = mapper.readValue(istream, new TypeReference<HashMap<String, HashSet<String>>>() {});
}
响应&#34;加载属性文件在每个螺栓中是昂贵的,这不是一个好的设计&#34; ...我不同意。您的螺栓将在整个群集中分布到许多不同工作者(也称为许多不同的JVM)中的许多不同节点。这意味着您需要在同一个螺栓的多个实例中加载配置。另外,如果你想动态重新加载配置,你将需要在你的螺栓内部的那个机制。
另一种选择是使用Zookeeper,但说实话,API使用起来很痛苦,HDFS也很完美。