web-dev-qa-db-ja.com

AWSLambdaデータをKinesisStreamにプッシュする

Lambda関数からKinesisストリームにデータをプッシュする方法はありますか?インターネットを検索しましたが、それに関連する例は見つかりませんでした。

ありがとう。

13
Harish

はい、LambdaからKinesisStreamに情報を送信できます。送信は非常に簡単です。適切な権限でLambdaを実行していることを確認してください。

  1. Kinesis.jsというファイルを作成します。このファイルは、ペイロードを受信して​​KinesisStreamに送信する「保存」関数を提供します。ストリームにデータを送信したい場所に、この「保存」機能を含めることができるようにしたいと考えています。コード:
const AWS = require('aws-sdk');
const kinesisConstant = require('./kinesisConstants'); //Keep it consistent
const kinesis = new AWS.Kinesis({
  apiVersion: kinesisConstant.API_VERSION, //optional
  //accessKeyId: '<you-can-use-this-to-run-it-locally>', //optional
  //secretAccessKey: '<you-can-use-this-to-run-it-locally>', //optional
  region: kinesisConstant.REGION
});

const savePayload = (payload) => {
//We can only save strings into the streams
  if( typeof payload !== kinesisConstant.PAYLOAD_TYPE) {
    try {
      payload = JSON.stringify(payload);
    } catch (e) {
      console.log(e);
    }
  }

  let params = {
    Data: payload,
    PartitionKey: kinesisConstant.PARTITION_KEY,
    StreamName: kinesisConstant.STREAM_NAME
  };

  kinesis.putRecord(params, function(err, data) {
    if (err) console.log(err, err.stack);
    else     console.log('Record added:',data);
  });
};

exports.save = (payload) => {
  const params = {
    StreamName: kinesisConstant.STREAM_NAME,
  };

  kinesis.describeStream(params, function(err, data) {
    if (err) console.log(err, err.stack);
    else {
      //Make sure stream is able to take new writes (ACTIVE or UPDATING are good)
      if(data.StreamDescription.StreamStatus === kinesisConstant.STATE.ACTIVE
        || data.StreamDescription.StreamStatus === kinesisConstant.STATE.UPDATING ) {
        savePayload(payload);
      } else {
        console.log(`Kinesis stream ${kinesisConstant.STREAM_NAME} is ${data.StreamDescription.StreamStatus}.`);
        console.log(`Record Lost`, JSON.parse(payload));
      }
    }
  });
};
  1. KinesisConstant.jsファイルを作成して、一貫性を保ちます:)
module.exports = {
  STATE: {
    ACTIVE: 'ACTIVE',
    UPDATING: 'UPDATING',
    CREATING: 'CREATING',
    DELETING: 'DELETING'
  },
  STREAM_NAME: '<your-stream-name>',
  PARTITION_KEY: '<string-value-if-one-shard-anything-will-do',
  PAYLOAD_TYPE: 'String',
  REGION: '<the-region-where-you-have-lambda-and-kinesis>',
  API_VERSION: '2013-12-02'
}
  1. ハンドラーファイル:データをストリームに送信したい人に応答を送信するための「done」関数を追加しましたが、「kinesis.save(event)」がすべての作業を行います。
const kinesis = require('./kinesis');

exports.handler = (event, context, callback) => {
  console.log('LOADING handler');
  
  const done = (err, res) => callback(null, {
    statusCode: err ? '400' : '200',
    body: err || res,
    headers: {
      'Content-Type': 'application/json',
    },
  });
  
  kinesis.save(event); // here we send it to the stream
  done(null, event);
}
11
Max Cabrera

これは、コンピューターで行うのとまったく同じように行う必要があります。

nodejsの例を次に示します。

let aws = require('aws');
let kinesis = new aws.Kinesis();

// data that you'd like to send
let data_object = { "some": "properties" };
let data = JSON.stringify(data_object);

// Push data to kinesis
const params = {
  Data: data,
  PartitionKey: "1",
  StreamName: "stream name"
}

kinesis.putRecord(params, (err, data) => {
  if (err) console.error(err);
  else console.log("data sent");
}

Lambdaにはストリームへのアクセス許可がないため、このコードは機能しません機能することに注意してください。 AWSを介してLambdaリソースにアクセスする場合は、IAMロールを使用することをお勧めします。

  1. 新しいLambdaを構成するときは、既存の役割を選択するか、役割を作成できます。
  2. IAMに移動し、次にRolesに移動して、Lambda関数に割り当てた役割名を選択します。
  3. 関連する権限を追加します(putRecordputRecords)。

次に、Lambdaをテストします。

4
johni

はい、これは可能です。同じことを実行しようとして、Node.js 4.3ランタイムを使用してLambdaで実行できました。また、バージョン6.10でも機能します。

コードは次のとおりです。

Lambda関数の上部で次のように宣言します。

var AWS = require("aws-sdk");
var kinesis = new AWS.Kinesis();
function writeKinesis(rawdata){
    data = JSON.stringify(rawdata);
    params = {Data: data, PartitionKey: "<PARTITION_KEY>", StreamName: "<STREAM_NAME>"};
    kinesis.putRecord(params, (err, data) => {
    if (err) console.error(err);
    else console.log("data sent");
    });  
}

ここで、exports.handlerで、関数を呼び出します。

writeKinesis(<YOUR_DATA>);

注意すべき点がいくつかあります... Kinesisがデータを取り込むには、データをエンコードする必要があります。以下の例では、CloudWatchからログを取得し、それらをKinesisストリームに送信する関数があります。

Buffer.toString( 'utf8')の内容をwriteKinesis関数に挿入していることに注意してください。

exports.handler = function(input, context) {
    ...
    var zippedInput = new Buffer(input.awslogs.data, 'base64');
    zlib.gunzip(zippedInput, function(error, buffer) {
        ...
        writeKinesis(buffer.toString('utf8'));
        ...
    }
    ...
}

最後に、IAMで、適切な権限を設定します。 Lambda関数は、以下の権限を含むIAMロールのコンテキスト内で実行する必要があります。私の場合、デフォルトのlambda_elasticsearch_executionロールを変更して、次のコードで「lambda_kinesis_execution」というポリシーを含めました。

"Effect": "Allow",
"Action": [
    "kinesis:*"
],
"Resource": [
    "<YOUR_STREAM_ARN>"
]
1
nukalov