Storm缓存对象的传递(多个bolt共同操作同一个缓存)

本文探讨了在Apache Storm中实现缓存管理的有效方法。通过对比两种不同的实现思路——构造函数传参与使用get方法,详细解释了为何在Storm的环境下,直接通过构造函数传递缓存对象的方式不可行,而通过在prepare方法中初始化缓存并提供get方法来获取同一对象引用的方法可行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

最近项目中遇到要在Bolt A 中添加缓存cache,在Bolt B中删除缓存cache的需求。

思路:

两个思路

  1. 在拓扑(Topology)中创建一个缓存,将创建的缓存以构造函数传参的形式传递进去。
  2. 在上游的Bolt,也就是Bolt A中创建一个缓存,并在该类中添加get方法。

 第一种思路(构造函数传参:实验证明不可用)

原因:storm的prepare中会对对象进行序列化和反序列化,之后形成一个新的对象。传递进来的对象并没有使用。

 以下代码是一个简写,主函数中会创建一个set对象,通过构造函数传递到bolt中。

此时set的对象地址传递到了boltA和boltB中。

在storm继续运行启动prepare的时候,storm框架会对你创建的对象进行序列化和反序列化,之后重新创建一个对象。

此时,主函数一个对象、BoltA一个对象、BoltB一个对象。一共有三个对象,不存在共用缓存的说法。

    // 主函数
    public static void main(String[] args){
        Set<String> set = new HashSet<>();
        TopologyBuilder builder = new TopologyBuilder();
        builder.setSpout("Spout", new Spout());
        builder.setBolt("BoltA", new BoltA(set)).globalGrouping("Spout");
        builder.setBolt("BoltB", new BoltB(set)).globalGrouping("Spout");
    }
    // Bolt A
    private static HashSet<String> setA;
    public BoltA(HashSet<String> set) {
        this.setA = set;
    }
    public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
    }
    // Bolt B
    private static HashSet<String> setB;
    public BoltB(HashSet<String> set) {
        this.setB = set;
    }
    public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
    }

 更为详细的解释

private Map<String, Integer> counts = null;

	/**
	 * 注意: 所有的序列化操作最好都在prepare方法中进行 原因:
	 * Storm在工作时会将所有的bolt和spout组件先进行序列化,然后发送到集群中,
     * 如果在序列化之前创建过任何无法序列化的对象都会造成序列化时抛出NotSerializableException。
	 * 此处的HashMap本身是可以序列化的所以不会有这个问题,但是有必要养成这样的习惯 。
	 */
	@Override
	public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
		this.collector = collector;
		this.counts = new HashMap<>();
	}

 

第二种思路(使用get方法,实验可以使用)

原因:在storm的prepare中初始化对象,通过get方法获取到的是同一个对象引用。

在BoltA中创建一个缓存,并添加一个get方法,在BoltB中调用。

此时传递的是同一个对象引用。

    // Bolt A
    private static ConcurrentHashSet<String> setA;

    public void prepare(Map conf, TopologyContext context, OutputCollector collector) {
        setA = new ConcurrentHashSet<>();
    }

    public static ConcurrentHashSet<String> getSetA() {
        return setA;
    }

    // Bolt B
    public void execute(Tuple tuple) {
        BoltA.getSetA.remove();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值