由于一系列令人遗憾的事件,一个程序移动了块
/dataN/dfs/dn/current/BP-XXXXXXX/current/finalized/subdirN/subdirN/blk_NNNNNNNNNN
成
/tmp/blk_NNNNNNNNNN
我没有从程序中记录任何记录原始subdirN/subdirN/
目录的位置。
有没有办法根据fsimage文件,块文件本身或其他一些元数据来确定这个块应该在哪里?
我能够通过查找相应的* .meta文件来恢复一些块,但仍然存在一些漏洞。复制使我免于最糟糕的情况,但我仍然缺少5"任务关键"文件我想尝试恢复。
从hdfs fsck /
我可以知道丢失的块是什么,以及它们属于哪些HDFS文件,但是我不知道它们应该放在块池中的哪个位置。
hdfs fsck / -delete
不是解决方案。我不想删除任何内容,我想尽最大努力恢复文件,因为我有块。我只是不知道他们去哪了。
$ hdfs version
Hadoop 2.6.0-cdh5.4.4
答案 0 :(得分:3)
不确定是否可以手动执行恢复,但您可以尝试。
使用以下代码在DatanodeUtil.idToBlockDir(...)
中计算子目录:
int d1 = (int)((blockId >> 16) & 0xff);
int d2 = (int)((blockId >> 8) & 0xff);
String path = DataStorage.BLOCK_SUBDIR_PREFIX + d1 + SEP + DataStorage.BLOCK_SUBDIR_PREFIX + d2;
如果文件是手动移动的,fsimage可能仍然包含块id,使用hdfs oiv
命令将fsimage
转换为XML
并通过删除的文件名获取blockIds。
答案 1 :(得分:0)
以下是我最终要解决的问题。这并不适用于所有情况,但它在我的工作中有效。
我利用了输入文件分隔符将是"行输入记录分隔符"并且hadoop中的块可以与丢失的块连接。数据的顺序对我来说并不重要,只是所有的行都在那里。
我只是检索了文件的所有块(包括不再在hdfs中移动到新位置的块),将它们连接在一起。从HDFS中删除了该文件,并对受污染的文件进行了hdfs -put
以恢复内容。
不完美,但效果很好。这使我无需进行任何反向工程,也证明了恢复数据的最简单方法。
感谢您的帮助。我确定这里有适用于此问题的下一个人的有用信息。