在 Apache Spark 中指定运行时依赖性

Specifying runtime dependency in Apache Spark

我正在尝试 运行 一个使用 Apache Tika 提取元数据的简单 Spark 应用程序。我用 Maven 创建了一个阴影 jar,应用程序 运行 没问题,但 Tika 解析器在 运行 时没有被使用。应用代码如下:

SparkConf sparkConf = new SparkConf();
JavaSparkContext sc = new JavaSparkContext(sparkConf);
if (args.length == 0 || args[0] == null) {
    return;
}
JavaPairRDD<String,PortableDataStream> files = sc.binaryFiles(args[0]);
List<Map<String,String>> results = files.map(new Function<Tuple2<String,PortableDataStream>, Map<String,String>>() {

    public Map<String,String> call(Tuple2<String, PortableDataStream> stringPortableDataStreamTuple2) throws Exception {
        DataInputStream des = stringPortableDataStreamTuple2._2.open();
        Tika tika = new Tika();
        Parser parser = new AutoDetectParser();
        BodyContentHandler handler = new BodyContentHandler(-1);
        String detected = tika.detect(des);
        Map<String,String> metadata = new HashMap();
        metadata.put("Type", detected);
        Metadata tikaMetadata = new Metadata();
        parser.parse(des, handler, tikaMetadata, new ParseContext());
        String[] names = tikaMetadata.names();
        for (String name : names) {
            metadata.put(name, tikaMetadata.get(name));
        }
        return metadata;
    }
}).collect();
for (Map<String,String> o : results) {
    for (String key : o.keySet()) {
        System.out.println(key + " : " + o.get(key));
    }
    System.out.println();
}
sc.stop();

输出总是类似于:

Type : image/jpeg
X-Parsed-By : org.apache.tika.parser.EmptyParser
Content-Type : application/octet-stream

这表示未使用 Tika 解析器。根据文档,我可以使用 spark.driver.extraClassPath 属性 配置 运行 时间依赖项,因此我修改了我的 $SPARK_HOME/conf/spark-defaults.conf.template 文件以具有:

spark.driver.extraClassPath /path/to/tika/jar/tika-app-1.13.jar

仍然无法正常工作,谁能帮我理解为什么?或者,是否有更好的方法来指定 运行 时间依赖性?我目前 运行 使用 Spark 1.6.1 仅在本地模式下通过 spark-submit 启动应用程序。

您可以在提交申请时使用 --jars 添加依赖 jar,

例如,

./bin/spark-submit \
  --class org.apache.spark.examples.SparkPi \
  --master yarn \
  --deploy-mode cluster \
  --executor-memory 20G \
  --num-executors 50 \
  --jars /path/to/tika/jar/tika-app-1.13.jar \
  /path/to/examples.jar

Ways of adding jars for execution

RDD 的 map 函数中的代码在执行器上执行,而不是在驱动程序上执行。由于您在 map 中使用 Tika,因此您需要将必要的 jars 复制到每个执行程序

您可以通过以下方式做到这一点:

  • 首选解决方案,如#WoodChopper 的答案中所述,通过使用 --jars

  • 或者如果您愿意,可以在 spak-defaults.conf 中添加以下行: spark.executor.extraClassPath /path/to/tika/jar/tika-app-1.13.jar