Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache storm 如何关闭Storm Trident拓扑中iBackMap实现打开的数据库连接?_Apache Storm_Trident - Fatal编程技术网

Apache storm 如何关闭Storm Trident拓扑中iBackMap实现打开的数据库连接?

Apache storm 如何关闭Storm Trident拓扑中iBackMap实现打开的数据库连接?,apache-storm,trident,Apache Storm,Trident,我正在为我的Trident拓扑实现一个iBackMap,以将元组存储到ElasticSearch(我知道GitHub中已经有几个Trident/ElasticSearch集成的实现,但是我决定实现一个更适合我的任务的自定义实现) 因此,我的实现是一个带有工厂的经典实现: 公共类ElasticSearchBackingMap实现iBackMap{ //这里省略了其他一些很酷的东西。。。 私人最终客户; 公共静态StateFactory getFactoryFor(最终字符串主机、最终int端口、最

我正在为我的Trident拓扑实现一个iBackMap,以将元组存储到ElasticSearch(我知道GitHub中已经有几个Trident/ElasticSearch集成的实现,但是我决定实现一个更适合我的任务的自定义实现)

因此,我的实现是一个带有工厂的经典实现:

公共类ElasticSearchBackingMap实现iBackMap{
//这里省略了其他一些很酷的东西。。。
私人最终客户;
公共静态StateFactory getFactoryFor(最终字符串主机、最终int端口、最终字符串clusterName){
返回新的StateFactory(){
@凌驾
公共状态makeState(映射配置、IMetricsContext度量、int partitionIndex、int numPartitions){
ElasticSearchBackingMap esbm=新的ElasticSearchBackingMap(主机、端口、群集名称);
CachedMap cm=新的CachedMap(esbm,本地缓存大小);
MapState ms=OpaqueMap.build(cm);
返回新的SnapshottableMap(ms,新值(全局_键));
}
};
}
公共ElasticSearchBackingMap(字符串主机、int端口、字符串clusterName){
设置设置=ImmutableSettings.settingsBuilder()
.put(“cluster.name”,clusterName).build();
//TODO添加关闭客户端的可能性
客户端=新的TransportClient(设置)
.addTransportAddress(新的InetSocketTransportAddress(主机、端口));
}
//实际的实现被忽略了
}
您可以看到,它获取主机/端口/集群名称作为输入参数,并创建一个ElasticSearch客户端作为类的成员,但它从不关闭客户端

然后从拓扑中以一种非常熟悉的方式使用它:

tridentTopology.newStream(“喷口”,喷口) //…这里有一些处理步骤。。。 .groupBy(聚合字段) .持久聚合( ElasticSearchBackingMap.getFactoryFor( ElasticSearchConfig.ES_主机, ElasticSearchConfig.ES_端口, ElasticSearchConfig.ES\u群集\u名称 ), 新字段(字段名.结果), 新的BatchAggregator(), 新字段(FieldNames.AGGREGATED)); 该拓扑被包装到一些公共静态void main中,打包在一个jar中,并发送给Storm执行

问题是,我应该担心关闭ElasticSearch连接,还是这是Storm自己的事?如果不是Storm完成的,我应该如何以及何时在拓扑的生命周期中完成


提前谢谢

好的,回答我自己的问题

首先,再次感谢@dedek的建议,并在Storm's Jira中重新推出门票

最后,由于没有官方的方法,我决定使用Trident过滤器的cleanup()方法。到目前为止,我已经验证了以下内容(针对Storm v.0.9.4):

使用本地群集

  • 在群集关闭时调用cleanup()
  • 清除拓扑时不会调用cleanup(),这不应该是一个悲剧,很可能不会使用LocalCluster进行真正的部署
具有真实群集

  • 当拓扑被终止时,以及当工作进程停止使用pkill-TERM-u storm-f'backtype.storm.daemon.worker'时,都会调用它
  • 如果工人被kill-9杀死,或者当它崩溃,或者不幸的是,当工人由于异常而死亡时,它不会被调用
总的来说,这或多或少地保证了cleanup()能够被调用,前提是要小心异常处理(无论如何,我倾向于在我的每一个Trident原语中添加“ThunderCatch”)

我的代码:

公共类CloseFilter实现过滤器{
私有静态最终记录器LOG=LoggerFactory.getLogger(CloseFilter.class);
私人最终可关闭[]可关闭;
公共关闭过滤器(可关闭…可关闭){
this.closeables=closeables;
}
@凌驾
公共布尔值isKeep(三元组){
返回true;
}
@凌驾
public void prepare(映射配置、TridentOperationContext上下文){
}
@凌驾
公共空间清理(){
用于(可关闭c:可关闭){
试一试{
c、 close();
}捕获(例外e){
warn(“未能关闭{}的实例”,c.getClass(),e);
}
}
}
}

不过,如果有一天用于关闭连接的钩子成为API的一部分,那就太好了。

TransportClient应该是每个storm worker的一个单例。实际上,我认为您不需要关闭java客户端,因为storm topology应该永远不会停止。黑客可能是:在每个worker上创建一个单例,例如,在创建第一个状态时,在聚合器的清理方法中关闭这个单例-我在代码中看到了
BatchAggregator
。但我也希望看到一个更好的解决方案……也可以看到这个功能请求:感谢@dedek的破解!现在我正在使用最新版本的Kafka Producer API实现一个向Kafka发送事件的状态,它必须关闭,否则会有事件丢失的风险。我的代码中的BatchAggregator实现了没有cleanup()的ReducerAggregator。但是标准函数中有清理功能,可以实现类似smth的CloseConnectionFunction[facepalm]问题是,如果杀死拓扑会触发清理(),我从未见过它在本地集群上被触发。。。明天将尝试使用真正的集群,看看…@dedek请看下面我的答案。当然不是最好的,所以我们希望有一天STORM-49能够实现。