背景說明
項目中,爲了減少備份機房hdfs namenode內存壓力,將採集文件壓縮成tar,再傳輸至備份機房。在此期間,爲了確保跨集羣傳輸tar包的正確性,在生成tar文件時,需要生成crc32值。下面給出了java生成crc32值的代碼。
具體代碼實現
public interface IChunkSum extends Checksum
{
/**
* 獲取校驗值
* @return
*/
public String getStringValue();
}
public class Crc32ChunkSum implements IChunkSum
{
private CRC32 crc = new CRC32();
@Override
public void update(int b)
{
crc.update(b);
}
@Override
public void update(byte[] b, int off, int len)
{
crc.update(b, off, len);
}
@Override
public long getValue()
{
return crc.getValue();
}
@Override
public void reset()
{
crc.reset();
}
@Override
public String getStringValue()
{
return String.valueOf(getValue());
}
}
Crc32ChunkSum crc32ChunkSum = new Crc32ChunkSum();
try (TarArchiveOutputStream os = new TarArchiveOutputStream(new CheckedOutputStream(fs.create(new Path(fullTarName.toString())),crc32ChunkSum)))
{
InputStream is = null;
Path path = null;
for (FileInfo file : files)
{
path = new Path(file.getFullFilePath());
is = fs.open(new Path(file.getFullFilePath()));
TarArchiveEntry entry = new TarArchiveEntry(path.getName());
entry.setSize(file.getSize());
os.putArchiveEntry(entry);
IOUtils.copy(is, os);
os.closeArchiveEntry();
IOUtils.closeQuietly(is);
}
IOUtils.closeQuietly(os);
LOGGER.info("compress task run success,tar name is,{}",tarName);
Timestamp endDate = new Timestamp(System.currentTimeMillis());
ContextFactory.getContext().publishEvent(new CompressTaskEvent(tarName, dir, true, files, interfaceFileName,type,beginDate,endDate,crc32ChunkSum.getStringValue()));
}
壓縮模塊和下載模塊都是採用上述方式計算出的值,因此,如果傳輸沒有問題,起碼兩邊計算出的CRC32值是一致的。
疑惑,待查
1、網上推薦一個linux計算CRC值的命令—cksum,但是與上述代碼計算值不一樣~(待後續研究)
2、另外,hdfs dfs -checksum 命令,也可以計算出一個值,該值與上述代碼計算出來的也不一樣。