在 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
RDD 的 map
函数中的代码在执行器上执行,而不是在驱动程序上执行。由于您在 map
中使用 Tika
,因此您需要将必要的 jars 复制到每个执行程序
您可以通过以下方式做到这一点:
首选解决方案,如#WoodChopper 的答案中所述,通过使用 --jars
或者如果您愿意,可以在 spak-defaults.conf 中添加以下行:
spark.executor.extraClassPath /path/to/tika/jar/tika-app-1.13.jar
我正在尝试 运行 一个使用 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
RDD 的 map
函数中的代码在执行器上执行,而不是在驱动程序上执行。由于您在 map
中使用 Tika
,因此您需要将必要的 jars 复制到每个执行程序
您可以通过以下方式做到这一点:
首选解决方案,如#WoodChopper 的答案中所述,通过使用
--jars
或者如果您愿意,可以在 spak-defaults.conf 中添加以下行:
spark.executor.extraClassPath /path/to/tika/jar/tika-app-1.13.jar