Bạn có chắc chắn muốn xóa bài viết này không ?
Bạn có chắc chắn muốn xóa bình luận này không ?
Checksum exception khi hadoop distcp
Mình phải chuyển dữ liệu giữa 2 hadoop cluster. Một cluster chạy Cloudera Hadoop 4 (CDH4.3), một cluster chạy Cloudera Hadoop 5 (CDH5.3.3). Trong quá trình distcp, chương trình ném rất nhiều exception ra log và tự động kết thúc (do nhiều lỗi quá).
Nội dung exception như sau:
15/04/21 19:47:48 INFO mapreduce.Job: map 15% reduce 0%
15/04/21 19:48:15 INFO mapreduce.Job: Task Id : attempt_1429591146207_0018_m_000003_1, Status : FAILED
Error: java.io.IOException: File copy failed: webhdfs://oldcluster:50070/Data/part-r-00000.bz2 --> hdfs://newcluster:8020/Data/part-r-00000.bz2
at org.apache.hadoop.tools.mapred.CopyMapper.copyFileWithRetry(CopyMapper.java:284)
at org.apache.hadoop.tools.mapred.CopyMapper.map(CopyMapper.java:252)
at org.apache.hadoop.tools.mapred.CopyMapper.map(CopyMapper.java:50)
at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145)
at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:784)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:168)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1642)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:163)
Caused by: java.io.IOException: Couldn't run retriable-command: Copying webhdfs://oldcluster:50070/Data/part-r-00000.bz2 to hdfs://newcluster:8020/Data/part-r-00000.bz2
at org.apache.hadoop.tools.util.RetriableCommand.execute(RetriableCommand.java:101)
at org.apache.hadoop.tools.mapred.CopyMapper.copyFileWithRetry(CopyMapper.java:280)
... 10 more
Caused by: java.io.IOException: Check-sum mismatch between webhdfs://oldcluster:50070/Data/part-r-00000.bz2 and hdfs://newcluster:8020/Data/.distcp.tmp.attempt_1429591146207_0018_m_000003_1.
at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.compareCheckSums(RetriableFileCopyCommand.java:211)
at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doCopy(RetriableFileCopyCommand.java:131)
at org.apache.hadoop.tools.mapred.RetriableFileCopyCommand.doExecute(RetriableFileCopyCommand.java:100)
at org.apache.hadoop.tools.util.RetriableCommand.execute(RetriableCommand.java:87)
... 11 more
Mình thử tính checksum của 2 file thì phát hiện ra:
$ hdfs dfs -checksum webhdfs://oldcluster:50070/Data/part-m-00003.lzo
webhdfs://oldcluster:50070/Data/part-m-00003.lzo MD5-of-0MD5-of-512CRC32 0000020000000000000000001c4f9532307c66aaffead00581c2c1e4
Thuật toán checksum ở cluster cũ là MD5-of-0MD5-of-512CRC32
CDH cũ hơn 4.3 dùng CRC32, CDH5 trở đi dùng CRC32C. Khi một block dữ liệu được ghi vào CDH5, giá trị checksum sẽ được tính và đưa vào thuộc tính của file. Giá trị này sẽ được đem so sánh với giá trị checksum của file ở cluster CDH4.3. Do thuật toán tính checksum của 2 phiên bản CDH khác nhau, nên giá trị này khác nhau, dẫn đến lỗi trên.
Cách giải quyết cho vấn đề exception này là thêm cờ -Ddfs.checksum.type=CRC32
lúc distcp, ép cách tính checksum luôn dùng thuật toán CRC32 để kiểm tra







