Hadoop :实践环节–故意造成数据块丢失

使用以下步骤连续杀死3个DataNode:

  1. 使用下列命令重启所有节点: $ start-all.sh

  2. 等到Hadoop的 “dfsadmin –report”命令显示有4个活跃节点:

  3. 把测试文件的新副本file1.new放到HDFS上: $ Hadoop fs -put file1.data file1.new

  4. 登录到集群中的3台主机并杀死每台主机上的DataNode进程。

  5. 等候10分钟,之后通过“dfsadmin”命令监视集群状态,直到集群状态如下所示: … Under replicated blocks: 123 Blocks with corrupt replicas: 0 Missing blocks: 33

Datanodes available: 1 (4 total, 3 dead) …

6.尝试从HDFS获取测试文件file1.new。 $ hadoop fs -get file1.new file1.new 11/12/04 16:18:05 INFO hdfs.DFSClient: No node available for block: blk_1691554429626293399_1003 file=/user/hadoop/file1.new 11/12/04 16:18:05 INFO hdfs.DFSClient: Could not obtain block blk_1691554429626293399_1003 from any node: java.io.IOException: No live nodes contain current block … get: Could not obtain block: blk_1691554429626293399_1003 file=/ user/hadoop/file1.new

  1. 使用start-all.sh 脚本重启所有死亡节点: $ start-all.sh

  2. 不断监视数据块状态: $ Hadoop dfsadmin -report | grep -i blocks Under replicated blockss: 69 Blocks with corrupt replicas: 0 Missing blocks: 35 $ Hadoop dfsadmin -report | grep -i blocks Under replicated blockss: 0 Blocks with corrupt replicas: 0 Missing blocks: 30

9.等到输出“Missing blocks: 0”,然后将测试文件file1.new拷贝到本地文件系统。 $ Hadoop fs -get file1.new file1.new

10.对获取的文件和原始文件进行MD5校验。

$ md5sum file1.* f1f30b26b40f8302150bc2a494c1961d file1.data f1f30b26b40f8302150bc2a494c1961d file1.new

原理分析

在重启被杀死进程之后,我们将测试文件拷贝到HDFS。严格意义上来讲,将测试文件拷贝到HDFS并不是必需的,我们也可以使用HDFS上的已有文件,但由于数据块分别存储在不同的主机,使用原始副本得出的结果更具代表性。

之后,我们按照前述步骤杀死3个DataNode,并等候HDFS的响应。与前面几个例子不一样的是,杀死这么多节点意味着某些数据块的所有副本都存储在被杀死的节点上。如我们所见,结果正是如此:仅剩1个节点的集群中有100多个数据块的副本数量低于复制因子(很明显,这些数据块仅剩1个副本),同时丢了33个数据块。

讨论数据块有点抽象,所以我们尝试获取测试文件。因为我们知道,由于缺少33个数据块造成测试文件不完整,就像是有33个洞。访问测试文件以失败告终,因为Hadoop无法找到缺失的数据块,而这些数据块在文件传送过程中是必需的。

接下来我们重新启动所有节点并再次尝试获取测试。这一次终于成功了,但我们采取了一个额外的验证措施,对获得的文件进行MD5校验,以确认它与原始文件完全相同——结果确实如此。

从本例可以看出,虽然节点故障可能会导致数据无法访问,但节点恢复之后,这个暂时性的数据缺失问题就不复存在。这点特别重要。

数据丢失的可能性

不要从本例中轻易得出Hadoop集群不会丢失数据这样的结论。一般来讲,很难出现数据丢失这样的情况,但灾难往往喜欢以错误的方式突然出现。

如上例所示,不少于复制因子的多个节点同时发生故障有可能导致数据块缺失。在由4台主机组成的示例集群中,3个死亡节点导致数据块缺失的可能较高。在由1000台主机组成的集群中,这个可能性相对较低但仍然存在。随着集群规模增大,故障率也随之增大;狭小的时间窗口内,3个节点同时发生故障的可能性越来越低。因此,它带来的影响也减小了,但多个节点接连发生故障总会带来数据丢失的风险。

另一个隐蔽的问题是反复故障或局部故障。例如,整个集群的不稳定电源会导致节点反复关机和重启。

Hadoop为了达成复制目标,可能会不断要求恢复运行的主机复制那些副本数量少于复制因子的数据块,电源问题导致的突然关机又会造成这些任务的中途失败。这样一系列事件也会提高潜在的数据丢失风险。

最后,不要忘了人为因素。即使将复制因子设置为集群中的主机数量,它保证了每个节点上都存储了一份数据副本,但在用户意外删除文件或目录时也无济于事。

结论是,由系统故障造成的数据丢失的可能性很小,但由无法避免的人工操作造成的数据丢失的可能性仍然存在。复制数据并不是一个完整的备份方案。用户必须充分认识到待处理数据的重要性以及本节讨论的数据丢失对我们造成的影响。

实际上,Hadoop集群中最严重的数据丢失是由NameNode和文件系统损坏 造成的。我们将在下一章比较详细地讨论这一话题。

数据块损坏

DataNode发出的状态报告中也包括了已损坏数据块的数量,这一点我们之前从未提及。DataNode将数据块初次写入HDFS时,同时将一个包含本数据块密码校验和的隐藏文件写入相同目录。默认情况下,DataNode为每512字节生成一个校验和。

每当客户端读取数据块时,同时也会读取校验和列表。客户端会计算已读取数据的校验和,并将其与获取的校验和列表进行对比。如果两个校验和不一致,该DataNode节点上的数据块被标记为损坏数据,客户端会获取另一个副本。得知数据块已损坏之后,NameNode会调度该DataNode基于现有的未损坏副本生成一个新的副本。

如果你认为不会发生数据损坏的情况,想一下出现故障的内存、硬盘、存储控制器,或单台主机的其他问题,它们都可能在初次写入数据块或读取数据块时导致数据块损坏。这些情况非常罕见。存储同一数据块副本的所有DataNode发生相同数据损坏的可能性微乎其微。但是,请记住,正如前面提到的,复制并不是一个完整的备份方案,如果用户需要确保数据100%可用,可能需要考虑在集群之外备份数据。

你可能感兴趣的:(Hadoop :实践环节–故意造成数据块丢失)