Как добавить к файлу hdfs на очень маленьком кластере (3 узла или меньше)

#java #hadoop #hdfs

#java #hadoop #hdfs

Вопрос:

Я пытаюсь добавить к файлу в hdfs в кластере с одним узлом. Я также пробовал на кластере с 2 узлами, но получаю те же исключения.

В hdfs-site я dfs.replication установил значение 1. Если я установлю dfs.client.block.write.replace-datanode-on-failure.policy значение DEFAULT , я получу следующее исключение

 java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try. (Nodes: current=[10.10.37.16:50010], original=[10.10.37.16:50010]). The current failed datanode replacement policy is DEFAULT, and a client may configure this via 'dfs.client.block.write.replace-datanode-on-failure.policy' in its configuration.
  

Если я последую рекомендации в комментарии к конфигурации в hdfs-default.xml для чрезвычайно маленьких кластеров (3 узла или меньше) и заданного dfs.client.block.write.replace-datanode-on-failure.policy значения NEVER я получаю следующее исключение:

 org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.SafeModeException): Cannot append to file/user/hadoop/test. Name node is in safe mode.
The reported blocks 1277 has reached the threshold 1.0000 of total blocks 1277. The number of live datanodes 1 has reached the minimum number 0. In safe mode extension. Safe mode will be turned off automatically in 3 seconds.
  

Вот как я пытаюсь добавить:

 Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://MY-MACHINE:8020/user/hadoop");
conf.set("hadoop.job.ugi", "hadoop");

FileSystem fs = FileSystem.get(conf);
OutputStream out = fs.append(new Path("/user/hadoop/test"));

PrintWriter writer = new PrintWriter(out);
writer.print("hello world");
writer.close();
  

Есть ли что-то, что я делаю неправильно в коде?
может быть, в конфигурации чего-то не хватает?
Любая помощь будет оценена!

Редактировать

Даже если для этого dfs.replication установлено значение 1 , когда я проверяю статус файла через

 FileStatus[] status = fs.listStatus(new Path("/user/hadoop"));
  

Я обнаружил, что status[i].block_replication установлено значение 3 . Я не думаю, что это проблема, потому что, когда я изменил значение dfs.replication на 0 , я получил соответствующее исключение. Итак, очевидно, что он действительно подчиняется значению dfs.replication но на всякий случай, есть ли способ изменить block_replication значение для каждого файла?

Комментарии:

1. Я предполагаю, что для кластера с одним узлом репликация должна быть равна нулю, и каково значение для dfs.support.append?

2. @sambhavSharma Я пытался установить для него значение 0, но он также выдал исключение, что нет активных datanodes и dfs.support.append действительно имеет значение true

3. Да, репликация должна быть 1

4. @peeskillet Я думаю, что проблема в другом, здесь безопасный режим автоматически отключается через пару секунд, и я могу нормально работать с чем угодно, однако, если я попытаюсь добавить, он снова попадет в него.

Ответ №1:

Как я упоминал при редактировании. Даже если dfs.replication установлено значение 1 , fileStatus.block_replication для него установлено значение 3.

Возможное решение — запустить

 hadoop fs -setrep -w 1 -R /user/hadoop/
  

Который изменит коэффициент репликации для каждого файла рекурсивно в данном каталоге. Документацию по команде можно найти здесь.

Что нужно сделать сейчас, так это посмотреть, почему значение в hdfs-site.xml игнорируется. И как заставить значение 1 быть значением по умолчанию.

Редактировать

Оказывается, что dfs.replication свойство также должно быть установлено в Configuration экземпляре, в противном случае он запрашивает, чтобы коэффициент репликации для файла был по умолчанию, равный 3, независимо от значения, установленного в hdfs-site.xml

Добавление в код следующего оператора решит эту проблему.

 conf.set("dfs.replication", "1");
  

Комментарии:

1. Чтобы прояснить ситуацию для дальнейшего использования: решение для новых файлов — добавить conf.set(«dfs.replication», «1») в конфигурацию FileSystem.get. Для существующих файлов также необходим запуск hadoop fs -setrep -w 1 /user /hadoop / (-R игнорируется в текущих версиях).

Ответ №2:

Я также столкнулся с тем же исключением, которое вы опубликовали изначально, и я решил проблему благодаря вашим комментариям (установите dfs.replication равным 1).

Но я чего-то не понимаю, что произойдет, если у меня будет репликация? В таком случае разве невозможно добавить к файлу?

Я буду признателен за ваш ответ, и если у вас был опыт работы с ним.

Спасибо

Комментарии:

1. Когда у вас есть репликация, вы должны убедиться, что коэффициент репликации меньше или равен количеству ваших datanodes. Причина, по которой запись в первый раз завершается успешно, а добавление завершается неудачей, когда коэффициент репликации превышает количество узлов данных, заключается в том, что добавление является более строгим для обеспечения согласованности, тогда как запись в первый раз может допускать недостаточную репликацию. p.s. ваш ввод был бы более подходящим в качестве комментария, чем в качестве ответа