【问题标题】:Run lambda functions in the same lambda code from AWS在来自 AWS 的相同 lambda 代码中运行 lambda 函数
【发布时间】:2019-01-21 16:50:37
【问题描述】:

我有以下 lambda 函数,它在调用时可以正常启动 databricks 集群。现在,我想添加另一个 lambda 函数并在 60 秒的间隔后按顺序运行它。我通过一个接一个地列出两个 lambda 函数来尝试它,但只执行了最后一个函数,并且由于集群处于 TERMINATED 状态,作业失败了。在集群启动后,有人可以帮我运行这项工作吗?

用于启动 databricks 集群的 Lambda:

const https = require("https");   
var tokenstr = "token:xxxxxxxxaaaaaabbbbbccccccc";

exports.handler = (event, context, callback) => 
{
     var data = JSON.stringify({
        "cluster_id": "2222-111000-123abcde"
      });

         var start_cluster_options = {
             host: "aaa.cloud.databricks.com",
             port: 443,
             path: "/api/2.0/clusters/start",
             method: "POST",
             // authentication headers
             headers: {
              "Authorization": "Basic " + new Buffer(tokenstr).toString("base64"),
              "Content-Type": "application/json",
              "Content-Length": Buffer.byteLength(data)
             }
          };

          var request = https.request(start_cluster_options, function(res){
            var body = "";

            res.on("data", function(data) {
              body += data;
            });

            res.on("end", function() {
              console.log(body);
            });

            res.on("error", function(e) {
              console.log("Got error: " + e.message);
            });

          });

      request.write(data);
      request.end();
    };

从 lambda 运行 databricks 作业的函数:

exports.handler = (event, context, callback) => {
     var data = JSON.stringify({
   "job_id": 11111
   });

var run_job_options = {
    host: "aaa.cloud.databricks.com",
      port: 443,
      path: "/api/2.0/jobs/run-now",
      method: "POST",
      // authentication headers
      headers: {
       "Authorization": "Basic " + new Buffer(tokenstr).toString("base64"),
       "Content-Type": "application/json",
       "Content-Length": Buffer.byteLength(data)
     }
   };

   var request = https.request(run_job_options, function(res){
     var body = "";

     res.on("data", function(data) {
       body += data;
     });

我想在同一个 lambda 函数中同时使用 START / RUN_JOB,如果这不是更好的方法,请帮助我,我是 LAMBDA 调用的新手。

更新:

我已按照@Dudemullet 的建议修改了我的代码,并收到一条错误消息“2018-08-15T22:28:14.446Z 7dfe42ff-a0da-11e8-9e71-f77e93d8a2f8 任务在 3.00 秒后超时”,不确定,我做错了什么,请帮忙。

const https = require("https");
var tokenstr = "token:xxxxxxxxaaaaaabbbbbccccccc";

 var data = JSON.stringify({
    "cluster_id": "2222-111000-123abcde"
  });

 var data2 = JSON.stringify({
   "job_id": 11111
 });

  var start_cluster_options = {
     host: "aaa.cloud.databricks.com",
     port: 443,
     path: "/api/2.0/clusters/start",
     method: "POST",
     // authentication headers
     headers: {
      "Authorization": "Basic " + new Buffer(tokenstr).toString("base64"),
      "Content-Type": "application/json",
      "Content-Length": Buffer.byteLength(data)
     }
  };

 var run_job_options = {
     host: "aaa.cloud.databricks.com",
     port: 443,
     path: "/api/2.0/jobs/run-now",
     method: "POST",
     // authentication headers
     headers: {
      "Authorization": "Basic " + new Buffer(tokenstr).toString("base64"),
      "Content-Type": "application/json",
      "Content-Length": Buffer.byteLength(data2)
    }
  };

exports.handler = (event, context, callback) => 
{
   https.request(start_cluster_options, function(res){});
   setTimeout(() => {
    https.request(run_job_options, function(res){});
    callback(); // notify lambda everything is complete
    }, 60);
};

我在 python 中做 lambda 函数,但是这个函数是从一个示例扩展而来的,所以我不确定 node.js 编码。

******更新结束******

理想情况下,我希望将它包含在 AWS lambda 中,而不是进入 AWS Step 函数等。

谢谢

【问题讨论】:

  • 所以首先你想运行start_cluster函数然后等待60秒然后运行submit_job函数?如果集群在 60 秒后没有启动怎么办?
  • 好的,60 秒只是表示,集群启动大约需要 120 秒。我可以添加一些缓冲区的等待间隔。谢谢。
  • 一旦 start_cluster 完成,集群就启动了。使用 aws sdk 发送调用 submit_job 的 SNS
  • 在单个 lambda 函数中根本不可能做到这一点吗?
  • 嗯 ????,所以这段代码看起来有点草率。如果你愿意,我建议你最终使用 Promise 或 async/await。但是请注意,您只想在第一个请求肯定完成时执行代码的run request 部分。为此,您在回调中发出该请求。添加空间以提高清晰度。 js exports.handler = (event, context, callback) => { https.request(start_cluster_options, function(res){ setTimeout(() => { https.request(run_job_options, function (res) { callback(); }); }, 60); }); };

标签: python node.js amazon-web-services aws-lambda


【解决方案1】:

您可以使用AWS Step Functions 执行此操作。它基本上就像一个工作流。

在高层次上,这就是您可能想要做的事情:

1) Run your lambda to start the cluster and return cluster id or something.
2) Check cluster status every 10 seconds.
3) If the cluster is up, execute `submit job` lambda function.

【讨论】:

  • 不能在同一个 AWS lamdba 函数中完成吗?仅针对这 2 个功能,我是否需要使用 AWS Step,这增加了我的长长的 AWS 服务列表。我已经在使用 RDS、S3、Glue、Lambda、Cloudwatch 等,我不想要其他 AWS 服务,并且更喜欢将它放在同一个 AWS lamdba 中,任何建议。
  • 幕后 step function 调用 lambda,因此您将能够重用您的 lambda 函数。
  • 我的 lambda 函数应该根据文件登陆 S3 存储桶启动。这可以通过 AWS Step 实现吗?换句话说,我的 databricks 集群启动/作业运行基于文件登陆到 S3 存储桶,可能一天一次或两次。谢谢
  • 是的。编写一个 lambda 函数来触发你的 step 函数以响应 s3 事件。
【解决方案2】:

假设您已将其抽象为两个函数。

startServerrunJob

您的 lambda 将一直运行,直到您调用回调或执行时间 (TTL) 到期。所以你可以编写如下所示的代码。

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

  https.request(start_cluster_options, function (res) {

    setTimeout(() => {
      https.request(run_job_options, function (res) {

        callback();

      });
    }, 60);

  });
};

另一种简单的方法是使用 SQS。 Lambda 现在可以使用 SQS 作为事件源。因此,您可以在 SQS 队列中创建一条消息,并将其可见性超时设置为您需要的任何时间。 Sqs visibility timeout

【讨论】:

  • 谢谢 Dudemullet,我正在寻找完全一样的东西,你能提供一些代码示例吗,我是 lambda 新手,发现很难将我上面的 lambda 函数绑定到子函数。
  • @Yuva 我已经更新了我的代码块以更好地反映您的需求
猜你喜欢
  • 2016-02-29
  • 2021-03-20
  • 2019-07-06
  • 1970-01-01
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
相关资源
最近更新 更多