Вы были очень близки к этому, когда нашли spring.yarn.client.launchcontext.arguments
и spring.yarn.appmaster.launchcontext.arguments
. У нас нет настроек, которые автоматически передавали бы все аргументы командной строки от клиента в мастер приложений, который затем передал бы их в контекст запуска контейнера. Не уверен, что мы вообще хотим это делать, потому что вы наверняка хотите контролировать то, что происходит с контекстом запуска контейнера YARN. Пользователь, использующий клиент, потенциально может передавать мошеннические аргументы по пищевой цепочке.
Сказав это, давайте посмотрим, что мы можем сделать с нашим Простым руководством по применению YARN для одного проекта.
Нам по-прежнему нужно использовать эти аргументы контекста запуска, чтобы определить параметры нашей командной строки, чтобы в основном сопоставить, как вещи передаются от клиента в мастер приложений в контейнер.
Что я добавил в application.yml:
spring:
yarn:
client:
launchcontext:
arguments:
--my.appmaster.arg1: ${my.client.arg1:notset1}
appmaster:
launchcontext:
arguments:
--my.container.arg1: ${my.appmaster.arg1:notset2}
Изменено HelloPojo
в классе Application
:
@YarnComponent
@Profile("container")
public static class HelloPojo {
private static final Log log = LogFactory.getLog(HelloPojo.class);
@Autowired
private Configuration configuration;
@Value("${my.container.arg1}")
private String arg1;
@OnContainerStart
public void onStart() throws Exception {
log.info("Hello from HelloPojo");
log.info("Container arg1 value is " + arg1);
log.info("About to list from hdfs root content");
FsShell shell = new FsShell(configuration);
for (FileStatus s : shell.ls(false, "/")) {
log.info(s);
}
shell.close();
}
}
Обратите внимание, как я добавил arg1
и использовал @Value
, чтобы сопоставить его с my.container.arg1
. Мы можем использовать либо @ConfigurationProperties
, либо @Value
, которые являются обычными функциями Spring и Spring Boot. Дополнительные сведения см. в справочных документах по Boot как их использовать.
Затем вы можете изменить модульный тест AppIT
:
ApplicationInfo info = submitApplicationAndWait(Application.class, new String[]{"--my.client.arg1=arg1value"});
и запустить сборку с тестами
./gradlew clean build
или просто соберите его без запуска теста:
./gradlew clean build -x test
а затем отправить в реальный кластер Hadoop с вашим my.client.arg1
.
java -jar build/libs/gs-yarn-basic-single-0.1.0.jar --my.client.arg1=arg1value
В любом случае вы видите arg1value
в журналах контейнера:
[2014-07-18 08:49:09.802] boot - 2003 INFO [main] --- ContainerLauncherRunner: Running YarnContainer with parameters [--spring.profiles.active=container,--my.container.arg1=arg1value]
[2014-07-18 08:49:09.806] boot - 2003 INFO [main] --- Application$HelloPojo: Container arg1 value is arg1value
Использование формата ${my.client.arg1:notset1}
также позволяет автоматически определить значение по умолчанию notset1
, если my.client.arg1
опущено пользователем. Мы работаем над контекстом приложения Spring здесь, управляемым Spring Boot, так что все вкусности оттуда в вашем распоряжении.
Если вам нужен более точный контроль над этими пользовательскими аргументами (с использованием args4j, jopt и т. д.), вам потребуется отдельный код/jar для заказа клиента/приложения/контейнера, чтобы создать настраиваемый основной метод клиента. Все остальные руководства по началу работы с Spring YARN в значительной степени используют многопроектные сборки, так что взгляните на них. Например, если вы просто хотите иметь значение первого и второго аргумента без необходимости использовать полное --my.client.arg1=arg1value
в командной строке.
Дайте нам знать, если это работает для вас, и если у вас есть другие идеи, чтобы сделать вещи проще.
person
Janne Valkealahti
schedule
18.07.2014