前言
hadoop比较适合做离线处理,这个是众所周知的,而且hdfs为了保证数据的一致性,每次写文件时,针对数据的io.bytes.per.checksum字节,都会创建一个单独的校验和。默认值为512字节,因为crc-32校验是4字节,存储开销小于1%。而客户端读取数据时,默认会验证数据的crc校验和。除此之外,每个数据节点还会在后台线程运行一个数据块检测程序,定期检查存储在数据节点上的所有块。当块和对应的crc校验匹配不上,由于hdfs存储着块的副本,它可以复制正确的副本替换出错的副本。
crc校验的性能损耗
可以想到,hdfs都是存储大文件的,每512字节就做一个crc校验,客户端在读写文件都要做这个校验,这个对hdfs的性能消耗是比较大的,crc最开始是采用jni调用,但是jni调用都要做上下文切换,加上每512字节就做一次crc校验,所以导致jvm切换很频繁,后来修改为pure java的crc校验,性能还提高了下,如果是几百兆就做一个crc校验,那么jni调用导致的上下文切换少些,那么jni就还有优势,但是在hadoop这个应用场景明显不合适。
后来淘宝的针对hadoop的crc场景,定制了jvm,将crc指令优化为调用硬件指令,性能测试报告证明提高了hdfs性能的20%-30%。
hadoop为什么要设计crc校验
既然crc校验对hdfs有这么大的性能损耗,那么hadoop还为什么要用crc校验呢,hadoop设计的应用场景就是离线数据的分布式计算,所以这些数据会保存很久,保存一个月,半年,一年,十年等。而数据保存这么久,那么物理存储介质由于中位衰减,会造成数据损坏,这对一个大文件来说,很容易导致一个块由于时间关系,硬盘错位,最终导致整个文件都是错误的,这对离线处理来说是不可以接受的,所以我想,hadoop就是为了离线处理的应用场景,才设计出crc校验。如果hadoop是做实时处理的,crc校验就没有必要了,毕竟数据不会放多久。
总结
hadoop里很多细节背后都有着它的设计思想,学习hadoop的过程中,我们不止要学会用,了解其实现,看其源码,更要了解整个hadoop的核心设计思想。