Как создать каталог в HDFS на Google Cloud Platform через Java API

Я запускаю кластер Hadoop на облачной платформе Google, используя облачное хранилище Google в качестве серверной части для постоянных данных. Я могу подключиться к главному узлу по ssh с удаленного компьютера и запустить команды Hadoop fs. В любом случае, когда я пытаюсь выполнить следующий код, я получаю ошибку тайм-аута.

Код

FileSystem hdfs =FileSystem.get(new URI("hdfs://mymasternodeip:8020"),new Configuration());
Path homeDir=hdfs.getHomeDirectory();
//Print the home directory
System.out.println("Home folder: " +homeDir); 

// Create a directory
Path workingDir=hdfs.getWorkingDirectory();
Path newFolderPath= new Path("/DemoFolder");

newFolderPath=Path.mergePaths(workingDir, newFolderPath);
if(hdfs.exists(newFolderPath))
    {
        hdfs.delete(newFolderPath, true); //Delete existing Directory
    }
//Create new Directory
hdfs.mkdirs(newFolderPath); 

При выполнении команды hdfs.exists() я получаю сообщение об ошибке тайм-аута.

Ошибка

org.apache.hadoop.net.ConnectTimeoutException: вызов с gl051-win7/192.xxx.1.xxx на 111.222.333.444.bc.googleusercontent.com:8020 не удался из-за исключения времени ожидания сокета: org.apache.hadoop. net.ConnectTimeoutException: тайм-аут 20000 миллисекунд при ожидании готовности канала к подключению. ch : java.nio.channels.SocketChannel[ожидание подключения remote=111.222.333.444.bc.googleusercontent.com/111.222.333.444:8020]

Известно ли вам о каких-либо ограничениях на использование API-интерфейсов Java Hadoop против Hadoop на Google Cloud Platform?

Спасибо!


person gl051    schedule 30.06.2015    source источник


Ответы (1)


Похоже, вы запускаете этот код на своем локальном компьютере и пытаетесь подключиться к виртуальной машине Google Compute Engine; по умолчанию GCE имеет строгие настройки брандмауэра, чтобы ваши внешние IP-адреса не подвергались воздействию произвольных входящих подключений. Если вы используете значения по умолчанию, ваш кластер Hadoop должен находиться в сети GCE «по умолчанию». Чтобы разрешить входящие TCP-подключения на порт 8020 и, возможно, на другие порты Hadoop, а также с вашего локального IP-адреса, чтобы это работало. Это будет выглядеть примерно так:

gcloud compute firewall-rules create allow-http \
    --description "Inbound HDFS." \
    --allow tcp:8020 \
    --format json \
    --source-ranges your.ip.address.here/32

Обратите внимание, что вы на самом деле хотите избежать открытия 0.0.0.0/0 исходного диапазона, поскольку Hadoop не выполняет аутентификацию или авторизацию для этих входящих запросов. Вы захотите ограничить его, насколько это возможно, только входящим IP-адресом, с которого вы планируете дозваниваться. Возможно, вам потребуется также открыть пару других портов, в зависимости от того, какие функции вы используете для подключения к Hadoop.

Более общая рекомендация заключается в том, что везде, где это возможно, вы должны пытаться запускать свой код на самом кластере Hadoop; в этом случае вы будете использовать само имя главного хоста в качестве авторитета HDFS, а не внешний IP-адрес:

hdfs://<master hostname>/foo/bar

Таким образом, вы можете ограничить доступ к порту только SSH-портом 22, где входящий трафик должным образом блокируется демоном SSH, и тогда вашему коду не придется беспокоиться о том, какие порты открыты, или даже об IP-адресах в все.

person Dennis Huo    schedule 30.06.2015
comment
Привет, Деннис, открытие порта сработало для меня, но, как вы уже указали, может возникнуть необходимость открыть и другие порты, в частности, если я хочу загрузить в HDFS некоторые файлы данных с моего локального компьютера, это мой последний цель. Я думаю, вы правы, у меня должен быть код Java, работающий на главном узле, чтобы избежать воздействия слишком большого количества портов на входящий трафик, но как лучше всего отправить на главный узел исходные файлы данных (программно)? Спасибо! - person gl051; 01.07.2015
comment
Как правило, вы можете либо использовать файлы-копии вычислений gcloud, либо можно сначала разместить файлы в Google Cloud Storage, используя gsutil cp <local file> gs://<your bucket>/<your GCS location>, а затем SSH в мастер и gsutil cp gs://<your bucket>/<your GCS location> <master local file>. Если вы говорите об объемных данных, вы также можете сначала загрузить их в Google Cloud Storage, а затем в мастер-ноде сделать hadoop fs -cp gs://your-bucket/your-location/data hdfs://<master-hostname>/<hdfs-location>. - person Dennis Huo; 01.07.2015
comment
Если данных много, вы даже можете использовать hadoop distcp, чтобы затем перейти с GCS на HDFS. В качестве альтернативы рассмотрите возможность чтения файлов из GCS непосредственно в ваших заданиях Hadoop; везде, где вы бы использовали hdfs://, просто используйте вместо этого gs://bucket/location. - person Dennis Huo; 01.07.2015