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

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

В hdfs-сайте у меня 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.replication установлено значение 1, fileStatus.block_replication установлено значение 3.

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

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

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

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

ИЗМЕНИТЬ

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

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

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

Ответ 2

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

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

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

Спасибо