Я относительно новый пользователь Python и Airflow, и мне очень трудно заставить spark-submit запустить задачу Airflow. Моя цель - успешно выполнить следующую задачу DAG

from datetime import datetime, timedelta
from airflow import DAG
from airflow.contrib.operators.spark_submit_operator import SparkSubmitOperator
from airflow.operators.bash_operator import BashOperator

default_args = {
    'owner': 'matthew',
    'start_date': datetime(2019, 7, 8)
}

dag = DAG('CustomCreate_test2',
          default_args=default_args,
          schedule_interval=timedelta(days=1))

t3 = BashOperator(
    task_id='run_test',
    bash_command='spark-submit --class CLASSPATH.CustomCreate ~/IdeaProjects/custom-create-job/build/libs/custom-create.jar',
    dag=dag
)

Я знаю, что проблема заключается в Airflow, а не в bash, потому что когда я запускаю команду spark-submit --class CLASSPATH.CustomCreate ~/IdeaProjects/custom-create-job/build/libs/custom-create.jar в терминале, она запускается успешно.

Я получаю следующую ошибку из журналов Airflow

...
[2019-08-28 15:55:34,750] {bash_operator.py:132} INFO - Command exited with return code 1
[2019-08-28 15:55:34,764] {taskinstance.py:1047} ERROR - Bash command failed
Traceback (most recent call last):
  File "/Users/matcordo2/.virtualenv/airflow/lib/python3.7/site-packages/airflow/models/taskinstance.py", line 922, in _run_raw_task
    result = task_copy.execute(context=context)
  File "/Users/matcordo2/.virtualenv/airflow/lib/python3.7/site-packages/airflow/operators/bash_operator.py", line 136, in execute
    raise AirflowException("Bash command failed")
airflow.exceptions.AirflowException: Bash command failed
...

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

...
[2019-08-28 15:54:49,749] {logging_mixin.py:95} INFO - [[34m2019-08-28 15:54:49,749[0m] {[34mspark_submit_hook.py:[0m427} INFO[0m - at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)[0m
[2019-08-28 15:54:49,803] {taskinstance.py:1047} ERROR - Cannot execute: ['spark-submit', '--master', 'yarn', '--num-executors', '2', '--total-executor-cores', '1', '--executor-cores', '1', '--executor-memory', '2g', '--driver-memory', '1g', '--name', 'CustomCreate', '--class', 'CLASSPATH.CustomCreate', '--verbose', '--queue', 'root.default', '--deploy-mode', 'cluster', '~/IdeaProjects/custom-create-job/build/libs/custom-create.jar']. Error code is: 1.
...

Есть ли что-то, что мне нужно сделать, используя SparkSubmitOperator(...), прежде чем я смогу запустить команду spark-submit ... в задаче BashOperator(...)?

Есть ли способ запустить мою команду spark-submit непосредственно из задачи SparkSubmitOperator(...)?

Есть ли что-нибудь, что мне нужно сделать для spark_default на странице Admin-> Connections в Airflow?

Есть ли что-нибудь, что нужно настроить на странице Администратор-> Пользователи в Airflow? Есть ли что-нибудь, что нужно настроить, чтобы Airflow запускал искру или запускал файл jar, созданный конкретным пользователем? Если да, то что / как?

0
mattc-7 29 Авг 2019 в 00:27

2 ответа

Лучший ответ

Я нашел обходной путь, который решил эту проблему.

Создайте новое соединение ssh (или отредактируйте соединение по умолчанию), как показано ниже на странице Airflow Admin-> Connection . Пример SSH-подключения Airflow

Ниже текстовая версия, если вы не видите изображение
Conn ID : ssh_connection
Тип Conn : SSH
Хост : домашний IP-адрес
Имя пользователя : HOST USERNAME
Пароль : ХОЗЯЙСТВЕННЫЙ ПАРОЛЬ
< Сильный > Порт :
Дополнительно : {"key_file": "/ PATH TO HOME DIR / airflow / .ssh / id_rsa", "allow_host_key_change": "true", "no_host_key_check": "true"}

Затем внесите коррективы в ваш скрипт на python

from airflow import DAG
from airflow.contrib.operators.ssh_operator import SSHOperator
from airflow.operators.bash_operator import BashOperator
from datetime import datetime, timedelta

default_args = {
    'owner': 'matthew',
    'start_date': datetime(2019, 8, 28)
}

dag = DAG('custom-create',
          default_args=default_args,
          schedule_interval=timedelta(days=1),
          params={'project_source': '~/IdeaProjects/custom-create-job',
                  'spark_submit': '/usr/local/bin/spark-submit',
                  'classpath': 'CLASSPATH.CustomCreate',
                  'jar_file': 'build/libs/custom-create.jar'}
          )

templated_bash_command = """
    echo 'HOSTNAME: $HOSTNAME' #To check that you are properly connected to the host
    cd {{ params.project_source }}
    {{ params.spark_submit }} --class {{ classpath }} {{ jar_file }}
"""

t1 = SSHOperator(
    task_id="SSH_task",
    ssh_conn_id='ssh_connection',
    command=templated_bash_command,
    dag=dag
)

Я надеюсь, что это решение поможет другим людям, которые могут столкнуться с подобной проблемой, как я.

1
mattc-7 29 Авг 2019 в 20:39

На аналогичный вопрос уже был дан ответ - Ссылка StackOverFlow

Я думаю, что ссылка выше поможет вам.

В будущем, если вы захотите внедрить то же самое в AWS EMR или AZURE , тогда у вас есть прекрасный способ составить график заданий на запуск - Документация воздушного потока

Пример для вышесказанного - (AWS EMR)

 <airflow_EMR_task> =cover_open(json.load(open(airflow_home+'/<tasks_json_containing_all_spark_configurations>')))
 <airflow_EMR_task>['Job']['Name'] =  <airflow_EMR_task>['Job']['Name'] + <'optional_postfix'>
airflow_swperformance_cpu_creator = EmrRunJobFlowOperator(
    task_id='<task_id>',
    job_flow_overrides= <airflow_EMR_task>['Job'],
    aws_conn_id='aws_default',
    emr_conn_id='emr_default',
    retries=1,
    dag=dag
)

И A Simple JSON будет - (тот же файл JSON, как упомянуто выше)

{
    "Job": {
        "Name": "<task_name>",
        "LogUri": "<task_log_uri>",
        "ReleaseLabel": "emr-5.6.0",
        "Applications": [
            {
                "Name": "Spark"
            },
            {
                "Name": "Hive"
            }
        ],
        "Tags": [
            {
                "Key" : "<any_tag>",
                "Value" : "<any_tag>"
            },
            {
                "Key" : "<any tag>",
                "Value": "<any_tag>"
            },
            {
                "Key" : "<any_tag>",
                "Value": "<any_tag value>"
            }
        ],
        "JobFlowRole": "EMR_EC2_DefaultRole_Stable",
        "ServiceRole": "EMR_DefaultRole",
        "VisibleToAllUsers": true,
        "Configurations": [
            {
                "Classification": "spark-defaults",
                "Properties": {
                    "spark.driver.extraJavaOptions":"-XX:+UseParallelGC -XX:+UseParallelOldGC -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxHeapFreeRatio=70 -XX:+CMSClassUnloadingEnabled -XX:+ExitOnOutOfMemoryError -Dlog4j.configuration=log4j-custom.properties",
                    "spark.executor.extraJavaOptions":"-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxHeapFreeRatio=70 -XX:+CMSClassUnloadingEnabled -XX:+ExitOnOutOfMemoryError -Dlog4j.configuration=log4j-custom.properties",
                    "spark.scheduler.mode": "FAIR",
                    "spark.eventLog.enabled": "true",
                    "spark.serializer": "org.apache.spark.serializer.KryoSerializer",
                    "spark.sql.orc.filterPushdown": "true",
                    "spark.dynamicAllocation.enabled": "false"
                },
                "Configurations": []
            },
            {
                "Classification": "spark",
                "Properties": {
                    "maximizeResourceAllocation": "true"
                },
                "Configurations": []
            },
            {
                "Classification": "hive-site",
                "Properties": {
                    "javax.jdo.option.ConnectionUserName": "<HIVE USERNAME IF ANY>",
                    "javax.jdo.option.ConnectionPassword": "<<hive_connection_password>>",
                    "javax.jdo.option.ConnectionURL": "<Hive_URL_IF_ANY"
                },
                "Configurations": []
            },
            {
                "Classification": "emrfs-site",
                "Properties": {
                    "fs.s3.serverSideEncryption.kms.keyId": "<<encryption_key>>",
                    "fs.s3.enableServerSideEncryption": "true"
                },
                "Configurations": []
            },
            {
                "Classification":"spark-env",
                "Configurations":[{
                    "Classification":"export",
                    "Configurations":[],
                    "Properties": {
                        "ANY_ENV_VARIABLE_REQUIRED_FOR_SPECIFIC_JOB",
                        "ANY_ENV_VARIABLE_REQUIRED_FOR_SPECIFIC_JOB",
                        "ANY_ENV_VARIABLE_REQUIRED_FOR_SPECIFIC_JOB",
                        "ANY_ENV_VARIABLE_REQUIRED_FOR_SPECIFIC_JOB",
                        "ANY_ENV_VARIABLE_REQUIRED_FOR_SPECIFIC_JOB"
            "S3_BUCKET_NAME":"<S3_bucekt_naem_if_Required>"
                    }
                }
                ]}
        ],
        "Instances": {
            "Ec2KeyName": "<ssh_key>",
            "KeepJobFlowAliveWhenNoSteps": false,
            "Ec2SubnetId": "<subnet>",
            "EmrManagedSlaveSecurityGroup": "<security_group>",
            "EmrManagedMasterSecurityGroup": "<security_group_parameter>",
            "AdditionalSlaveSecurityGroups": [
                "<self_explanatory>"
            ],
            "AdditionalMasterSecurityGroups": [
                "<self_explanatory>"
            ],
            "InstanceGroups": [
                {
                    "InstanceCount": 4,
                    "InstanceRole": "CORE",
                    "InstanceType": "r3.xlarge",
                    "Name": "Core instance group - 2"
                },
                {
                    "InstanceCount": 1,
                    "InstanceRole": "MASTER",
                    "InstanceType": "r3.xlarge",
                    "Name": "Master instance group - 1"
                }
            ]
        },
        "BootstrapActions": [],
        "Steps": [
            {
                "Name": "download-dependencies",
                "HadoopJarStep": {
                    "Jar": "command-runner.jar",
                    "Args": [
                        "aws",
                        "s3",
                        "cp",
                        "<appropriate_s3_location>",
                        "/home/hadoop",
                        "--recursive"
                    ],
                    "Properties": []
                },
                "ActionOnFailure": "TERMINATE_CLUSTER"
            },
            {
                "Name": "run-script",
                "HadoopJarStep": {
                    "Jar": "command-runner.jar",
                    "Args": [
                        "sudo",
                        "/bin/sh",
                        "/home/hadoop/pre-executor.sh"
                    ],
                    "Properties": []
                },
                "ActionOnFailure": "TERMINATE_CLUSTER"
            },
            {
                "Name": "spark-submit",
                "HadoopJarStep": {
                    "Jar": "command-runner.jar",
                    "Args": [
                        "spark-submit",
                        "/home/hadoop/analytics-job.jar",
            "--run-gold-job-only"
                    ],
                    "Properties": []
                },
                "ActionOnFailure": "TERMINATE_CLUSTER"
            }
        ]
    }
}

И это будет все.

0
Golokesh Patra 29 Авг 2019 в 07:01