У меня есть 5 подчиненных кластеров Hadoop (с использованием CDH4) --- подчиненные устройства - это то место, где работают DataNode и TaskNode. Каждое ведомое устройство имеет 4 раздела, предназначенных для хранения HDFS. Одно из ведомых устройств требовало переустановки, что привело к потере одного из разделов HDFS. В этот момент HDFS жаловалась на пропущенные 35 КБ блоков.
Через несколько дней переустановка была завершена, и я вернул узел в Hadoop. HDFS остается в безопасном режиме, и новый сервер не регистрирует количество блоков, равное количеству других узлов. Например, под администратором DFS новый узел показывает, что он имеет 6 КБ блоков, в то время как другие узлы имеют около 400 КБ блоков.
В настоящее время журналы DataNode нового узла показывают, что он выполняет некоторую проверку (или копирование?) На различных блоках, некоторые из которых не работают как уже существующие. Я считаю, что HDFS просто реплицирует существующие данные на новый узел. Пример проверки:
2013-08-09 17:05:02,113 INFO org.apache.hadoop.hdfs.server.datanode.BlockPoolSliceScanner: Verification succeeded for BP-143510735-141.212.113.141-1343417513962:blk_6568189110100209829_1733272
Пример отказа:
2013-08-09 17:04:48,100 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: meez02.eecs.umich.edu:50010:DataXceiver error processing REPLACE_BLOCK operation src: /141.212.113.141:52192 dest: /141.212.113.65:50010
org.apache.hadoop.hdfs.server.datanode.ReplicaAlreadyExistsException: Block BP-143510735-141.212.113.141-1343417513962:blk_-4515068373845130948_756319 already exists in state FINALIZED and thus cannot be created.
at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.createTemporary(FsDatasetImpl.java:813)
at org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.FsDatasetImpl.createTemporary(FsDatasetImpl.java:92)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.<init>(BlockReceiver.java:155)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.replaceBlock(DataXceiver.java:846)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.opReplaceBlock(Receiver.java:137)
at org.apache.hadoop.hdfs.protocol.datatransfer.Receiver.processOp(Receiver.java:70)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:221)
at java.lang.Thread.run(Thread.java:679)
В DFS Admin я также вижу, что этот новый узел загружен на 61% (соответствует приблизительному использованию других узлов), хотя его количество блоков составляет около 2% от других узлов. Я предполагаю, что это просто старые данные, которые HDFS не распознает.
Я подозреваю, что произошло одно из нескольких: (a) HDFS отказалась от данных этого узла из-за устаревания; (б) при переустановке был изменен некоторый системный параметр, поэтому HDFS рассматривает его как совершенно новый узел (т.е. не существующий с данными); или (c) каким-то образом перепутались сопоставления дисков, что привело к изменению сопоставления разделов, и HDFS не смогла найти старые данные (хотя диски имеют метки, и я на 95% уверен, что мы правильно поняли).
Главный вопрос: Как я могу заставить HDFS повторно распознавать данные на этом диске?
Подвопрос 1: Если мое предположение об использовании данных нового узла верно - 61% использования - это фантомные данные - будет ли он когда-либо очищен HDFS, или мне нужно удалить это вручную?
Подвопрос 2: В настоящее время я не могу бежать listCorruptFileBlocks
для поиска недостающих блоков из-за того, что «очереди репликации не инициализированы». Есть идеи, как это исправить? Должен ли я ждать, пока новый узел перебалансируется (т.е. завершится этап проверки / копирования)?
Обновление 1: Я думал, что решил проблему, перезапустив свой NameNode. Это привело к тому, что количество блоков нового узла увеличилось примерно до того же уровня использования, что и другие узлы, и DFS изменила свое сообщение на:
Включен безопасный режим. Сообщенным блокам 629047 требуются дополнительные 8172 блока, чтобы достичь порогового значения 0,9990 от общего числа блоков 637856. Безопасный режим будет отключен автоматически.
Я оставил его в таком состоянии на несколько часов, надеясь, что он наконец выйдет из безопасного режима, но ничего не изменилось. Затем я вручную отключил безопасный режим, и сообщение DFS изменилось на «8800 блоков отсутствуют». На этом этапе я смог запустить hdfs fsk -list-corruptfileblocks
, чтобы увидеть большую часть файлов, в которых отсутствуют блоки.
Текущая оставшаяся проблема: как восстановить эти недостающие блоки ... (следует ли включить это в новый вопрос?)
У нас сегодня была похожая проблема. Один из наших узлов (из 3, с репликацией = 3) просто умер на нас, и после перезапуска мы начали видеть это в журналах затронутых узлов данных:
18/04/27 14:37:22 INFO datanode.DataNode: Receiving BP-1114663060-172.30.36.22-1516109725438:blk_1073743913_3089 src: /172.30.36.26:35300 dest: /172.30.36.25:50010
18/04/27 14:37:22 INFO datanode.DataNode: g500603svhcm:50010:DataXceiver error processing WRITE_BLOCK operation src: /172.30.36.26:35300 dst: /172.30.36.25:50010; org.apache.hadoop.hdfs.server.datanode.ReplicaAlreadyExistsException: Block BP-1114663060-172.30.36.22-1516109725438:blk_1073743913_3089 already exists in state FINALIZED and thus cannot be created.
Webui namenodes показывает, что datanode имеет только 92 блока (из 13400 остальных).
Исправлено, запустив отчет о полном блоке на datanode, который обновил данные namenode на нем:
hdfs dfsadmin -triggerBlockReport g500603svhcm:50020
Результат: на узле данных отсутствовала пара блоков, которые он с радостью принял и восстановил кластер.
В итоге мне пришлось удалить файлы с плохими блоками, которые после дальнейшего расследования, как я понял, имеют очень низкую репликацию (rep = 1, если я правильно помню).
Это сообщение SO содержит дополнительную информацию о поиске файлов с плохими блоками, используя что-то вроде:
hadoop fsck / | egrep -v '^\.+$' | grep -v eplica
Итак, чтобы ответить на мои вопросы:
dfsadmin
.