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

问题:

最近项目中遇到要在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) {
    }

第二种思路(使用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();
    }

猜你喜欢

转载自blog.csdn.net/qq_39313597/article/details/88891041