【问题标题】:Generating a unique key for dynamodb within a lambda function在 lambda 函数中为 dynamodb 生成唯一键
【发布时间】:2019-02-02 00:59:48
【问题描述】:

DynamoDB 没有自动为您生成唯一密钥的选项。

在示例中,我看到人们从字段组合中创建了一个 uid,但是有没有办法为没有任何可以充当唯一标识符的值组合的数据创建唯一 ID?我的问题专门针对 lambda 函数。

我看到的一个选项是基于时间戳创建一个 uuid,并在末尾添加一个计数器,将其插入(或检查它是否存在),并在重复的情况下以增量重试直到成功。但是,这意味着我可能会超过 lambda 函数的执行时间限制而无需创建条目。

【问题讨论】:

  • 您使用什么编程语言?通常,您使用适用的库在代码中生成 UUID。无需自己编写代码,也无需使用此方法重试/执行时间问题。
  • 我正在使用 nodejs,但尤其是在异步环境中,我似乎不可能创建一个没有潜在重试/执行时间问题的 uuid。

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


【解决方案1】:

如果你使用的是 Node.js 8.x,你可以使用 uuid 模块。

var AWS = require('aws-sdk'),
    uuid = require('uuid'),
    documentClient = new AWS.DynamoDB.DocumentClient();
[...]
        Item:{
            "id":uuid.v1(),
            "Name":"MyName"
        },

如果您使用的是 Node.js 10.x,则可以使用不带 uuid 模块的 awsRequestId。

    var AWS = require('aws-sdk'),
        documentClient = new AWS.DynamoDB.DocumentClient();
[...]
    Item:{
        "id":context.awsRequestId,
        "Name":"MyName"
    },

【讨论】:

  • 如果您每个请求只需要一个 UUID 并且您没有将数据库中的请求 ID 用于任何事情,那么重用 awsRequestId 是一个有趣的不需要依赖项的解决方案。如果您将其存储在可能导致冲突的其他位置或不要在同一请求中使用两次,请小心。
  • context 应该是什么?由于缺乏说明而投反对票。
  • context 是 Lambda 处理程序的第二个参数:exports.handler = async function(event, context) {}
【解决方案2】:

NPM 上可用的 UUID 包正是这样做的。

https://www.npmjs.com/package/uuid

您可以在 4 种不同的生成算法之间进行选择:

  • V1 时间戳
  • V3 命名空间
  • V4 随机
  • V5 命名空间(再次)

这会给你:

“一个 UUID [that] 是 128 位长,并且可以保证跨域的唯一性 空间和时间。” - RFC4122

生成的 UUID 如下所示:1b671a64-40d5-491e-99b0-da01ff1f3341
如果太长,您始终可以使用 Base64 对其进行编码以获取 G2caZEDVSR6ZsAAA2gH/Hw,但您将无法通过原始 UUID 中包含的时间和命名空间信息(这对您可能无关紧要)来操作数据。

【讨论】:

  • 它可以生成字母数字ID来减少长度吗?
  • 您可以将其编码为 base64 以减少长度。但是 UUID 包含有关日期、名称空间等的可用信息。如果您仅将 UUID 用作键,并且不需要根据这些键包含的信息来操作数据,请继续对它们进行编码。
【解决方案3】:

awsRequestId 看起来像它实际上是 V.4 UUID(随机),代码如下:sn-p:

exports.handler = function(event, context, callback) {
    console.log('remaining time =', context.getRemainingTimeInMillis());
    console.log('functionName =', context.functionName);
    console.log('AWSrequestID =', context.awsRequestId);
    callback(null, context.functionName);
};

如果你想自己生成这个,你仍然可以使用https://www.npmjs.com/package/uuidUlide(性能稍好)根据RFC-4122生成不同版本的UUID

对于 Go 开发人员,您可以使用来自 Google's UUIDPbormanSatori 的这些包。 Pborman 性能更好,详情请查看these articles and benchmarks

更多关于通用唯一标识符规范的信息可以在here找到。

【讨论】:

  • 对开发中的快速测试很有用,但我认为实体 ID 最好是真正全球唯一的。
【解决方案4】:

我们使用 idgen npm 包来创建 id。还有更多关于长度的问题,具体取决于增加或减少大小的计数。

https://www.npmjs.com/package/idgen

我们更喜欢 UUID 或 GUID,因为它们只是数字。使用 DynamoDB,它是 guid/uuid 的所有字符,使用 idgen,您可以使用更少的字符创建更多的 id,并减少冲突。因为每个字符都有更多的范围。

希望对你有帮助。

EDIT1:

注意!从 idgen 1.2.0 开始,超过 16 个字符的 ID 将包含一个基于当前毫秒时间的 7 个字符的前缀,以减少冲突的可能性。

【讨论】:

  • 我会检查的!但是你接受会有碰撞的事实吗?在我看来,基于随机值的方法可能会成为问题,因为如果不基于时间戳,从长远来看,冲突会增加。
  • 添加了时间戳信息。这取决于您生成的速度以及您想要多少个 id(以毫秒为单位)。没有可以生成无碰撞生成的标准。更多的 id 会增加 id 生成器的宽度以减少碰撞。
【解决方案5】:

这里有一个更好的解决方案。

这个逻辑可以在不使用任何库的情况下构建,因为有时导入 lambda 函数层会变得很困难。您可以在下面找到将生成唯一 id 并将其保存在 SQS 队列中的代码链接,而不是会产生写入、获取和删除 id 成本的 DB。

还提供了一个 cloudformation 模板,您可以将其部署到您的帐户中,它将设置整个应用程序。链接中提供了详细说明。

请参考以下链接。

https://github.com/tanishk97/UniqueIdGeneration_AWS_CFT/wiki

【讨论】:

  • add context to your link,以便您的其他用户知道它是什么以及它为什么存在,然后引用您链接到的页面中最相关的部分,以防目标页面不可用.可能会删除仅是链接的答案。
【解决方案6】:

如果你使用 node js 运行时,你可以使用这个

const crypto = require("crypto")
const uuid = crypto.randomUUID() 

import { randomUUID } from 'crypto'
const uuid = randomUUID()  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多