用shell控制hql执行,如何控制多个阶段之间串行,阶段内部并行

来源:互联网 发布:福建网络安全教育 编辑:程序博客网 时间:2024/06/16 10:55

上周组里同学给了一个数据任务:

1.在hive上传汽车词包

2.根据汽车词包圈出指定时间段内的cookie

3.根据cookie找出这些用户的所有搜索记录

4.从所有搜索数据中找到含有明星的搜索记录

5.根据每个明星group by,计数

我的解决办法如下:

1.第一第二第三阶段我写了一个sql语句



2.第四阶段我用了python处理,因为我无法写成

select query

from sousuo

where query like

(

select "%star%"

from star

)

所以我就用了python逐行处理

python代码如下


3.将python的结果上传hive,然后上传明星词表,然后group by,sql代码如下


 

这个程序刚写完的时候还挺开心,因为我用了hivevar来封装了参数,可以完全自动化运行。

但是周一同学使用的时候反映半年的词包提不上去,只能提15天的。然后我就意识到sql映射的mapper个数太多,导致任务提不上去。

首先sql语句不适合将多个步骤融合在一起,会导致sql映射的mapper文件太多,导致任务提不上去。

所以每步都分开。

第一阶段:

上传词包.sql

第二阶段:

圈pc端cookie.sql

圈wise端cookie.sql

第三阶段:

圈pc端的搜索数据

圈wise端的搜索数据

第四阶段:

用python对搜索数据做明星词的过滤。

第五阶段:

将过滤出来的结果上传hive,用group by计数

 

main函数:

main函数为了保证串行执行,所有的sql语句都不能后台启动,如果后台启动,下一阶段将不会等上一阶段的结果。

但是第二、第三阶段中的pc端和wise端应该并行做。

解决方法是

对第二阶段的两个sql都用后台启动:

nohup sh qe.sh stage2_pc &

nohup sh qe.sh stage2_wise &

但是要在原来qe.sh脚本的后面,写上echo "" > stage2_pc.done,这样sql执行成功后,就会生成相应的done文件。

启动成功后,不能立即启动第三阶段,也不能通过if [[ $? == 0 ]]来检测第二阶段是否执行成功。

而要写一个while循环不停检测stage2_pc.done和stage2_wise.done是否生成。

如果生成才能继续执行第三阶段,如果没有生成就一直在此检测。

第三阶段的并行启动同样这样处理。

当然上面的这种处理办法,只是将频道分开,并未将一个大的时间段映射成多个小的时间段。


 

部门的产品线mcdt系统的后台正是这样处理的,如果sql包含的时间范围太大,频道太多,都会造成sql生成的mapper个数太多,所以对频道分开,对时间段也会分开,拆成一个一个的,然后并行启动。

因为涉及到多个阶段,然后每个阶段中又有多个sql,所以会为每个阶段建立一个文件夹,检测这个文件夹下所有sql是否成功执行的方法就是,就是检测done文件个数和sql文件个数是否相等,如果相等就执行下一个stage,如果不相等,就一直检测,这样就能严格保证每个阶段内的sql并行执行,多个阶段之间串行执行,下面给出了mcdt后台控制流程的shell中的一段代码:


 

借鉴于这种解决方案,这个同学的任务也应该将时间段分开,频道分开,映射成多个sql文件,并且将这些sql文件放在一个文件夹下,一起后台执行,因为sql文件太多,所以在最后的while循环中检测目录下done文件个数和sql文件个数是否相等比较方便。

之前看后台的这个代码感觉没有什么稀奇,现在真的感觉原作者的良苦用心。

 

遗留问题:

1.起止时间是在配置文件中写的,把时间片切开,比如30天一个sql文件,这么多的sql文件都是自动生成,考虑用python动态组装sql语句。

2.成功生成done文件,error文件如何生成的。

重启三次脚本都不能成功,就生成error文件,另外注意done文件在sql执行成功之后才能生成,所以调用sql不能后台启动。


3.如果数据量太大,用python逐行处理可能比较耗时,这里完全可以考虑用原生的mapred来写,因为源数据不能通过hive建表,所以通过hadoop写或者spark写都可以,对容器过滤,可以用到spark中的filter()函数。

为啥我会意识到这里可以用spark?

我们可以简单考虑搜索数据可以人为分成多个部分,然后在每个部分同时运行这个pyhton代码,多个部分之间可以完全不影响的并行运行,这就是mapred最合适的应用场景。