网上应该一搜就会有很多关于hdfs基本操作的文章和代码,但是在一些细节上,对于新手很重要的那些信息,都没有比较清楚地说明。对,就是对我这样的新手很重要的内容,找了好久找不到。所以,经过一些实践后,我就觉得很有必要把这些东西,新手真的需要的东西稍微记录一下。
为什么是远程
如果只是像网上多数文章里的情景,那么基本就一台机器上装套hadoop,然后也在同样的机器上去尝试,应该是一点问题都没有吧。不过我是没有尝试过了,毕竟对我来说,很难搞到一台带ui的linux机器给我装hadoop和ide去搞开发啊,基本就是windows。而且真正工作要用到hdfs的话,基本不可能就装在自己的机器吧,所以最终还是得要连接上远程的hdfs去操作的呢。那么一上来就这样不是更好么?
最简单的例子
乱七八糟的不多写了。首先上个最简单的例子,能够证明成功连上了远端的hdfs并读取其中数据的例子。
pom.xml
|
|
没错,就依赖这么点东西就够了。
HdfsDemo.java
|
|
稍微解释下:
- main方法开头两行,设置hdfs的远程调用地址。这很显然,总得告诉程序hdfs在哪里,然后才可能连过去啊。这个配置一般在hadoop的core-site.xml中可以看到。
- 然后就是使用这个配置,连接上hdfs了
- 然后把根目录的信息打印出来
使用idea debug的输出
|
|
看HdfsLocatedFileStatus开头的输出行,可见是可以查询远端hdfs的目录信息了。
slf4j和log4j的警告应该是我没有加入相关的依赖导致的,无视就好。
上传文件
用户权限问题
新手肯定会遇到这样的错误
|
|
看错误内容基本能够知道,就是用户权限的问题。跟linux类似,操作hadoop上的文件,需要相应的用户权限,前面下载没有出现问题,是因为other具有读权限。所以,只要用户权限具有对应文件的写权限,那应该就不会出现上面的错误了。
看到user=Administrator,应该就是使用了我当前windows的用户名了。我不可能又重新在windows上新建一个hadoop用户做开发吧,也不可能把hadoop上的文件权限又改一遍,那么怎么修改这个user呢,显然只能是配置了。通过看FileSystem.get的代码实现,会看到类似下面的代码:
|
|
只要在系统变量里设置好HADOOP_USER_NAME=hadoop,就可以使用hadoop的用户权限去操作hdfs的文件了。
使用腾讯云emr的问题
|
|
腾讯云的emr,默认是只有namenode放开外网访问,其他节点都只能私有网络访问,一开始没有注意这个问题,看到上传文件时出现上面的错误,想了想,才发现是有点问题的。
上传时,客户端会先从namenode获取datanode的地址,然后将文件传到datanode。hdfs是能做replication的,数量看具体的配置,datanode一般也会配置为多台,数量大于等于replication数量。看上面的错误,可以知道emr配置minReplication为1,datanode个数为3,上传一个test.txt文件,先尝试传到192.168.1.12:4001的datanode,但是连接失败,然后再尝试192.168.1.16:4001的datanode,同样失败,再尝试192.168.1.12:4001的datanode,还是失败,所有datanode都尝试完,成功个数小于minReplication,所以最后判断上传任务失败,抛出异常。
所以,要远程上传文件到hdfs,必须要确保客户端是可以连接到datanode的。
但是这种情况,就算datanode是允许外网访问的,新手也可能会遇到客户端也会连接不上datanode的问题。为什么呢,是因为一般hadoop各个节点之间是通过内网访问的,客户端从namenode获取的datanode地址也是内网的。怎么样让namenode给客户端返回datanode的外网地址呢?这个我暂时也找不到在哪里配置,但是有一种曲线救国的方法。就是设置客户端使用hostname去访问datanode,这样只要在本地hosts配置一下对应的外网ip就可以了。
|
|
完整例子
最后是一个简单的例子,包括了各种基本的文件和目录操作。
|
|