为做到数据的实时传输(实时:当前时间传输上一个小时的数据),shell用于控制整个流程,python用于处理数据。
shell代码如下:
#bin/bash ######### ## 笃笃学车4G运行脚本 ## 编写者:zhangqm ## 日期:2018-04-04 ## 调用方式:nohup sh duduxueche.sh day/hour > ../log/duduxueche.log 2>&1 & ## type数据有两种:1、day:按天跑 2、hour:按小时跑 ######## # 程序的日志目录 log='/data1/u_lx_data/zhangqm/yanjie/dudu/log' # 4G表的HDFS目录 sourceDataHdfs='/user/db_lte/public/sada_lte_xdr03_103' # MR清单数据,HDFS目录 mrDataListHdfs='/user/u_lx_data/private/zhangqm/dudu' # MR清单数据,本地目录 dataList='/data1/u_lx_data/zhangqm/yanjie/dudu/data' # 结果数据 resultList='/data1/u_lx_data/zhangqm/yanjie/dudu/result' # 稽核语句 # 调用方式:Check_num 目录 时间 小时 function Check_num() { if [ $3 == 'day' ];then num=$(hadoop fs -du -h -s $1/$2 |awk -F" " '{print $1}'|sed 's/ //g') echo $num else num=$(hadoop fs -du -h -s $1/$2/$3|awk -F" " '{print $1}'|sed 's/ //g') echo $num fi } # 得到清单数据 # 调用方式:Deal_data 时间 小时 function Deal_data() { if [ $2 == 'day' ];then # 拉清单数据 echo '开始处理'${dayTime_1}'天数据。。。' hadoop jar dudu4g_0514.jar ${sourceDataHdfs}/$1/ ${mrDataListHdfs}/$1 # 检查天数据是否产生 size=$(Check_num ${mrDataListHdfs} $1 $2) if [ ${size} > 0 ] ; then hadoop fs -cat ${mrDataListHdfs}/$1/* > ${dataList}/$1.txt else echo '天数据没有产生,请核查。。。' fi else # 拉清单数据 echo '开始处理'${dayTime}${hourTime_1}'小时数据。。。' hadoop jar dudu4g_0514.jar ${sourceDataHdfs}/$1/$2 ${mrDataListHdfs}/$1/$2 # 检查小时数据是否产生 size=$(Check_num ${mrDataListHdfs} $1 $2) if [ ${size} > 0 ] ; then if [ ! -d ${dataList}/$1 ];then mkdir ${dataList}/$1 fi hadoop fs -cat ${mrDataListHdfs}/$1/$2/* > ${dataList}/$1/$2.txt else echo '当前小时数据没有产生,请核查。。。' fi fi } #按小时跑 function Run_hour() { while true do # 获取系统当前时间 dayTime=$(date +"%Y%m%d" ) # 获取系统当前小时的前1小时的小时 hourTime_1=$(date -d "-1 hour" +"%H") if [ ${hourTime_1} -eq 23 ];then dayTime=$(date -d "-1 day " +"%Y%m%d") fi # 测试小时数据是否已经产生 hadoop fs -test -e ${mrDataListHdfs}/${dayTime}/${hourTime_1} #十五分钟检测一次,主要是解决跑程序所花费的时间不同问题 if [ $? -eq 0 ] ;then echo '******************************************' echo ${dayTime}${hourTime_1}'小时已经跑过。。。。' echo '等待十五分钟。。。。。' sleep 900 echo '当前时间为:'$(date +"%Y-%m-%d %H:%M") else echo '******************************************' echo ${dayTime}${hourTime_1}'小时没有跑过。。。。' echo '当前时间为:'$(date +"%Y-%m-%d %H:%M") Deal_data ${dayTime} ${hourTime_1} if [ ! -d ${resultList}/${dayTime} ];then mkdir ${resultList}/${dayTime} fi echo '得到结果数据,当前时间为:'$(date +"%Y-%m-%d %H:%M") python duduxueche.py ${dataList} ${dayTime} ${hourTime_1} ${resultList} echo ${dayTime}${hourTime_1}'小时全部结束,进入下一个小时的处理。。。。' #把70的数据结果放到231的HDFS上 ./duduxueche.exp ${resultList} ${dayTime} ${hourTime_1} fi # exit 2 done } #按天跑 function Run_day() { while true do # 获取系统当前时间 dayTime=$(date +"%Y%m%d" ) # 获取系统时间的前一天的时间 dayTime_1=$(date -d "-1 day $dayTime" +"%Y%m%d") # 测试天数据是否已经产生 hadoop fs -test -e ${mrDataListHdfs}/${dayTime_1} #8小时检测一次,主要是解决跑程序所花费的时间不同问题 if [ $? -eq 0 ] ;then echo '******************************************' echo ${dayTime_1}'天已经跑过。。。。' echo '等待8个小时。。。。。' sleep 28800 echo '当前时间为:'$(date +"%Y-%m-%d %H:%M") else echo '******************************************' echo ${dayTime_1}'天没有跑过。。。。' echo '当前时间为:'$(date +"%Y-%m-%d %H:%M") Deal_data ${dayTime_1} $1 #if [ ! -d ${resultList}/${dayTime} ];then # mkdir ${resultList}/${dayTime} #fi echo '得到结果数据,当前时间为:'$(date +"%Y-%m-%d %H:%M") python duduxueche.py ${dataList} ${dayTime} ${hourTime_1} ${resultList} #echo ${dayTime}${hourTime_1}'小时全部结束,进入下一个小时的处理。。。。' # 把70的数据结果放到231的HDFS上 #./duduxueche.exp ${resultList} ${dayTime} ${hourTime_1} fi # exit 2 done } if [ $1 == 'hour' ] ;then Run_hour else Run_day $1 fi
Python代码如下:
# -*- coding:utf-8 -*- from datetime import datetime import pandas as pd import sys #***************** ##按口径出的phone结果 # 口径:1)关键词且官网 2)关键词且app 3)关键词访问大于1 4)官网访问大于1 #***************** def Main(): dataList = sys.argv[1]+"/"+ sys.argv[2]+"/"+sys.argv[3]+".txt" # 对照表清单数据(加密和不加密手机号对应关系) mapRuletxt = sys.argv[1]+"/"+"mapRuletxt.txt" targetTxt = sys.argv[4]+"/"+ sys.argv[2]+"/"+sys.argv[3]+".txt" # 存储最终解果 phoneSet = set() # 存储有关键词行为的phone kwPhoneSet = set() # 存储有官网行为的phone webPhoneSet = set() # app行为 appPhoneSet = set() #存储对照表清单数据 dict={} uname = ['phone', 'time', 'name'] # 找官网的数据 def web(str): if str.find('app') == -1 and str.find('kw') == -1: return str print("开始。。。。。") print(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) with open(mapRuletxt,'r') as fr: for line in fr: line = line.strip().split("\t") dict[line[1]] = line[0] with open(dataList,'r') as fr: for line in fr: line = line.strip().split("\t") if line[2].find('app') != -1: # app的 appPhoneSet.add(line[0]) elif line[2].find('kw') != -1: #关键词搜索的 kwPhoneSet.add(line[0]) else: # 官网访问行为的 webPhoneSet.add(line[0]) # 有过关键词搜索行为且有过官网访问行为的phone for kwphone in kwPhoneSet: if kwphone in webPhoneSet: phoneSet.add(kwphone) # 有过关键词搜索行为且有过app行为的phone for kwphone in kwPhoneSet: if kwphone in appPhoneSet: phoneSet.add(kwphone) # 关键词访问大于1的phone df = pd.read_table(dataList, sep="\t", header=None, names=uname, index_col=False)[['phone', 'name']] kw = df[df.name.str.contains('kw')].groupby('phone')['name'].agg([('uv',pd.Series.nunique)]).reset_index() for phone in kw[kw.uv > 1]['phone']: phoneSet.add(phone) # 官网访问大于1的phone web = df.applymap(web).dropna().groupby('phone')['name'].agg([('uv',pd.Series.nunique)]).reset_index() for phone in web[web.uv > 1]['phone']: phoneSet.add(phone) with open(targetTxt,'w+') as fw: for phone in phoneSet: if phone in dict: fw.write(dict[phone]+"\n") print("结束。。。。。") print(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) if __name__ == "__main__": Main()