aws-sdk js runJobFlow из лямбды не отправляет запрос на запуск кластера EMR

Я пытаюсь запустить кластер EMR из лямбды, которая запускается событием в корзине S3.

Триггер работает нормально, а затем я создаю AWSRequest с runJobFlow, но в консоли EMR нет событий и кластер не запускается.

Все, включая созданный AWSRequest, регистрируется в CloudWatch, но никаких ошибок не регистрируется.

Это просто ничего не делает

Вот код:


const aws = require('aws-sdk');

const emr = new aws.EMR({
    apiVersion: '2009-03-31',
    region: 'us-east-1'
});

const emrClusterConfig = (s3_input_path, s3_output_path) => {

    const ret = {
        Name:`cluster-for-job`,
        ServiceRole: 'EMR_DefaultRole',
        JobFlowRole: 'EMR_EC2_DefaultRole',
        VisibleToAllUsers: true,
        ScaleDownBehavior: 'TERMINATE_AT_TASK_COMPLETION',
        LogUri: 's3n://log-uri/elasticmapreduce/',
        ReleaseLabel: 'emr-5.29.0',
        Instances:{
            InstanceGroups: [
                {
                    Name: 'Master Instance Group',
                    Market: 'ON_DEMAND',
                    InstanceRole: 'MASTER',
                    InstanceType: 'm5.xlarge',
                    InstanceCount: 1,
                    EbsConfiguration: {
                        EbsBlockDeviceConfigs: [
                          {
                            VolumeSpecification: { 
                              SizeInGB: 32, 
                              VolumeType: 'gp2',
                            },
                            VolumesPerInstance: 2
                          },
                        ]
                    },
                },
                {
                    Name: 'Core Instance Group',
                    {... similar to master ...}
                }
            ],
            Ec2KeyName: 'my-keys',
            Ec2SubnetId: 'my-subnet-id',
            EmrManagedSlaveSecurityGroup:'sg-slave-security-group',
            EmrManagedMasterSecurityGroup:'sg-master-security-group',
            KeepJobFlowAliveWhenNoSteps: false,
            TerminationProtected: false
        },
        Applications:[
            {
                'Name': 'Spark'
            },
        ],
        Configurations:[{
            "Classification":"spark",
            "Properties":{}
        }],
        Steps:[{
            'Name': 'step',
            'ActionOnFailure': 'TERMINATE_CLUSTER',
            'HadoopJarStep': {
                'Jar': 's3n://elasticmapreduce/libs/script-runner/script-runner.jar',
                'Args': [
                    "/usr/bin/spark-submit", "--deploy-mode", "cluster",
                    's3://path-to-a-very-humble.jar', s3_input_path, s3_output_path
                ]
            }
        }],

    }

    return ret
}

exports.handler = async (event, context) => {

    const record = event.Records[0];
    const eventName = record.eventName;

    if(eventName === 'ObjectCreated:Put' || eventName === 'ObjectCreated:Post' || eventName === 'ObjectCreated:CompleteMultipartUpload' || eventName === 'ObjectCreated:Copy'){

        const s3_inputPath = 's3n://in-bucket/key';
        const s3_outputPath = 's3n://out-bucket/key';

        try{
            const cluster_config = emrClusterConfig(s3_inputPath,s3_outputPath);
            const AWS_EMRJobRequest = emr.runJobFlow(cluster_config)
            AWS_EMRJobRequest
                .on('success', function(response){ console.log("success => " + response)})
                .on('error', function(response){ console.log("error => " + response)})
                .on('complete', function(response){ console.log("complete => "  + response)})
                .send( function(err, data){
                    if (err) console.log(err, err.stack); // an error occurred
                    else     console.log(data);           // successful response
                    context.done(null,'λ Completed');
                });
             console.log('Finished Launching EMR cluster: ', AWS_EMRJobRequest)
        }
        catch(err){
            console.log(err);
        }
    }
    else{
        console.log(`:: not interested in event ${eventName}`);
    }
    context.done(null, 'λ Completed');
};   

Раньше я настраивал эти кластеры вручную, и они нормально работают. Я скопировал конфигурацию кластера из информации в AWS CLI Export, чтобы она соответствовала настройкам моих существующих кластеров.

Это просто ничего не делает, просто регистрирует в конце «Завершение запуска кластера EMR» с запросом obj, но ничего не происходит.


person jsan    schedule 01.05.2020    source источник


Ответы (1)


aws завершает функцию до получения ответа, потому что AWSRequest отправляет запрос асинхронно. Поскольку вы используете обработчик async, вы можете использовать AWS.Request.promise. Это немедленно запускает вызов службы и возвращает обещание, которое либо выполняется с помощью свойства данных ответа, либо отклоняется с помощью свойства ошибки ответа.

let AWS_EMRJobRequest = emr.runJobFlow(cluster_config);
return AWS_EMRJobRequest.promise();

см. документацию для больше информации.

person Visuddha Karunaratne    schedule 31.07.2020