Spark Streaming 任务定时清零重启

作者:草小诚([email protected]
转载请注原文地址:https://blog.csdn.net/cxcjoker7894/article/details/85774764

本文介绍state定时清零,如欲监控失败自动重启请移步【Spark Streaming 监控失败后自动重启】

业务实现中,监听目录后,在任务里用 updateStateByKey 方法储存了当前的计算数值(state),但是实际的数据要求 每天清零,也就是一直都仅显示当天的计算数值。

Spark Streaming 似乎没有直接提供这样的功能,那么除了写系统脚本每天重启 Spark Job,有没有更优雅的解决办法呢?

哈,当然是有的,利用 while TrueawaitTerminationOrTimeout 函数就可以实现了,各语言的这个方法都在 StreamingContext 包(类)里:

Scala 文档 StreamingContext 包下的 awaitTerminationOrTimeout 方法(搜索)
Java 文档 StreamingContext 类下的 awaitTerminationOrTimeout 方法(搜索)
Python 文档 pyspark.streaming.StreamingContext.awaitTerminationOrTimeout

方法的解释是:执行后会等待任务的结束,如果结束会返回 True,如果过程中出现异常会抛出,可以设置 timeout 时长,设置后如果限定时长内没有等到任务结束,就返回 False

所以不难看出,我们只要设置 timeout 时长至每天的零点,然后等待该方法返回 False 再去重新 start 任务就好了。因为返回 False 就意味着这个方法一直等到了零点任务都没有结束。

下面以python为例,先获取当前时间到明天零点的秒数,作为 timeout 时长:

import datetime

def get_reset_seconds():
    # 明天0点的时间字符串
    date_second = (datetime.datetime.now() + datetime.timedelta(days=1)).strftime("%Y-%m-%d") + ' 00:00:00'
    # 明天0点的时间戳(秒)
    reset_ts = int(datetime.datetime.strptime(date_second, "%Y-%m-%d %H:%M:%S").timestamp())
    # 当前时间到明天0点的差值(秒)
    return reset_ts - int(datetime.datetime.now().timestamp())

将任务的创建与启停用 while True 包起来,每次循环为一天,每次重启都重新调用上面的方法设置 timeout 时长,即使是首次启动也无需担心:

from pyspark import SparkContext
from pyspark.streaming import StreamingContext

while True:
    spark_context = SparkContext('example','example')
    streaming_context = StreamingContext(spark_context, 1) # 伪实时,每1秒计算一次目录增量
    file_stream = streaming_context.textFileStream('/example')
    streaming_context.checkpoint('/example')
    ………………
    streaming_context.start()
    if streaming_context.awaitTerminationOrTimeout(get_reset_seconds()) == False:
        streaming_context.stop()

大功告成,这个任务会在每次 awaitTerminationOrTimeout 方法返回 False 的时候进入下一个循环,即每天0点的时候自动重启,清空原来的计算数值(state),完美的实现了需求。

你可能感兴趣的:(Spark)