【问题标题】:Apache Spark - Is it possible to use a Dependency Injection MechanismApache Spark - 是否可以使用依赖注入机制
【发布时间】:2018-05-03 01:06:29
【问题描述】:

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

例如,是否可以使用 Guice

如果有,是否有任何文档或示例说明如何操作?

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

目前,我的团队和我正在使用蛋糕模式 - 但是它变得非常冗长,我们更喜欢 Guice。这是更直观的东西,其他团队成员已经知道了。

【问题讨论】:

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


    【解决方案1】:

    我最近一直在努力解决同样的问题。我的大部分发现是您将面临序列化问题。

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

    【讨论】:

    • databricks 中的这个库在哪里?
    【解决方案2】:

    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
    

    这是一个应用程序类

    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 的东西。

    【讨论】:

    • 我在考虑 Guice...Spring 对 guice 有什么好处吗?
    • 正如在另一个答案中链接的那样,Guice 实际上并不是开箱即用的。该链接来自 Salesforce,他们 扩展 Guice,因为注入的对象无法序列化。我知道我公司的一些团队正在使用 Spark + SpringBoot,因此我可以假设它更适合此类事情。
    【解决方案3】:

    当然可以!在 Qwant.com,我们使用 Spark 1.6 和 Google Guice 4,在 Hadoop YARNspark-submit bin 上运行 java 程序。

    如果你在 Hadoop 上运行 Spark(通过 HDP 程序集 jar),guice 已经在这里,所以请注意你的版本 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/

    【讨论】:

    • 嗨@ThomasDecaux - 很高兴看到与 Guice 集成的完整示例。
    • full I cant :/ (因为 entreprise private) 但实际上没有陷阱(除了序列化问题,如果您在工作人员中使用 Guice 注入器,我真的不鼓励),只需确保您的代码正在使用您编译时使用的正确版本运行。
    猜你喜欢
    • 2022-05-07
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-22
    • 2020-02-02
    相关资源
    最近更新 更多