sparkStreaming 中使用累加器遇到的坑

最近使用sparkstreaming是有個場景需要統計入mysql的數據量,因此考慮使用累加器;按照官網使用

如下方式:

 JavaStreamingContext jssc = new JavaStreamingContext (conf, Durations.seconds(3));
 LongAccumulator  BroadbandArrearsAll = jssc.sparkContext().sc().longAccumulator("BroadbandArrearsAll");

然後在處理邏輯中調用累加器

directStream.foreachRDD(rdd-> {
    //處理邏輯...
    //其他邏輯
    phoneData.foreachPartition(partitions->{
        
        if(滿足條件統計){
            處理邏輯
            broadbandArrears.add(1L);
        }
    })

})

把任務提交到集羣發現broadbandArrears.add(1L);報空指針錯誤。累加器實例在task中沒實例化;官網例子就是最外面實例的累加器???

之後使用下面方式實例化累加器

directStream.foreachRDD(rdd-> {
            LongAccumulator  broadbandArrears = rdd.context().longAccumulator("BroadbandArrears");
            //獲取kafka的 offset
            OffsetRange[] offsetRanges = ((HasOffsetRanges) rdd.rdd()).offsetRanges();
             //處理邏輯....
            phoneData.foreachPartition(partitions->{
                if(滿足條件){
                        處理邏輯
                        broadbandArrears .add(1L);
                    }

            });
});

提交任務後發現沒有問題,但是累加器累加的是一個task的計數,也就是流計算定義的一個Dstream中的數據

查閱資料後發現,應該使用單例模式,就是整個流任務定義一個累加器實例;代碼如下

class BroadbandArrears {
    private volatile  static LongAccumulator instance = null;
    public static   LongAccumulator  getInstance(SparkContext sc) {
        if (instance == null) {  //如果累加器不存在則創建
            synchronized(BroadbandArrears.class) {
                if (instance == null) {
                    instance = sc.longAccumulator("BroadbandArrears"); //用以記錄被刪除的詞
                }
            }
        }
        return  instance;
    }
}

directStream.foreachRDD(rdd-> {
            LongAccumulator instance = BroadbandArrears.getInstance(rdd.context());
            //獲取kafka的 offset
            OffsetRange[] offsetRanges = ((HasOffsetRanges) rdd.rdd()).offsetRanges();
            //處理邏輯....
            phoneData.foreachPartition(partitions->{
                if(滿足條件){
                        處理邏輯
                        instance.add(1L);
                    }

            });
});

你會發現達到了自己的目的;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章