spark+scala+spring整合提高搬砖效率

标签: spark spring scala 大数据 分布式计算
14人阅读 评论(0) 收藏 举报
分类:

0.背景

为什么会想到把这三个整合在一起? 当然是工作中遇到不舒服的地方。

最近数据的需求特别多,有时候自己定位问题也经常要跑数据,通常就是spark+scala的常规画风。虽然是提同一个jar包,但执行的每个包的路径都不一样,这就导致我要不断的去改脚本,很不舒服。提交spark job的画风通常是这样子的:

spark-submit --cluster hadoop-spark2.0 \
	--class com.acceml.hit.User.PvCount \
    "xxx.jar" ${params1} ${params2} ${params3}

spark-submit --cluster hadoop-spark2.0 \
	--class com.acceml.hit.ShanghaiUser.UvCount \
    "xxx.jar" ${params1} ${params2} ${params3}

spark-submit --cluster hadoop-spark2.0 \
	--class com.acceml.hit.User.xxx.View \
    "xxx.jar" ${params1} ${params2} ${params3}
用spring整合了一下,提交一个job只要指定它执行的类名即可。如下,三条命令分别解析pv、uv、曝光...
sh log_parser.sh PvCount 20180412
sh log_parser.sh UvCount 20180412
sh log_parser.sh View 20180412

1.实现

1.1 思路

说白了,这上面就是不需要指定包路径,想让程序根据类名执行相应的逻辑,利用控制反转在spring中简直再简单不过了。java代码如下:

@Service
public class TaskEngine {
    //定义task名字到Task的一个映射
    private final Map<String, Task> name2Task = new HashMap<>();
    //自动注入所有Task的子类,这里task只是一个interface.
    @Autowired
    public TaskEngine(List<Task> tasks) {
        tasks.forEach(task -> name2Task.put(task.getClass().getSimpleName(), task));
    }
    public static void main(String[] args) throws Exception {
        //spring注入
        ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        TaskEngine taskEngine = (TaskEngine) appContext.getBean("taskEngine");
        //根据指定参数跑job.
        taskEngine.name2Task.get(args[0]).runTask();
    }
}
由于spark开发中我不喜欢用java,写起来太冗长,虽然java8支持lambda表达式,但是java版本和spark兼容的问题可能又是一个坑,用scala写job提交也可以借鉴自动注入,然后根据参数(类名)去选择提交哪个job,就此开始了如下尝试。

1.2 scala+srping实现依赖注入的功能

1、定义一个scala的trait:

trait LogParser extends Serializable {
    def name(): String =  {
        this.getClass.getSimpleName
    }
    def run(params: ParseParams, sparkSession: SparkSession)
}

2、所有要执行的业务逻辑程序都实现它:

@Component
class DemoParser extends LogParser {
    override def run(params: ParseParams, sparkSession: SparkSession): Unit = {
        //业务逻辑.
    }
}

3、定义一个LogparserFactory的Bean用spring的自动注入把LogParser所有子类注入进来。

@Service
class LogParserFactory {
    private var logParsers: java.util.List[LogParser] = _
    //自动注入所有子类.
    @Autowired
    def this(list: java.util.List[LogParser]) {
        this()
        logParsers = list
    }
}

4、spark主程序加载所有Bean,并选择所需要的逻辑去执行.

//spring注入
val appContext = new ClassPathXmlApplicationContext("applicationContext.xml")
//获取得到相应的Bean
val logParserFactory = appContext.getBean("logParserFactory").asInstanceOf[LogParserFactory]
logParserFactory.getLogParsers()
      .filter(e => e.name().equals(className))
      .foreach(e => e.run(params, sparkSession))

5、新来了一个需求就啥都不用改,再写一个类就可以了.

@Component
class View extends LogParser {
    override def run(params: ParseParams, sparkSession: SparkSession): Unit = {
        //业务逻辑.
    }
}

2.遇到的坑

2.1 spring版本不统一.

其他的依赖包里面经常会依赖不同版本的spring,导致程序运行时报错NoClassDefFoundError.这个时候用mvn dependency:tree查看一下。exclude掉其他version的spring就好了。

2.2 spring的xsi规则配置

由于spring是在spark集群中跑,xsi有可能定义为http形式可能获取不到,所以指定到classpath的路径下本地获取:

xsi:schemaLocation="http://www.springframework.org/schema/beans
            classpath:/org/springframework/beans/factory/xml/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
            classpath:/org/springframework/context/config/spring-context-4.1.xsd">

3.源码

Acceml/offline_job_babelgithub.com图标

4.约束

  • 类名不能重复,不然会报错,这是spring的性质决定的.

祝搬砖愉快 ⊙ω⊙


作者简介:

毕业于哈尔滨工业大学,就职小米科技,负责小米广告在线引擎的研发。

更多后端知识,请关注知乎专栏:春风得意码蹄疾

查看评论

程序搬砖大法

来,让我们愉快的搬砖吧!!!2333333!   作为一只飞的比较早的老鸟,一直被人问:“我这里不会写,怎么办呀!”“完全不知道怎么开始写啊!”“看到这个需求就懵逼!” 特别是看到刚入职的同事一脸懵逼...
  • w8452960
  • w8452960
  • 2017-04-28 10:33:27
  • 679

python3.5搬砖记录

新手一枚,记录学习python 的历程 格式化输出 print("{0}".format(a)) __name__ == main 的使用 try-except的用法 try-except-else的...
  • qq_29630271
  • qq_29630271
  • 2017-12-29 11:01:28
  • 181

对搬砖程序员的思考

我实习那段时间里,我一直在搬代码砖。以前在提高班我以能百度或者Google到一段代码来解决一个问题为荣。可是到了公司,老板和同事都特别嫌弃我们经常不知道如何写代码,然后花费比较长的时间去百度或者Goo...
  • u012308971
  • u012308971
  • 2016-04-30 23:03:03
  • 677

无风险套利?这是对搬砖最大的误解!

文/麦芽糖 在技术上这么专业的网站。我这文估计有点乱入的感觉。不管,反正发文是为了赚币。 对了。文章来源我的公号:麦芽识财(ID:MYshicai),各位客官来玩啊...
  • qq_41620424
  • qq_41620424
  • 2018-01-11 20:56:20
  • 1618

一个码农搬砖3年的总结

毕业三年了,搬砖生涯第一阶段已经结束,回顾一下纯粹技术学习方面的经历(不谈职场厚黑学以及政治话题,嘿嘿),仅与各位看官共分享,同进步 在校重基础 上面5个字,吐血箴言,别被导师忽悠,跟着做一些鸡毛项目...
  • secretx
  • secretx
  • 2016-08-18 11:42:57
  • 1636

区块链开发专题(数字货币国内平台如何搬砖流程)

区块链爱好者(QQ:53016353) 搬砖是非常灵活的 各家平台汇率不同 费用不同 存取时间差的不同 都会影响收益 初学者 可按下图灵活变化 不一定要按下图方法或步骤实施 可由个人自己研究添加...
  • jQQ53016353
  • jQQ53016353
  • 2017-06-19 13:43:09
  • 998

btc搬砖工具

  • 2013年11月11日 16:05
  • 7KB
  • 下载

IT搬砖者的内心独白

我为什么开始要写博客      大学毕业两年有余,一直从事于开发编程工作,虽历经几个项目组,但前几日面试官问我学到了什么技能我还真不知从何说起,好像经历了很多,但又好像什么也没经历一般,归根...
  • wenjinxingwen
  • wenjinxingwen
  • 2016-10-12 22:21:50
  • 328

搬砖问题 c++

题目内容: 现有n块砖,要由n人一次搬完,假定男人一次可以搬4块,女人一次可以搬3块,两个小孩搬1块,计算这n人中男人、女人和小孩的人数。 输入格式: 表示人数的整型数 ...
  • dxuehui
  • dxuehui
  • 2017-09-21 00:32:34
  • 435

4搬砖和抱你,我该如何选择?

“我不戴金箍,救不了她,戴了金箍,爱不了她。一万年太久,只争朝夕,一路走来,才发现没有什么是永垂不朽。我们才终于懂得,曾经离我们一步之遥的人,一旦错过,之后即使化身盖世英雄,身披金衣战甲,脚踏七彩祥云...
  • dabinge666
  • dabinge666
  • 2018-01-10 11:37:48
  • 83
    个人资料
    等级:
    访问量: 7万+
    积分: 1876
    排名: 2万+
    推荐网址
    博客专栏