一、问题
在YARN上停止Spark Streaming的方式比较粗暴“yarn application -kill [applicationId]”。
命令执行后,YARN在分配给Streaming App的container上执行“kill -15”命令结束进程,不会考虑Streaming App的执行情况。
虽然spark-yarn的ApplicationMaster在启动时加入了shutdownHook执行sc.stop(),但是这也只能使Spark Context完成关闭工作。Streaming Context中的receiverTracker、jobGenerator、jobExecutor等组件并不会正常关闭。
当然,如果你启用了checkpoint和writeAheadLog(以ReliableKafka为例),这并不会造成数据的丢失。但是正在执行的RDD中的数据在应用恢复后会被再处理一次,造成数据的重复处理。如果,你的Streaming App对数据的准确性要求比较高,那就需要自己实现一个Stop Gracefully的方法。
虽然spark-yarn的ApplicationMaster在启动时加入了shutdownHook执行sc.stop(),但是这也只能使Spark Context完成关闭工作。Streaming Context中的receiverTracker、jobGenerator、jobExecutor等组件并不会正常关闭。
当然,如果你启用了checkpoint和writeAheadLog(以ReliableKafka为例),这并不会造成数据的丢失。但是正在执行的RDD中的数据在应用恢复后会被再处理一次,造成数据的重复处理。如果,你的Streaming App对数据的准确性要求比较高,那就需要自己实现一个Stop Gracefully的方法。
二、解决方案
调用SteamingContext类的stop方法是关闭Streaming Context最好的方法。我们要做的就是在关闭App的时候调用执行这个方法。