spark streaming 使用updateByKey统计一段时间里wordcount 无法累加问题(checkpoint无效)

  • 代码功能:使用sparkStreaming的updateByKey()方法统计一段时间里面接收到的文本中每个单词出现的次数。

    • checkpoint地址默认放在hdfs的用户目录下。
      • 在虚拟机中使用dc -lk 9999 -v在9999端口上放入文本,StreamingContext的socketTextStream()方法从端口接受文本信息。
  • 发现在9999端口输入新的值之后,控制台输出当前的词频统计信息,但不会显示历史state的信息,并且也无法累计统计。

  • 推测是state为None,即无法从checkpoint获取历史版本。很可能是ssc.checkpoint('checkpoint')这里的路径解析有问题。于是:

    1. 到hadoop的hdfs用户目录下查看是否创建了checkpoint文件:hadoop fs -ls /user/root,发现空空如也。

    2. 想要spark能够自动找到hdfs的目录需要在spark-env.sh中配置hadoop配置文件的位置(HADOOP_HOME也是需要的)查看spark-env.sh:

      export HADOOP_CONF_DIR=/usr/local/hadoop/hadoop-2.10.1
      

      原来这里的路径写成了hadoop的主目录了。添加etc/hadoop即可:

      export HADOOP_CONF_DIR=/usr/local/hadoop/hadoop-2.10.1/etc/hadoop
      
import os
SPARK_HOME = '/usr/local/spark/spark-3.0.1-bin-hadoop2.7'
JAVA_HOME = '/usr/local/jdk/jdk1.8.0_271'
# HADOOP_HOME = '/usr/local/hadoop/hadoop-2.10.1'
# os.environ['HADOOP_HOME'] = HADOOP_HOME
os.environ['SPARK_HOME'] = SPARK_HOME
os.environ['JAVA_HOME'] = JAVA_HOME

from pyspark import SparkContext
from pyspark.streaming import StreamingContext

sc = SparkContext('local[2]',appName='updateByKey')
ssc = StreamingContext(sc,1)

# 1.开启检查点——这是pudateByKey必须的   默认会在hadoop的/user/root/目录下
ssc.checkpoint('checkpoint')

# 2.定义状态更新函数 参数一为新值,参数二为状态,返回新的状态
def updateFunc(new_values,last_state):
    return  sum(new_values) + (last_state or 0)     # 如果return None,key对应的state就会被删除,所以要避免

# 3. 数据来源:监听端口
lines = ssc.socketTextStream('localhost',9999)

# 4.对数据进行处理,reduce部分使用updateByKey()函数
counts = lines.flatMap(lambda line : line.split(' ')).map(lambda x : (x,1)).updateStateByKey(updateFunc=updateFunc)

counts.pprint()

ssc.start()
ssc.awaitTermination()
posted @ 2021-01-11 18:49  风和雨滴  阅读(167)  评论(0编辑  收藏  举报