创建Hadoop FileSystem报`Provider org.apache.hadoop.fs.azure.NativeAzureFileSystem not a sub...

栏目: 编程工具 · 发布时间: 7年前

内容简介:为了验证一个线上问题,写了一个简单的Spark任务,在提交节点上听过报如下错误:错误的代码是这一段:

为了验证一个线上问题,写了一个简单的Spark任务,在提交节点上听过 spark-submit 命令提交任务,总是跑不起来。

报如下错误:

18/12/26 16:37:24 ERROR study.Application: error
java.util.ServiceConfigurationError: org.apache.hadoop.fs.FileSystem: Provider org.apache.hadoop.fs.azure.NativeAzureFileSystem not a subtype
        at java.util.ServiceLoader.fail(ServiceLoader.java:239)
        at java.util.ServiceLoader.access$300(ServiceLoader.java:185)
        at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:376)
        at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
        at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
        at org.apache.hadoop.fs.FileSystem.loadFileSystems(FileSystem.java:2400)
        at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2411)
        at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2428)
        at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:88)
        at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2467)
        at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2449)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:367)
        at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:166)
        at com.vivo.internet.ai.platform.study.FeatureOnlineService.syncByModelMeta(FeatureOnlineService.java:105)
        at com.vivo.internet.ai.platform.study.FeatureOnlineService.syncByModelName(FeatureOnlineService.java:80)
        at com.vivo.internet.ai.platform.study.Application.run(Application.java:34)
        at com.vivo.internet.ai.platform.study.Application.main(Application.java:18)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:744)
        at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:187)
        at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:212)
        at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:126)
        at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

错误的代码是这一段:

...
// 避免打jar包时SPI文件出现问题
Configuration cfg = new Configuration();
cfg.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");

String hiveSuccessPath = null;
try {
    // 一个特征集就是一张hive表,需要先检查特征数据是否写OK
    FileSystem fileSystem = FileSystem.get(URI.create("/hive/warehouse/dm_ads_db.db"), cfg);
    for (String featureSetPath : featureSetPathToKeys.keySet()) {
        // hdfs://footstone/hive/warehouse/dm_ads_db.db/feature_app_cn_base/dt=20180913/_SUCCESS
        hiveSuccessPath = featureSetPath + "/dt=" + dateForFeature + "/_SUCCESS";
        boolean success = fileSystem.exists(new Path(hiveSuccessPath));
        if (!success) {
            LOGGER.warn("hdfs file not exist:{}", hiveSuccessPath);
            throw new IllegalArgumentException("feature data is not ready:" + featureSetPath);
        }
    }
} catch (RuntimeException e) {
    throw e;
} catch (IOException e) {
    throw new RuntimeException("check path error:" + hiveSuccessPath, e);
}
...

就是这一句 FileSystem fileSystem = FileSystem.get(URI.create("/hive/warehouse/dm_ads_db.db"), cfg);

改成:

FileSystem fileSystem = FileSystem.get(URI.create("hdfs://footstone/hive/warehouse/dm_ads_db.db"), cfg);

或者

FileSystem fileSystem = FileSystem.get(cfg);

还是报一样的错误。

谷歌都没有任何结论。只能跟着源码看下去了。

Hadoop对文件系统进行了抽象,HDFS只是其中的一个实现。Java抽象类 org.apache.hadoop.fs.FileSystem 定义了Hadoop中一个文件系统的客户端接口,并且该抽象类允许自定义实现对应的文件系统,运行时通过 Java 的SPI机制加载相应的实现类。下面是常见的几个具体实现:

文件系统 URI schema Java实现(都在org.apache.hadoop包中) 描述
Local file fs.LocalFileSystem 使用客户端校验和的本地磁盘文件系统。使用RawLocalFileSystem表示无校验和的本地磁盘文件系统。
HDFS hdfs hdfs.DistributedFileSystem Hadoop的分布式文件系统。将HDFS设计成与MapReduce结合使用,可以实现高性能。
WebHDFS webhdfs Hdfs.web.WebHdfsFileSystem 基于HTTP的文件系统,提供对HDFS的认证读/写访问。
HAR har Hdfs.web.WebHdfsFileSystem WebHDFS的HTTPS版本
Secure WebHDFS swebhdfs fs.HarFileSystem 一个构建在其他文件系统之上用于文件存档的文件系统。Hadoop存档文件系统通常用于将HDFS中的多个文件打包成一个存档文件,以减少namenode内存的使用。使用hadoop的achive命令来创建HAR文件。
View viewfs viewfs.ViewFileSystem 针对其他Hadoop文件系统的客户端挂载表。通常用于为联邦namenode创建挂载点。
FTP ftp fs.ftp.FTPFileSystem 由FTP服务器支持的文件系统
S3 S3a fs.s3a.S3AFileSystem 由Amazon S3 支持的文件系统。替代老版本的s3n(S3)原生
Azure wasb fs.azure.NativeAzureFileSystem 由Microsoft Azure 支持的文件系统
Swift swift fs.swift.snative.SwiftNativeFileSystem 由OpenStack Swift 支持的文件系统

SPI通过 java.util.ServiceLoader 类加载 META-INF/services/ 目录下的ServiceProvider。于是解压打包的jar包(是一个大的uberjar),发现里面确实有 META-INF/services/org.apache.hadoop.fs.FileSystem 文件,打开一看,里面写了好几个实现类:

org.apache.hadoop.fs.LocalFileSystem
 org.apache.hadoop.fs.viewfs.ViewFileSystem
 org.apache.hadoop.fs.s3.S3FileSystem
 org.apache.hadoop.fs.s3native.NativeS3FileSystem
 org.apache.hadoop.fs.ftp.FTPFileSystem
 org.apache.hadoop.fs.HarFileSystem

但是呢,就没有 NativeAzureFileSystem 的声明,类路径也没有这个依赖。

而且报错的代码也很奇怪:

private static void loadFileSystems() {
  synchronized (FileSystem.class) {
    if (!FILE_SYSTEMS_LOADED) {
      ServiceLoader<FileSystem> serviceLoader = ServiceLoader.load(FileSystem.class);
      for (FileSystem fs : serviceLoader) {
        SERVICE_FILE_SYSTEMS.put(fs.getScheme(), fs.getClass());
      }
      FILE_SYSTEMS_LOADED = true;
    }
  }
}
private S nextService() {
    if (!hasNextService())
        throw new NoSuchElementException();
    String cn = nextName;
    nextName = null;
    Class<?> c = null;
    try {
        c = Class.forName(cn, false, loader);
    } catch (ClassNotFoundException x) {
        fail(service,
             "Provider " + cn + " not found");
    }
    if (!service.isAssignableFrom(c)) {
        fail(service,
             "Provider " + cn  + " not a subtype");
    }
    try {
        S p = service.cast(c.newInstance());
        providers.put(cn, p);
        return p;
    } catch (Throwable x) {
        fail(service,
             "Provider " + cn + " could not be instantiated",
             x);
    }
    throw new Error();          // This cannot happen
}

出错的这一段:

if (!service.isAssignableFrom(c)) {
      fail(service,
           "Provider " + cn  + " not a subtype");
}

service是 org.apache.hadoop.fs.FileSystem , cn是 org.apache.hadoop.fs.azure.NativeAzureFileSystemorg.apache.hadoop.fs.azure.NativeAzureFileSystem extends org.apache.hadoop.fs.FileSystem ,所以正常来说 isAssignableFrom 这个判断应该是pass才对的。

综合判断:

1、打出来的uberjar包 META-INF/services/org.apache.hadoop.fs.FileSystem 没有 org.apache.hadoop.fs.azure.NativeAzureFileSystem 的注册,也没有 org.apache.hadoop.fs.azure.NativeAzureFileSystem 的class文件,但是forName却成功了 => Spark运行时有这个SPI注册和依赖包。 2、isAssignableFrom应该成功却失败了 => NativeAzureFileSystem是由不同的classLoader加载的。

分析那么多,怎么解决呢?对比可以正常跑的uberjar包,发现人家压根就没有 META-INF/services/org.apache.hadoop.fs.FileSystem 这个文件,继续跟踪下去,发现人家压根就没有打包spark的依赖。也就是说确实 META-INF/services/org.apache.hadoop.fs.FileSystem 就是spark-core带进去的。而且集群运行时的spark-core引进来的依赖中 META-INF/services/org.apache.hadoop.fs.FileSystem 比hadoop官方注册的FileSystem Provider要多(我们线上用的是CDH版本)。 最后把spark的依赖改成provider就可以跑通了。

<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-core_${scala.version}</artifactId>
  <version>${spark.version}</version>
  <scope>provided</scope>
</dependency>

时间关系,我没有找一下 arthas 查看一下类加载信息。留给感兴趣的同学。


以上所述就是小编给大家介绍的《创建Hadoop FileSystem报`Provider org.apache.hadoop.fs.azure.NativeAzureFileSystem not a sub...》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Learning Python, 5th Edition

Learning Python, 5th Edition

Mark Lutz / O'Reilly Media / 2013-7-6 / USD 64.99

If you want to write efficient, high-quality code that's easily integrated with other languages and tools, this hands-on book will help you be productive with Python quickly. Learning Python, Fifth Ed......一起来看看 《Learning Python, 5th Edition》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具