kafka往hdfs写入数据,如何指定hdfs的配置文件路径?

执行kafka往hdfs中自定义consumer时,显示hdfs文件系统系统出错
对应的代码29行是  hdfs = FileSystem.get(new HdfsConfiguration());
错误如下

1111.png


猜测是 HdfsConfiguration读取配置文件不成功
问题1. 冼老师曾经讲到 src/main/resources 中的hdfs-site.xml的配置文件一般不能打到客户端的包里,为什么?如何能打到客户端包里呢?
问题2. 如何指定classpath 指定hdfs-site.xml的路径呢?
我执行如下命令,也是出现上方的错误
 java  -classpath /root/software/test_kafka/src/main/resources -cp target/test_kafka-0.0.1-SNAPSHOT-jar-with-dependencies.jar cn.chinahadoop.kafka.hadoop_consumer.TestHadoopConsumer

wsxukai2013 - 奋斗中的蜗牛~

赞同来自:

两种方式: 1. java -cp target/kafka_hdfs-0.0.1-SNAPSHOT-jar-with-dependencies.jar:/etc/hadoop/conf cn.chinahadoop.kafka.hadoop_consumer.TestHadoopConsumer 2. java -cp target/kafka_hdfs-0.0.1-SNAPSHOT.jar:`/mnt/xkhadoop/hadoop-2.6.0-cdh5.4.0/bin/hadoop classpath` cn.chinahadoop.kafka.hadoop_consumer.TestHadoopConsumer    

fish - Hadooper

赞同来自: wsxukai2013

对于依赖于Hadoop编译出来的Jar包,要么使用"with-dependencies.jar"包,把hadoop相关的包都包含进来(像上一条回复一样)。 要么,可以采用如下方式执行: java -cp target/<xxxx_no_dependencies>.jar:`hadoop classpath` <main_class> <args>   java命令的cp中,出来编译出来的jar包,还使用hadoop classpath命令将hadoop相关的类目录全部加载进来。 你可以在命令行上自己执行一下hadoop classpath,看看都输出些什么。  

fish - Hadooper

赞同来自:

1. 我应该没有说过hdfs-site.xml不能达到客户端,其实打到客户端jar包中,就是想达到当任务执行时,可以从classpath中找到hdfs-site.xml的目的。注意,让应用从classpath中找到core-site.xml是目的,至于打到jar包中,或者在执行任务时定义classpath,都是手段。克隆出来的test_kafka项目中,使用mvn package编译出来的test_kafka-0.0.1-SNAPSHOT.jar中有hdfs-site.xml文件(jar -tf test_kafka-0.0.1-SNAPSHOT.jar | fgrep hdfs-site.xml确认一下)。 2. -classpath和-cp是一个意思,当有多个classpath时,使用java -cp <path1>:<path2> 方式。

fish - Hadooper

赞同来自:

你的问题并不是因为classpath中找不到hdfs-site.xml。 建议阅读下代码,看看hdfs中如何根据配置加载文件系统类的。   一些提示: FileSystem.java中,有如下代码:
  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;
      }
    }
  }
这里使用了Java util的ServiceLoader类加载系统支持的FileSystem,学习一下ServiceLoader的使用方法,可以知道它通过读取jar包中META-INF/services下的文件获取某个接口对应的实现类都有哪些。   将hadoop-hdfs.jar(cdh5.4.0中就是/usr/lib/hadoop-hdfs/hadoop-hdfs-2.6.0-cdh5.4.0.jar)解压开来,可以看到其中的文件META-INF/services/org.apache.hadoop.fs.FileSystem内容为:
org.apache.hadoop.hdfs.DistributedFileSystem
org.apache.hadoop.hdfs.web.HftpFileSystem
org.apache.hadoop.hdfs.web.HsftpFileSystem
org.apache.hadoop.hdfs.web.WebHdfsFileSystem
org.apache.hadoop.hdfs.web.SWebHdfsFileSystem
其中的第一行就是处理hdfs的类。 你可以对比一下自己编译出来的jar包中的这个org.apache.hadoop.fs.FileSystem,是不是缺了对DistributedFileSystem的定义?

fish - Hadooper

赞同来自:

尝试如下方式执行: java -cp target/kafka_hdfs-0.0.1-SNAPSHOT-jar-with-dependencies.jar:/etc/hadoop/conf cn.chinahadoop.kafka.hadoop_consumer.TestHadoopConsumer   -cp后面第一个文件是可执行主类所在的Jar包,冒号之后的第二个为你集群配置文件所在目录。

天热不下雨

赞同来自:

我解开了我编出来的jar包org.apache.hadoop.fs.FileSystem内容为 org.apache.hadoop.fs.LocalFileSystem org.apache.hadoop.fs.viewfs.ViewFileSystem org.apache.hadoop.fs.ftp.FTPFileSystem org.apache.hadoop.fs.HarFileSystem 确实缺少了org.apache.hadoop.hdfs.DistributedFileSystem  我应该如何在打包的时候将这行加进去呢   我在我的classpath是应该是能够知道我系统环境中的jar包的 [hadoop@hdfszz-1 ~]$ hadoop classpath /home/hadoop/app/hadoop-2.6.0-cdh5.4.5/etc/hadoop:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/common/lib/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/common/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/hdfs:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/hdfs/lib/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/hdfs/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/yarn/lib/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/yarn/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/mapreduce/lib/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/share/hadoop/mapreduce/*:/home/hadoop/app/hadoop-2.6.0-cdh5.4.5/contrib/capacity-scheduler/*.jar

天热不下雨

赞同来自:

我java -cp test_kafka-0.0.1-SNAPSHOT.jar:`hadoop classpath` cn.chinahadoop.kafka.consumer.HdfsConsumer 确实是可以正常执行了, 但是我还是觉得1个40M的jar包对我来说太大了, 希望老师能讲下如何在org.apache.hadoop.fs.FileSystem中加入 org.apache.hadoop.hdfs.DistributedFileSystem 和对jar包咱么这工工程删除一些依赖   41M     test_kafka-0.0.1-SNAPSHOT.jar 41M     test_kafka-0.0.1-SNAPSHOT-jar-with-dependencies.jar

fish - Hadooper

赞同来自:

首先,这个任务并非mapreduce任务,使用时并不会分发到集群所有节点中,为什么会有“40M的Jar包对我来说太大了”的说法。 另外,jar -tf xxx.jar看看这个jar包中有哪些类导致其这么大? 原因其实是将所有的依赖包都打进了jar包当中,打入jar包使得使用起来简单,用pom的以下定义实现了这个功能:
    <artifactId>maven-assembly-plugin</artifactId>
        <executions>
            <execution>
                <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
去掉这个包,所有的依赖将从jar包中被去除。   在jar包中不包含依赖class的时候,可以通过java -cp中将所有依赖的class都加进来的方式实现正常执行。比如:java -cp <app_jar>:<hadoop_classpath>:<kafka_classpath> main_class。 以上命令的<hadoop_classpath>,其实就是你执行hadoop classpath命令得到的结果。

要回复问题请先登录注册