0%

Hadoop杂记

本文主要包括:

  • hdfs的url在什么情况下指定ip:port

hdfs的url在什么情况下指定ip:port

我们在使用hdfs的时候,一般情况下都是不指定ip:port的,原因是,在hadoop的core-site.xml里,我们配置了如下的参数

<property>
  <name>fs.defaultFS</name>
  <value>hdfs://golden-02:9000</value>
</property>

在我们指定hdfs的路径的时候,hadoop会自动代入golden-02:9000,例如:

hadoop fs -ls /flink/checkpoint/cdc

这时候我们不需要指定hdfs://golden-02:9000/flink/checkpoint/cdc也能访问

但是,如果不使用hadoop,例如使用flink访问hdfs上的文件,那么,hdfs://就是必须要添加的了,这里有2中指定方式:

env.getCheckpointConfig().setCheckpointStorage("hdfs://golden-02:9000/flink/checkpoint/cdc/gjc_test_Mysql2Kakfa");
env.getCheckpointConfig().setCheckpointStorage("hdfs:///flink/checkpoint/cdc/gjc_test_Mysql2Kakfa");

可以指定以hdfs://golden-02:9000开头,也就是我们fs.defaultFS里配置的内容
也可以直接以hdfs:///开头,注意,这里是3个/,这两个都是一样的,因为flink程序会加载hadoop相关的配置的
这里推荐使用hdfs:///,因为namenode有可能会切换standby,切换了standby不知道还能不能访问到
如果不知道fs.defaultFS里的配置在哪里找,可以直接打开hive客户端,执行如下语句

hive> set fs.defaultFS;
22/03/31 15:36:26 INFO conf.HiveConf: Using the default value passed in for log id: 488dc8a0-b332-4854-b2a1-585b69a15bf6
fs.defaultFS=hdfs://digiwin-hdfs2

Exception in thread “main” org.apache.hadoop.fs.UnsupportedFileSystemException: No FileSystem for scheme “hdfs”

问题详情: 在IDEA可以正常读写HDFS,但是打成jar包,就报以上错误
解决方案:
在设置hadoop配置的时候,添加以下代码

conf.set("fs.defaultFS", Constants.webHDFSConf.get(env));
//主要是下面2个
conf.set("fs.hdfs.impl",org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
conf.set("fs.file.impl",org.apache.hadoop.fs.LocalFileSystem.class.getName());

网上说,还需要在pom里添加shade插件设置

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>

            <configuration>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
                <shadedArtifactAttached>true</shadedArtifactAttached>
                <shadedClassifierName>allinone</shadedClassifierName>
                <artifactSet>
                    <includes>
                        <include>*:*</include>
                    </includes>
                </artifactSet>
                <transformers>
                    <transformer
                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>reference.conf</resource>
                    </transformer>
                    <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                    </transformer>
                    <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

经过实际测试,不加这个配置也可以成功,主要是是conf要设置fs.hdfs.impl
如果使用webhdfs,可以做以下配置:

conf.set("fs.defaultFS", "webhdfs://172.16.2.204:14000");
conf.set("fs.webhdfs.impl",org.apache.hadoop.hdfs.web.WebHdfsFileSystem.class.getName());

采用传统的hdfs协议写数据,需要在内网或者把datanode/namenode所有节点对外网开放,否则数据写不进去。
因为传统的hdfs协议,client发送请求给namenode,namenode会分配datanode来接受数据,这时候client是与datanode直接通信的。单纯开一个namenode外网是不够的
webhdfs就相当于使用http协议,在hdfs协议之间做了一层转换,先把数据交给webhdfs,然后webhdfs再区调用hdfs写数据,这样就避免了需要把整个集群的外网都开放,保证集群安全
但是,webhdfs的性能没有直接使用hdfs协议的性能好,并且,存在单点故障。