前些日子调整武魂数据监控脚本,将部分hive脚本的运行时间进行了优化,对如何编写高效简洁的hive脚本,也进行了一定的思考:
1、一开始就要强制不往复杂的方向靠。很多时候,随着需求的增多以及变动,我们的脚本会越来越长,越来越丑陋不堪。这时候,要么保持脚本的正确性算了,脚本多么复杂丑陋都无所谓。要么花点时间调整下脚本(比如拆成几个独立的脚本),可以让自己和别人很容易看懂。从实践经历来看,后者相对前者更优,因为这个隐形要求(脚本不能太复杂),就会强迫自己花时间去思考、花精力实践编写更简洁的脚本。
2、最重要的是对未来的判断。其实,完成一个特定应用的hive脚本比较交单,难的是后续的需求变更和维护。要懂得判断估计可能会出现的情况,做好相应的准备,才不会被各种“坑”伤害到。编写数据处理的hive脚本有3点是需要预估的:
* 数据需求和业务的特点。在数据监控的“陷阱”这篇文章已经说过,就不重复了。总之,编写数据处理脚本都需要考虑这几个问题。
* 数据量的扩展性。当游戏从测试期到运营期,游戏服务器从1台递增到50台递增到100台时,前期编写的运行脚本是否还可以正常运行?随着数据量的线性增长,脚本的运行时间是否也以线性时间增长?
* 合理评估各项工作的时间、代价、收益,学会取舍,不追求完美。如果考虑所有的后续变化,工作量太多,则是不太现实的。如果部分数据需求变更几率很少,即使修改需要的时间也很少,那么就不需要在前期做这些工作,后期维护迭代也是可以接受的。
3、学会思考hive的一些特性,这次调整hive的监控脚本,对hive的理解也加进了一层:
* Map(映射)、Reduce(化简)等函数式编程概念是很巧妙的。复杂的数据处理应该在Map阶段完成,而不是在Reduce阶段,因为Reduce阶段是化简和汇总阶段。
* hive join的左表要尽可能少。对于左表,如果需求可以用distinct去除掉左表重复记录,就一定用distinct,可以节省join的运行时间。
* Hive可以自定义Map/Reduce脚本。但使用时需要注意,Map/Reduce脚本的运行时间过长,则也会成为hive脚本的运行瓶颈。发生这种情况,也需要优化Map/Reduce脚本。