【问题标题】:DynamoDB, dynamic atomic update of mapped values with AWS Lambda (NodeJS runtime)DynamoDB,使用 AWS Lambda(NodeJS 运行时)对映射值进行动态原子更新
【发布时间】:2017-08-01 14:12:59
【问题描述】:

我试图弄清楚如何对源数据包含映射值且这些映射的键是动态的项目执行原子更新。

如果您查看下面的示例数据,我试图弄清楚如何对同一项目上的 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
  }
}

通过 Lambda 执行 NodeJS 函数以更新 Dynamo:

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));
        }
    });
}

【问题讨论】:

    标签: node.js amazon-dynamodb aws-lambda


    【解决方案1】:

    如果您读取一个项目并调用 PutItem,则更新单个项目在 DynamoDB 中是原子的,它保证是原子的。它要么更新所有字段,要么不更新任何字段。

    现在我看到的唯一问题是您可能会遇到写入冲突。假设一个进程读取一个项目,更新一个地图,而另一个并行的进程执行相同的操作,这将导致一个 PutItem 覆盖最近的更新,您可能会丢失数据。

    要解决此问题,您可以使用conditional updates。简而言之,它允许您仅在满足指定条件时更新项目。您可以做的是为每个项目维护一个版本号。当你更新一个项目时,你可以增加一个版本属性,当你写一个项目时,检查版本号是你期望的。否则,您需要再次阅读该项目(有人在您使用它时对其进行了更新)再次执行更新并尝试再次写入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 2014-06-19
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多