hadoop集群之间的hdfs文件拷贝

一、背景

部门有个需求,在网络互通的状况下,把现有的hadoop集群(未作Kerberos认证,集群名为:bd-stg-hadoop)的一些hdfs文件拷贝到新的hadoop集群(作了Kerberos认证,集群名为zp-tt-hadoop)html

若是是两个都没有作安全认证的集群互传文件,使用distcp能够很快实现。经过查阅资料,在cdh的官网上居然有这么神奇的一个参数能够解决这么一个奇葩的需求。传送门:http://www.cloudera.com/documentation/enterprise/5-5-x/topics/cdh_admin_distcp_secure_insecure.htmljava

二、实现

2.1 Copying Data between two Insecure cluster

两个都没有作安全认证的集群,一般方法以下:node

$ hadoop distcp hdfs://nn1:8020/foo/bar hdfs://nn2:8020/bar/foo

也能够经过webhdfs的方式:web

$ hadoop distcp webhdfs://nn1:8020/foo/bar  webhdfs://nn2:8020/bar/foo

对于不一样Hadoop版本间的拷贝,用户应该使用HftpFileSystem。 这是一个只读文件系统,因此DistCp必须运行在目标端集群上。 源的格式是 hftp://<dfs.http.address>/<path> (默认状况dfs.http.address是 <namenode>:50070)。apache

distcp的一些参数以下:跨域

-i:忽略失败(不建议开启)
-log <logdir>:记录日志到 <logdir>
-m <num_maps>:同时拷贝的最大数目(指定了拷贝数据时map的数目。请注意并非map数越多吞吐量越大。)
-overwrite:覆盖目标(若是一个map失败而且没有使用-i选项,不单单那些拷贝失败的文件,这个分块任务中的全部文件都会被从新拷贝。 就像下面提到的,它会改变生成目标路径的语义,因此 用户要当心使用这个选项。)
-update:若是源和目标的大小不同则进行覆盖
-f <urilist_uri>:使用<urilist_uri> 做为源文件列表

2.2 Copying Data between a Secure and an Insecure

在secure-cluster上的core-site.xml配置文件中添加:安全

<property> 
  <name>ipc.client.fallback-to-simple-auth-allowed</name>
  <value>true</value> 
</property>

而后在secure-cluster执行以下命令:bash

distcp webhdfs://insecureCluster webhdfs://secureCluster 
distcp webhdfs://secureCluster webhdfs://insecureCluster

在我实际操做过程当中,两个集群都有作ha,使用上面的命令会报错:网络

16/09/27 14:47:52 ERROR tools.DistCp: Exception encountered 
java.lang.IllegalArgumentException: java.net.UnknownHostException: bd-stg-hadoop
	at org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:374)
	at org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:392)
	at org.apache.hadoop.hdfs.web.WebHdfsFileSystem.initialize(WebHdfsFileSystem.java:167)
	at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2643)
	at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:93)
	at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2680)
	at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2662)
	at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:379)
	at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
	at org.apache.hadoop.tools.GlobbedCopyListing.doBuildListing(GlobbedCopyListing.java:76)
	at org.apache.hadoop.tools.CopyListing.buildListing(CopyListing.java:86)
	at org.apache.hadoop.tools.DistCp.createInputFileListing(DistCp.java:365)
	at org.apache.hadoop.tools.DistCp.execute(DistCp.java:171)
	at org.apache.hadoop.tools.DistCp.run(DistCp.java:122)
	at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
	at org.apache.hadoop.tools.DistCp.main(DistCp.java:429)
Caused by: java.net.UnknownHostException: bd-stg-hadoop

解决以下:session

把bd-stg-hadoop集群名字改为了active-namenode的host再进行操做,以下:

$ hadoop distcp webhdfs://bd-stg-namenode-138/tmp/hivebackup/app/app_stg_session webhdfs://zp-tt-hadoop:8020/tmp/hivebackup/app/app_stg_session

成功执行后, 能够发现原理就是启动一个只有map的MapReduce做业来实现两个集群间的数据复制。

2.3 Copying Data between two Secure cluster

这种状况相对有些复杂了,须要Kerberos作跨域的配置。本文暂不研究讨论。

相关文章
相关标签/搜索