随着spark越来越流行,我们的很多组件都有可能和spark集成,比如说spark处理完的数据写入mysql,redis,或者hbase,elasticsearch,spark本身不包含db的依赖的,这就需要自己解决依赖的jar包,这里大致有两种处理思路处理依赖问题:
(1)使用maven将整个依赖打成一个fat的jar,这样所有的依赖都会在一个jar包,这样的好处就是一个jar包包含所有依赖,不需要额外考虑依赖的问题,但是弊端也非常明显如果依赖多的话jar包的体积会非常大超过100M都很正常,每次代码有小的变更都需要重新编译上传linux测试,如果你们win环境跟服务器中间是通过V**连接的,每次只允许上传几kb的数据,那么你就完蛋了,等你上传100M的jar包完了,1个小时也过去了,而且中间如果V**不稳定断了,那么恭喜你,你需要重新再来一次。一天的上班时间也就够你调试8次代码.....
(2)第二种方式是使用maven将核心代码打成一个jar,依赖的不打进去,但是需要自己把依赖的jar包在服务器上做成一份共享的,每次程序运行时都可以加载到,这样的工作只需要做一次即可,以后代码变更,只会提交核心代码,共享的依赖用在变化,这样的好处就是动静分离,核心代码体积非常小,只有只kb,每次编译重新打包上传linux运行速度非常快,依赖的jar虽然体积比较大,数量多但是我们只需要第一次将其全部收集到一个公共目录即可,程序运行时加载这个目录即可。这样的缺点就是如果框架对依赖由特殊要求,那么就需要了解这个框架如何加载jar包,才能正确。
在使用spark集成es时候,我使用的是上面的第二种方法,下面看下如何使用,集成es的jar包如下:
这里需要解释一下依赖jar包如何在spark中提交,大多数时候我们直接使用spark-submit提交命令加上--jars libs/*jar即可,少数时候会出现另外一种情况,明明libs目录下有这个jar包,但是在运行spark任务的时候一直报这个jar的类 找不到,如果出现这种情况,就需要在每台hadoop或者spark的机器上创建一个本地的jar目录,然后把那个出现问题的jar,放在这里面,最后在使用下面的几个参数配置此jar,这样以来这种问题基本就能解决。
在使用spark和es集成的时候guava的包就出现了上述的第二种情况,所以我在下面使用了第二种加载方式,最后调试通过。
最后需要注意的是,如果跟hive集成的时候,还用到了yarn-cluster模式,那么提交任务的时候,必须把hive-site.xml也提交上去,否则会报找不到hive的表异常。
最终提交spark任务到yarn集群上的命令如下:
spark这个集成相关依赖时,还是比较简单的,大部分时候我们使用--jars都能非常轻松的解决依赖问题,少数时候需要在每一台spark机器上上传jar包,除此之外在使用maven打包的时候散仙推荐使用第二种,不要把依赖和核心代码耦合在一个jar里,最好能分离,这样核心代码的体积会非常小方便调试。