2017-07-30 4 views
1

ソースデータにマップされた値が含まれており、これらのマップのキーが動的であるアイテムに対してアトミック更新を実行する方法を解明しようとしています。DynamoDB、AWS Lambda(NodeJSランタイム)でマップされた値の動的アトミック更新

以下のサンプルデータを見ると、BSSentDestIpとBSRecvDestIpの値のアトミックな更新が同じアイテムに対してどのようにできるかを理解しようとしています。私はドキュメントを読んでいたが、私が見つけることができる唯一のものはlist_appendだったので、後でトラバースして合計する必要がある追加されたキー/値のリストが私に残る。入力データの

http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html

例:ダイナモを更新するためにラムダを介して実行

{ 
    "RecordId": 31, 
    "UUID": "170ae748-f8cf-4df9-6e08-c0c8a5f029d4", 
    "UserId": "username", 
    "DeviceId": "e0:cb:4e:53:ae:ff", 
    "ExpireTime": 1501445446, 
    "StartTime": 1501441846, 
    "EndTime": 1501441856, 
    "MinuteId": 10, 
    "PacketCount": 1028, 
    "ByteSum": 834111, 
    "BSSent": 98035, 
    "BSRecv": 736076, 
    "BSSentDestIp": { 
    "151.101.129.69": 2518, 
    "192.168.1.254": 4780, 
    "192.168.1.80": 14089, 
    "192.33.31.162": 2386, 
    "54.239.30.232": 21815, 
    "54.239.31.129": 6423, 
    "54.239.31.69": 3255, 
    "54.239.31.83": 18447, 
    "98.138.253.109": 3020 
    }, 
    "BSRecvDestIp": { 
    "151.101.129.69": 42414, 
    "151.101.57.174": 20792, 
    "192.230.66.108": 130175, 
    "192.33.31.162": 56398, 
    "23.194.140.100": 26209, 
    "54.239.26.209": 57210, 
    "54.239.31.129": 188747, 
    "54.239.31.69": 41115, 
    "98.138.253.109": 111775 
    } 
} 

NodeJS機能:項目を読めば焦がす項目を更新

function updateItem(UserIdValue, MinuteIdValue) { 

    var UpdateExpressionString = "set PacketCount = PacketCount + :PacketCount, \ 
    ByteSum = ByteSum + :ByteSum, \ 
    BSSent = BSSent + :BSSent, \ 
    BSRecv = BSRecv + :BSRecv"; 

    var params = { 
     TableName: gDynamoTable, 
     Key: { 
      "UserId": UserIdValue, 
      "MinuteId": MinuteIdValue 
     }, 
     UpdateExpression: UpdateExpressionString, 
     ExpressionAttributeValues: { 
      ":PacketCount": gRecordObject.PacketCount, 
      ":ByteSum": gRecordObject.ByteSum, 
      ":BSSent": gRecordObject.BSSent, 
      ":BSRecv": gRecordObject.BSRecv 
     }, 
     ReturnValues: "UPDATED_NEW" 
    }; 

    dynamo.updateItem(params, function(err, data) { 
     if (err) { 
      console.log("updateItem Error: " + err); 
     } else { 
      console.log("updateItem Success: " + JSON.stringify(data)); 
     } 
    }); 
} 

答えて

2

がDynamoDBのにアトミックでありますPutItemを呼び出すと、アトミックになることが保証されます。すべてのフィールドを更新するか、いずれも更新しません。

これでわかるのは、書き込み競合が発生する可能性があることだけです。あるプロセスがアイテムを読み込んで1つのマップを更新し、別のプロセスが並行して同じことをすると、1つのPutItemが最新の更新を上書きし、データを失うことになります。

この問題を解決するにはconditional updatesを使用できます。要約すると、指定された条件が満たされた場合にのみアイテムを更新することができます。あなたができることは、すべてのアイテムでバージョン番号を維持することです。アイテムを更新するときは、バージョン属性を増やすことができます。アイテムを書き込むときには、そのバージョン番号が期待どおりのものであることを確認してください。それ以外の場合は、アイテムをもう一度読む必要があります(誰かがそれを使って作業している間にアイテムを更新しました)。あなたのアップデートを再度実行し、再度書き込もうとします。

関連する問題