DistCp同步HDFS至GCS遇问题:增量同步及快照Diff失效
HDFS到GCS的持续增量同步解决方案
问题描述
需要将本地HDFS数据持续同步至GCS:首次全量复制后,仅同步新增、更新的文件,同时删除GCS中本地已移除的文件。但遇到两个问题:
- 使用
distcp的-update参数时无效,会重复复制所有文件; - 尝试基于快照Diff的同步时失败,报错提示快照Diff仅支持DistributedFileSystem,而GCS不满足该要求。
尝试的命令及错误信息
基础增量同步命令
hadoop distcp --conf hdfs.conf -update -delete hdfs:///tmp/test_distcp gs://onpremhadoopfiles-123/
快照Diff同步命令
hadoop distcp --conf test.conf -update -diff test_distcp test_distcp_new hdfs:///tmp/test_distcp gs://xxxx-123/
快照Diff报错信息
Jul 29, 2022 9:56:31 AM com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystemBase configure WARNING: No working directory configured, using default: 'gs://onpremhadoopfiles-123/' 22/07/29 09:56:32 INFO tools.DistCp: Input Options: DistCpOptions{atomicCommit=false, syncFolder=true, deleteMissing=false, ignoreFailures=false, overwrite=false, append=false, useDiff=true, useRdiff=false, fromSnapshot=test_distcp, toSnapshot=test_distcp_new, skipCRC=false, blocking=true, numListstatusThreads=0, maxMaps=20, mapBandwidth=0.0, copyStrategy='uniformsize', preserveStatus=[BLOCKSIZE], atomicWorkPath=null, logPath=null, sourceFileListing=null, sourcePaths=[hdfs:/tmp/test_distcp], targetPath=gs://xxx-123/, filtersFile='null', blocksPerChunk=0, copyBufferSize=8192, verboseLog=false}, sourcePaths=[hdfs:/tmp/test_distcp], targetPathExists=true, preserveRawXattrsfalse 22/07/29 09:56:32 INFO client.RMProxy: Connecting to ResourceManager at xxx.xxx.com/xx.xx.xx.x:8032 22/07/29 09:56:33 ERROR tools.DistCp: Exception encountered java.lang.IllegalArgumentException: The FileSystems needs to be DistributedFileSystem for using snapshot-diff-based distcp at org.apache.hadoop.tools.DistCpSync.preSyncCheck(DistCpSync.java:98) at org.apache.hadoop.tools.DistCpSync.sync(DistCpSync.java:149) at org.apache.hadoop.tools.DistCp.prepareFileListing(DistCp.java:88) at org.apache.hadoop.tools.DistCp.createAndSubmitJob(DistCp.java:205) at org.apache.hadoop.tools.DistCp.execute(DistCp.java:182) at org.apache.hadoop.tools.DistCp.run(DistCp.java:153) at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:76) at org.apache.hadoop.tools.DistCp.main(DistCp.java:432)
可行解决方案
1. 修正DistCp参数实现增量同步
快照Diff方案不可行,因为其要求源和目标文件系统均为DistributedFileSystem,而GCS的GoogleHadoopFileSystem不属于该类型。可以调整DistCp参数实现增量同步:
hadoop distcp --conf hdfs.conf -sync -update -delete -skipcrccheck hdfs:///tmp/test_distcp gs://onpremhadoopfiles-123/
-sync:确保按文件夹结构同步,保持源和目标目录结构一致;-update:仅复制源中比目标新、或目标不存在的文件;-delete:删除目标中源已不存在的文件;-skipcrccheck:跳过CRC校验(GCS与HDFS的CRC算法存在差异,会导致DistCp误判文件需要更新,重复复制)。
2. 使用GCS原生传输服务
GCS自带的传输服务支持从HDFS进行增量同步,可基于文件的修改时间、大小判断是否需要同步,同时支持删除源已移除的文件。该服务可配置定时任务,实现持续自动同步,无需手动维护DistCp命令。
3. 自定义增量同步脚本
通过脚本实现源与目标的文件元数据对比:
- 遍历HDFS目录,记录所有文件的路径、修改时间、大小;
- 遍历GCS目标目录,获取对应元数据;
- 对比后,调用
hadoop distcp同步新增/更新的文件,调用hadoop fs -rm删除GCS中源已移除的文件; - 配合crontab或Oozie等调度工具,定时执行脚本实现持续同步。
内容的提问来源于stack exchange,提问作者Gaurang Shah
相关产品推荐
相关产品推荐

