Bagaimana fungsi AWS Lambda memperbarui semua catatan dalam tabel DynamoDB?

Saya sedang mengerjakan fungsi AWS Lambda (Node 4.3) yang perlu menjalankan semua item dalam tabel DynamoDB dan memperbarui atribut tertentu.

Masalah yang saya alami adalah bagaimana membuat Lambda menunggu hingga semua operasi DynamoDB selesai.

var async = require('async');
var aws = require('aws-sdk');
var doc = new aws.DynamoDB.DocumentClient();

exports.handler = (event, context, callback) => {
    doc.scan({
        TableName: 'Occupations_dev'
    }, function (err, data) {
        console.log(data.Items.length);

        var funcs = [];

        data.Items.forEach(function (item) {
            funcs.push(function (cb) {
                item.Popularity = 0;

                doc.put({
                    TableName: 'Occupations_dev',
                    Item: item
                }, function (err, data) {
                    if (err) {
                        console.log("ERROR: " + item.Name);
                        cb(err);
                    } else {
                        console.log('Finished put for ' + item.Id)
                        cb(null, item);
                    }
                });
            });
        });

        async.parallel(funcs, function (err, results) {
            console.log('Finished');

            if (err) {
                context.fail(err);
            } else {
                callback(null, 'Finished');
            }
        });
    });
};

Saya mencoba menggunakan async.parallel untuk menunggu semua permintaan db.put selesai tetapi berakhir dengan kesalahan Process exited before completing request setiap kali fungsi Lambda berjalan.

Itu memang memperbarui beberapa item DynamoDB tetapi jelas tidak semuanya.

Saya menambahkan beberapa panggilan console.log ketika ada kesalahan tetapi satu-satunya keluaran yang saya lihat di log adalah ini:

START RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870 Version: $LATEST
2017-03-30T02:08:11.691Z    b72fd7c6-14ed-11e7-a95a-c1185af4e870    1362
END RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870
REPORT RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870  Duration: 37165.80 ms   Billed Duration: 37200 ms   Memory Size: 128 MB Max Memory Used: 128 MB 
RequestId: b72fd7c6-14ed-11e7-a95a-c1185af4e870 Process exited before completing request

Apa cara yang tepat untuk membuat fungsi Lambda menunggu hingga semuanya selesai? (Jumlah datanya tidak besar, jadi saya tidak khawatir akan berjalan lebih dari 5 menit dan kehabisan waktu.)


person Mark Biek    schedule 30.03.2017    source sumber
comment
Saya membayangkan Process exited before completing request berarti ada kesalahan lain dalam kode js Anda - apakah ini berfungsi secara lokal, dan hanya kesalahan pada AWS Lambda?   -  person Bobby Matson    schedule 30.03.2017
comment
Saya relatif baru mengenal Lambda jadi saya tidak tahu cara menjalankannya secara lokal. Apakah ada cara untuk mendapatkan lebih banyak detail kesalahan dari Lambda? Saya tidak melihat apa pun di log CloudWatch.   -  person Mark Biek    schedule 30.03.2017
comment
Aneh, saya yakin mereka seharusnya ada di Cloudwatch. Saat Anda menjalankan cuplikan kode, apakah Anda melihat pernyataan console.log? Itu harus datang melalui keluaran log di Lambda   -  person Bobby Matson    schedule 30.03.2017
comment
Saya menambahkan beberapa pernyataan console.log ketika doc.put mengalami kesalahan tetapi saya tidak melihat satu pun pernyataan itu di log. Saya hanya melihat keluaran dari console.log(data.Items.length); dan sekitar 60 pernyataan Finished put for... sebelum mati.   -  person Mark Biek    schedule 30.03.2017
comment
Liar! Apakah DynamoDB mempunyai batasan pada koneksi simultan? Jika Anda mencoba memasukkan terlalu banyak catatan secara asinkron, hal itu dapat menyebabkan muntah. Mungkin coba gunakan pendekatan sinkron seperti async.series atau Promise.all dan lihat apakah hasilnya sama.   -  person Bobby Matson    schedule 30.03.2017
comment
Itu pemikiran yang menarik. Saya akan mencoba async.auto (atau mungkin waterfall) dan melihat apa yang terjadi. Terima kasih untuk bantuannya!   -  person Mark Biek    schedule 30.03.2017
comment
Tidak masalah! Saya mengedit komentar terakhir saya, menurut saya async.series adalah yang ingin Anda coba. Beri tahu saya bagaimana kelanjutannya!   -  person Bobby Matson    schedule 30.03.2017
comment
@BobbyMatson async.series berhasil! Sepertinya Anda benar tentang saya membanjiri DynamoDB dengan terlalu banyak koneksi. Anda harus mempostingnya sebagai jawaban sehingga saya dapat menerimanya dan memberi Anda penghargaan yang pantas. Terima kasih lagi. Saya benar-benar menghabiskan sepanjang hari mencoba memikirkan hal ini.   -  person Mark Biek    schedule 30.03.2017
comment
akan melakukan! Senang itu berhasil   -  person Bobby Matson    schedule 30.03.2017


Jawaban (2)


Pemanggilan fungsi async.parallel terjadi secara asinkron, yang kemungkinan membanjiri DynamoDB dengan banyak pembaruan simultan dan meningkatkan kesalahan "terlalu banyak koneksi" di tingkat DB

Saya akan merekomendasikan menggunakan operasi sinkron, seperti async.series untuk melakukan pembaruan DB. DynamoDB seharusnya tidak mengalami kesulitan memproses pembaruan ini satu demi satu.

person Bobby Matson    schedule 30.03.2017

Pesan "Proses keluar sebelum menyelesaikan permintaan" berarti fungsi Javascript keluar sebelum memanggil konteks.selesai (atau konteks.sukses, dll.).

Berikut adalah beberapa saran:

Pertama-tama, coba tingkatkan batas memori untuk fungsi tersebut. Baris Memory Size: 128 MB Max Memory Used: 128 MB ini mungkin menunjukkan bahwa memori tidak cukup dan proses terhenti begitu saja tanpa memanggil panggilan balik terakhir.

Apa yang mungkin Anda lihat setelah meningkatkan batas memori adalah salah satu dari berikut ini:

  • Fungsi Anda akan habis waktunya. Dalam hal ini Anda mungkin perlu meningkatkan kapasitas yang disediakan tabel (dan/atau batas waktu lambda Anda)

  • Bahkan jika fungsi berakhir tanpa batas waktu, Anda mungkin akan melihat bahwa tidak semua catatan tabel diproses. Hal ini karena operasi pemindaian dan kueri mungkin tidak mengembalikan semua baris tabel, jika jumlah total item yang dipindai melebihi batas ukuran kumpulan data maksimum sebesar 1 MB. Ketika pemindaian selesai, Anda harus memeriksa apakah LastEvaluatedKey dikembalikan bersama dengan datanya. Jika ya, Anda harus melakukan pemindaian lain dengan memberikan nilai LastEvaluatedKey sebagai parameter ExclusiveStartKey

person xtx    schedule 30.03.2017