更为严重的是,有些时候主机甚至连读出来的数据是否是正确的这件事都不知道!当你发现自己的程序在其它机器上都很正常,但是在某台机器上总是神秘的崩溃的时候,你就要看看是不是那台机器的内存或者其他存储器出现问题了。
经历了大量痛苦的数据恢复工作之后,终于有人想出了一个主意:把数据的校验和放到别的地方,例如,引用这块数据的地方,并且将元数据保存多份。解决问题的方法有很多,一种是花更多的钱去买更好的硬件,而另一种,则是采用一些合理的技术手段来降低硬件发生问题时的影响──你不是不可靠吗?那么我检查你,确认你的数据是对的我才接受;你不是容易丢失数据吗?那我就多存几份,多到将真的丢失数据的概率降到可以接受的水平为止。
这种技巧是广大劳动人民在长期的科研实践中总结出来的,并且在历史上有着相当广泛的应用。例如,传统 BSD 系统中的伯克利快速文件系统(FFS,在现代 FreeBSD 版本中称为 UFS)会保存大量的关键元数据──超级块和柱面组映射表的副本,而这些副本在布局的时候,被保证不会放在磁盘的相同盘面、柱面或扇区上,从而保证了磁盘在失去一个盘面、被划伤一个柱面,或者被子弹击穿时,仍然会有可用的超级块副本存在,从而能够恢复部分数据。
不过,简单地把所有数据保存多份有时是不需要的。首先,它会影响写入性能,并损害写操作的原子性。其次,存储设备尽管越来越便宜,但它总归还是要钱的,你不会希望把钱均匀的用在不同的数据上面──举个例子,你花12个小时写了一些代码,这些代码丢了你会很心疼;但是你的程序有bug,运行5分钟之后吐了一个2GB的core文件,这个文件丢了,你可能会觉得无所谓,至少没有丢掉代码那样心疼。那么,假如有3份存储资源,我想多数人不会给两种文件各分配1.5份,因为很明显,给代码分配2份,而给core文件分配1份,使得代码数据能够有更高的冗余度,是比较合算的做法。
标签: