百亿级日志处理稳定性保证的一些技巧

为了给各个业务出报表,我们每天会处理几百亿条原始日志。例行任务用MR/Spark程序编写,为了保证各业务线在上班前正常看到数据,对例行任务的稳定性提出了要求。由于我们会依赖很多中间层数据,集群偶尔异常、数据存在倾斜等问题,这对我们的程序带来了很大的挑战。针对遇到的问题,采用“兵来将挡,水来土掩”的方案,各个击破

依赖未生成

当天任务依赖的数据,部分是前一天的数据,部分是当天其他任务生成的数据。可以采用这两种方案。

添加监控

依赖的前一天的数据可能没生成。为了避免第二天的例行任务不挂掉,需要在前一天下午到晚上添加监控,如果数据没有按时生成,就发告警。然后由程序的owner来推动数据尽快产生。

function hdfs_check() {
    file=$1
    hadoop fs -test -e ${file}/_SUCCESS
    if [ $? -ne 0 ]; then
        send_mms "[FATAL]-[file_not_exists]-[${file}]" yanghao
    fi
}

function main() {
    date=`date -d "-1day" '+%Y%m%d'`
    hdfs_check  /user/yanghao/device_middle/date=${date}
}

程序启动时检查依赖

依赖的数据可能生成延迟,启动MR和Spark任务时,可以检查依赖是否生成,如果未生成,则一直等待,直到任务数据生成再启动

数据倾斜

数据倾斜会导致部分task的数据膨胀,进而导致内存溢出、任务变慢等后果。主要有下面几种方案来避免。

设计时避免

设计时考虑可能存在的倾斜问题,保证shuffle后各个key对应的数据量尽量均匀。

无法避免

  1. 将脏数据导致的倾斜问题提前过滤掉,再进行处理
  2. 如果数据没法过滤,将这部分数据分离,单独处理,然后合并到正常输出的结果中

集群异常

集群偶尔抖动,导致任务失败,但是重启问题能解决。这样可以在启动程序后,监控程序的返回值,如果失败,则重试。如果是MR,一般是waitForCompletion提交的,返回值表示是否正确执行,如果为false,则在代码中重新提交任务

本文总结了在生产环境中导致任务失败的常见case,并一一介绍了解决方案。当然报表未按时出来,还可能遇到其他问题,比如DB挂了,这就需要具体问题具体分析了。

你可能感兴趣的:(开发,MapReduce,spark私房菜)