Apache Spark - 是否可以使用依赖注入机制

时间:2017-11-19 20:01:35

标签: scala apache-spark dependency-injection bigdata guice

是否有可能使用框架在Spark应用程序中启用/使用依赖注入?

是否可以使用 Guice ,例如?

如果有,是否有任何文件或如何做的样本?

我使用 Scala 作为实现语言, Spark 2.2 ,以及SBT作为构建工具。

目前,我的团队和我正在使用蛋糕模式 - 然而它变得非常冗长,我们更喜欢Guice。这更加直观,并且已经被其他团队成员所熟知。

3 个答案:

答案 0 :(得分:0)

我最近一直在努力解决同样的问题。我的大部分发现都是你会遇到序列化的问题。

我在这里找到了一个很好的解决方案: https://www.slideshare.net/databricks/dependency-injection-in-apache-spark-applications

答案 1 :(得分:0)

Spring Boot提供与各种系统的集成,包括Spark,Hadoop,YARN,Kafka,JDBC数据库。

例如,我有application.properties

spring.main.web-environment=false

appName=spring-spark
sparkHome=/Users/username/Applications/spark-2.2.1-bin-hadoop2.7
masterUri=local

这是一个Application类

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.SparkSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:application.properties")
public class ApplicationConfig {
    @Autowired
    private Environment env;

    @Value("${appName:Spark Example}")
    private String appName;

    @Value("${sparkHome}")
    private String sparkHome;

    @Value("${masterUri:local}")
    private String masterUri;


    @Bean
    public SparkConf sparkConf() {
        return new SparkConf()
                .setAppName(appName)
                .setSparkHome(sparkHome)
                .setMaster(masterUri);
    }

    @Bean
    public JavaSparkContext javaSparkContext() {
        return new JavaSparkContext(sparkConf());
    }

    @Bean
    public SparkSession sparkSession() {
        SparkSession.Builder sparkBuilder = SparkSession.builder()
                .appName(appName)
                .master(masterUri)
                .sparkContext(javaSparkContext().sc());

        return sparkBuilder.getOrCreate();
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}

taskContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--List out all tasks here-->

    <bean id="exampleSparkTask" class="com.example.spark.task.SampleSparkTask">
        <constructor-arg ref="sparkSession" />
    </bean>

</beans>

应用

@SpringBootApplication
@ImportResource("classpath:taskContext.xml")
public class App {

    public static void main(String[] args) {
        SpringApplication.run(App.class, args);

    }
}

实际上在这里为Spark运行Scala代码

@Order(1)
class SampleSparkTask(sparkSession: SparkSession) extends ApplicationRunner with Serializable {

  // for spark streaming
  @transient val ssc = new StreamingContext(sparkSession.sparkContext, Seconds(3))

  import sparkSession.implicits._

  @throws[Exception]
  override def run(args: ApplicationArguments): Unit = {
    // spark code here
  }
}

从那里,你可以定义一些@AutoWired的东西。

答案 2 :(得分:0)

当然可以!在Qwant.com上,我们将Spark 1.6与Google Guice 4结合使用,并在Hadoop YARN bin spark-submit上运行Java程序。

guice已经存在,如果您在Hadoop上(通过HDP组装jar)运行Spark,请注意您的compile和您实际使用的run版本。

 org.apache.spark:spark-yarn_2.10:1.6.3
|    +--- .....
|    +--- org.apache.hadoop:hadoop-yarn-server-web-proxy:2.2.0
|    |    +--- .....
|    |    +--- com.google.inject:guice:3.0 -> 4.2.2 (*)

Spark 1.6带来了Google Guice 3.0。

如果您想“强制”使用Google Guice的版本,则必须使用类似的方法(通过Gradle):

shadowJar {
    relocate 'com.google.inject', 'shadow.com.google.inject'
}

https://imperceptiblethoughts.com/shadow/configuration/relocation/