Hadoop-cos-DistChecker 是一个在使用hadoop distcp
命令从HDFS迁移数据到COS上后,用于校验迁移目录完整性的工具。基于MapReduce的并行能力,可以快速地进行迁移源目录和目的目录的校验比对。
-
Hadooop MapReduce的运行环境
NOTE:如果是自建Hadoop集群,则hadoop-cos依赖需要选择最新版本(GitHub Tag为5.8.2以上)才能支持CRC64校验码的获取。如果是使用腾讯云EMR套件,则2020年5月8日后创建的集群都包含该Hadoop-cos版本。否则,需要提工单处理。
由于Hadoop-cos-distchecker需要获取Hadoop-cos(CosN文件系统)中的文件CRC64校验值,因此,在运行该工具以前,需要将配置项fs.cosn.crc64.checksum.enabled
置为true以支持获取Hadoop-cos文件的CRC64校验和,待工具运行完成后,再将该选项置回false以关闭CRC64校验和的获取。
注意: 由于Hadoop-COS支持的CRC64校验和与HDFS文件系统的CRC32C校验和无法兼容,因此在使用完该工具以后,务必将上述配置项恢复为关闭状态,否则可能会导致Hadoop-cos在某些调用文件系统getFileChecksum
接口的场景下运行失败。
源文件列表是用户使用hadoop fs -ls -R hdfs://host:port/{source_dir} | awk '{print $8}' > check_list.txt
导出待检查的子目录和文件列表。示例格式如下:
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_0
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_1
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_0
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_1
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/_SUCCESS
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/part-00000
源文件列表所在的目录,这个目录通常也是distcp
命令进行目录级别迁移时的源路径。例如,hadoop distcp hdfs://host:port/source_dir cosn://bucket-appid/dest_dir
,则hdfs://host:port/source_dir
为源目录。
这个路径也是源文件路径列表中公共父目录,例如:上述的源文件列表的公共父目录就是:/benchmarks
待比较目的目录。
目的路径:由目的目录的绝对路径${TARGET_WORK_DIR_PATH}加上源文件的相对路径${SOURCE_FILE_RELATIVE_PATH}拼接得到,即${TARGET_WORK_DIR_PATH}/${SOURCE_FILE_RELATIVE_PATH}。
源文件的相对路径${SOURCE_FILE_RELATIVE_PATH}则是由源文件的绝对路径去除源目录后得到。
hadoop-cos-distchecker是一个MapReduce作业程序,按照MapReduce作业的提交流程运行即可:
hadoop jar hadoop-cos-distchecker-2.8.5-1.0-SNAPSHOT.jar com.qcloud.cos.hadoop.distchecker.App <源文件列表的绝对路径> <源目录的绝对路径表示> <目的目录的绝对路径表示> [Hadoop 可选参数]
下面以校验 hdfs://10.0.0.3:9000/benchmarks
和cosn://hdfs-test-1250000000/benchmarks
为例,介绍工具的使用步骤。
首先,执行hadoop fs -ls -R hdfs://10.0.0.3:9000/benchmarks | awk '{print $8}' > check_list.txt
,将待检查源路径导出到一个check_list.txt的文件中,这个文件里面保存的就是源文件路径列表了:
然后,将check_list.txt放到HDFS中:hadoop fs -put check_list.txt hdfs://10.0.0.3:9000/
;
最后,执行Hadoop-cos-DistChecker,将hdfs://10.0.0.3:9000/benchmarks://hdfs-test-1250000000/benchmarks进行对比,然后输出结果保存到cosn://hdfs-test-1250000000/check_result路径下,命令格式如下:
hadoop jar hadoop-cos-distchecker-2.8.5-1.0-SNAPSHOT.jar com.qcloud.cos.hadoop.distchecker.App hdfs://10.0.0.3:9000/check_list.txt hdfs://10.0.0.3:9000/benchmarks cosn://hdfs-test-1250000000/benchmarks cosn://hdfs-test-1250000000/check_result
distchecker会读取源文件列表和源目录执行MapReduce作业,进行分布式地检查,最后的检查报告会输出到cosn:///hdfs-test-1250000000/check_result
路径下。
检查报告如下:
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO hdfs://10.0.0.3:9000/benchmarks/TestDFSIO,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO,None,None,None,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_control,None,None,None,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_0 hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_0,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_control/in_file_test_io_0,CRC64,1566310986176587838,1566310986176587838,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_1 hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_control/in_file_test_io_1,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_control/in_file_test_io_1,CRC64,-6584441696534676125,-6584441696534676125,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_data,None,None,None,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_0 hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_0,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_data/test_io_0,CRC64,3534425600523290380,3534425600523290380,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_1 hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_data/test_io_1,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_data/test_io_1,CRC64,3534425600523290380,3534425600523290380,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_write,None,None,None,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/_SUCCESS hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/_SUCCESS,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_write/_SUCCESS,CRC64,0,0,SUCCESS,'The source file and the target file are the same.'
hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/part-00000 hdfs://10.0.0.3:9000/benchmarks/TestDFSIO/io_write/part-00000,cosn://hdfs-test-1252681929/benchmarks/TestDFSIO/io_write/part-00000,CRC64,-4804567387993776854,-4804567387993776854,SUCCESS,'The source file and the target file are the same.'
检查报告是以如下格式展示:
check_list.txt中的源文件路径 源文件绝对路径,目的文件绝对路径,Checksum算法,源文件的checksum值,目的文件的checksum值,检查结果,检查结果描述
其中检查结果分为以下7种:
- SUCCESS:表示源文件和目的文件都存在,且一致;
- MISMATCH:表示源文件和目的文件都存在,但不一致;
- UNCONFIRM:无法确认源文件和目的文件是否一致,这种状态主要是由于COS上的文件可能是CRC64校验码特性上线前就存在的文件,无法获取到其CRC64的校验值
- UNCHECKED:未检查。这种状态主要是由于源文件无法读取或无法源文件的checksum值
- SOURCE_FILE_MISSING:源文件不存在
- TARGET_FILE_MISSING:目的文件不存在
- TARGET_FILESYSTEM_ERROR:目的文件系统不是CosN文件系统;
由于工具默认会使用输入的源文件列表路径作为InputPath,因此,若这个文件长度未达到map的split size阈值,则只会启动一个map做源路径的顺序校验。此时,若需要利用MapReduce的并行能力,可以适当调整MapReduce的mapreduce.input.fileinputformat.split.minsize
和 mapreduce.input.fileinputformat.split.maxsize
两个运行参数,使得源文件路径列表能够被切分成多片。
1.为什么检查报告的CRC64值出现负数?
因为CRC64值,有可能是20位的值,此时已超过Java long型的表示范围,但是其底层字节是一致的,而打印long型时,会出现负数表示;