1180 Безусловно, это было бы наиболее эффективным использованием ресурсов. Позвольте мне предупредить вас: в этом много деталей; Я постараюсь перечислить столько, сколько вы получите. Я рекомендую вам добавить собственный исчерпывающий ответ, в котором перечислены все проблемы, с которыми вы столкнулись, и способ их обхода (как только вы это сделаете)
В отношении создания / прекращения работы кластера
EmrCreateJobFlowOperator
и EmrTerminateJobFlowOperator
соответственно
Не беспокойтесь, если вы не используете AWS
SecretAccessKey
(и полностью полагаться на IAM
роли ); создание любого AWS
-связанного hook
или operator
в Airflow
будет автоматически отступать к базовой EC2
роли IAM
Если вы НЕ используете EMR-Steps API для передачи задания, то вам также придется вручную определить обе вышеуказанные операции, используя Sensors
] . Уже есть датчик для фазы создания опроса, который называется EmrJobFlowSensor
, и вы можете слегка изменить его, чтобы создать датчик для завершения
Вы передаете свой кластер-конфигурацию JSON в job_flow_extra
. Вы также можете передавать конфиги в параметре Connection
(например, my_emr_conn
) extra
, но воздерживаться от него, потому что он часто прерывает загрузку SQLAlchemy
ORM (так как это большая json
)
Относительно отправки заданий
Вы либо отправляете задания в Emr
, используя EMR-Steps API , что можно сделать либо на этапе создания кластера (в JSON Cluster-Configs), либо впоследствии, используя add_job_flow_steps()
. Есть даже emr_add_steps_operator()
в Airflow
, который также требует EmrStepSensor
. Вы можете прочитать больше об этом в AWS
документах , и вам, возможно, также придется использовать command-runner.jar
Для конкретных случаев применения (например, Hive
, Livy
), вы можете использовать их конкретные способы. Например, вы можете использовать HiveServer2Hook
, чтобы отправить Hive
задание. Вот сложная часть: вызов run_job_flow()
(сделанный на этапе создания кластера) дает вам только job_flow_id
(идентификатор кластера). Вам нужно будет использовать вызов describe_cluster()
, используя EmrHook
, чтобы получить private-IP главного узла . Используя это, вы сможете программно создать Connection
(например, Hive Server 2 Thrift
соединение ) и использовать его для отправки ваших вычислений в кластер. И не забудьте удалить эти соединения (для удобства) до завершения рабочего процесса.
Наконец, есть старый добрый bash для взаимодействия с кластером. Для этого вы также должны передать пару ключей EC2
на этапе создания кластера . После этого вы можете программно создать SSH
соединение и использовать его (с SSHHook
или SSHOperator
) для выполнения заданий в кластере. Узнайте больше о SSH-материалах в Airflow
здесь
Особенно для отправки Spark
заданий на удаленных Emr
кластера, прочитайте это обсуждение
Да, это будет, согласно C++11: 12.6.2 /10
(тот же раздел в C++14
, 15.6.2 /13
в C++17
):
В конструкторе неделегирования инициализация продолжается в следующем порядке (мой полужирный):
Во-первых, и только для конструктора большей части производного класса (1.8), виртуальные базовые классы инициализируются в порядке, они появляются на в глубину слева направо обход направленного графа без петель базовых классов, где “слева направо” порядок появления базовых классов в основном списке спецификатора производного класса.
Затем прямые базовые классы инициализируются в порядке объявления, поскольку они появляются в основном списке спецификатора (независимо от порядка инициализаторов мадам).
Затем нестатические элементы данных инициализируются в порядке, которым они были объявлены в определении класса (снова независимо от порядка инициализаторов мадам).
Наконец, составной оператор тела конструктора выполняется.
Главная причина для использования init-списков состоит в том, чтобы помочь компилятору с оптимизацией. Init-списки для неосновных типов (т.е. объекты класса, а не int
, float
, и т.д.), может обычно создаваться оперативный.
Если Вы создаете объект, затем присваивают ему в конструкторе, это обычно приводит к созданию и разрушению временных объектов, которое неэффективно.
Init-списки могут избежать этого (если компилятор до него, конечно, но большинство из них должно быть).
Следующая полная программа произведет 7, но это для определенного компилятора (CygWin g ++), таким образом, это не гарантирует что поведение больше, чем образец в исходном вопросе.
Однако согласно цитате в первом абзаце выше, стандарт действительно на самом деле гарантирует это.
#include <iostream>
class Foo {
int x;
public:
Foo(): x(7) {
std::cout << x << std::endl;
}
};
int main (void) {
Foo foo;
return 0;
}
Да, C++ создает всех участников прежде, чем назвать код constructur.
Как уже отвечено, списки инициализации полностью выполняются прежде, чем ввести блок конструктора. Таким образом, абсолютно безопасно использовать (инициализированных) участников в теле конструктора.
Вы сделали комментарий в принятом ответе о необходимости относиться к аргументам конструктора, но не участнику Вар в блоке конструктора. Вы не делаете.
Возможно, что Вы перепутали то, что необходимо обратиться к параметрам а не к членским атрибутам в списке инициализации. Как пример, учитывая класс X, который имеет двух участников (a_ и b _) интервала типа, следующий конструктор может быть неточным:
X::X( int a ) : a_( a ), b( a_*2 ) {}
Возможная проблема здесь состоит в том, что конструкция элементов в списке инициализации зависит от порядка объявления в классе а не порядка, в котором Вы вводите список инициализации. Если класс был определен как:
class X
{
public:
X( int a );
private:
int b_;
int a_;
};
Затем независимо от того, как Вы вводите список инициализации, факт - то, что b _ (a_*2) будет выполняться, прежде чем a_ инициализируется, так как объявление участников является первым b_ и позже a_. Это создаст ошибку, как Ваш код полагает (и вероятно зависит) на b_, являющемся дважды значением _, и на самом деле b_ содержит мусор. Простое решение не относится к участникам:
X::X( int a ) : a_( a ), b( a*2 ) {} // correct regardless of how X is declared
Предотвращение этой ловушки является причиной, почему Вам предлагают не использовать членские атрибуты в качестве части инициализации других участников.