如何使用 Dynamodb 全局表和 Lambda@edge 选择正确的区域?

Ben*_*rne 7 amazon-dynamodb aws-lambda-edge

我创建了一个 Lambda 函数,它从 DynamoDB 检索一些数据,并输出一些 JSON。我想做的是在 lambda@edge 中运行这个函数并生成一个响应,我可以使用 Cloudfront 缓存该响应。

\n\n

我面临的问题是,我在 DynamoDB 中的数据(当前)使用全局表复制到两个区域(us-east-2 和 eu-west-1),而 lambda@edge 显然在许多区域中运行。

\n\n

这让我无法使用AWS_REGION在 lambda 环境中使用。例如,如果请求在 us-west-1 中运行,环境变量将反映这一点,并且它会尝试从 us-west-1 检索数据,而数据实际上应该转到 us-east-2。

\n\n

虽然我承认我还没有尝试过这个(但)我想知道我是否可以在 Route53 中设置自己的基于延迟的路由,以将 ddb.mydomain.com 指向我使用的区域中 DynamoDB 的端点(假设 SAN 证书是)设置一下可以吗?

\n\n

我想也许我可以根据下面的示例映射代码中的区域

\n\n
const process = { env: { AWS_REGION: \'us-east-1\' } };\n\nconst regions = {\n  \'eu-west-1\': [\'eu-west-1\', \'eu-central-1\', \'...\'],\n  \'us-east-2\': [\'us-west-1\', \'us-east-1\', \'...\'],\n};\n\nconst activeRegions = Object.keys(regions);\n\nconst region = activeRegions.find(\n  key => regions[key].includes(process.env.AWS_REGION)\n) || activeRegions[0];\n\nconsole.log(region) // us-east-2\n
Run Code Online (Sandbox Code Playgroud)\n\n

这感觉维护起来比其价值要多,并且依赖于我对最佳选择区域的假设。我还必须保持我的区域列表是最新的。

\n\n

我可以仅使用该区域的前两个字母来限制当新数据中心稍微开放时更新它的需要,但它仍然不理想

\n\n
const process = { env: { AWS_REGION: \'ca-central-1\' } };\n\nconst regions = {\n  \'eu-west-1\': [\'eu\', \'sa\', \'ap\', \'...\'],\n  \'us-east-2\': [\'us\', \'ca\', \'sa\', \'...\'],\n};\n\nconst activeRegions = Object.keys(regions);\n\nconst key = activeRegions.find(\n  key => regions[key].includes(\n    process.env.AWS_REGION.substring(0, 2) // Just the first 2 letters\n  )\n) || activeRegions[0];\n\nconsole.log(key); // us-east-2\n
Run Code Online (Sandbox Code Playgroud)\n\n

我怀疑我遗漏了一些明显的东西,这可能会让我明智地从 lambda@edge 中选择数据存在的区域。

\n\n

编辑

\n\n

我后来发现了这个一个 aws lambda@edge 研讨会,该研讨会已被删除,这表明与上述方法类似。我不知道为什么它被删除。

\n\n
function updateDynamoDbClientRegion(request) {  \n    let region; \n\n     // Check if viewer country header is available \n    if (request.headers[\'cloudfront-viewer-country\']) { \n        const countryCode = request.headers[\'cloudfront-viewer-country\'][0].value;  \n        region = countryToRegionMapping[countryCode];   \n    }   \n\n     // Update DynamoDB client with nearer region   \n    if (region) {   \n        ddb = ddbUS;    \n    }   \n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

自述文件现在只是讨论使用全局表来减少延迟的选项,但没有提供有关如何选择最接近的有数据的表的见解。

\n\n

编辑2

\n\n

我已经从云中获取了延迟数据的副本,并将目前有效的以下要点拼凑在一起。

\n\n

https://gist.github.com/benswinburne/06a00fab330dca93ea6df2552f73850a

\n\n

这样做的缺点显然是数据是陈旧的。不幸的是,cloudping 的 api 对于此目的来说不够快,一旦我转到远程资源以获取最新数据,我可能就转到了任何区域中的 DynamoDB 表 \xc2\xaf \\_(\xe3\x83\x84)_/\xc2\xaf

\n

F_S*_*O_K 0

关于您对全局表的最后评论;目前无法将表从特定区域重新配置为全局表。目前有两个选项,具体取决于您的表是否被复制(即是否包含相同的数据)。如果它们包含相同的数据:

  1. 使用 DynamoDB 备份来备份表
  2. 创建一个新的全局表
  3. 将表转储恢复到新的全局表中

如果不复制表,则过程会略有不同:

  1. 使用数据管道从表中导出数据
  2. 创建一个新的全局表
  3. 使用数据管道将转储导入全局表

请注意,Data Pipeline 不支持新的按需 DynamoDB 预配。如果您沿着这条路线走下去,则需要在执行导出时重新配置表以使用旧样式配置。

我希望这有帮助。我认为你的问题最后是关于转移到全局表,此时你的 lambda@edge 将只使用最近的表。但我不确定这是否是您需要帮助的?

编辑:刚刚看了一下,我现在意识到这并不能真正解决您的问题。即使使用全局表,您仍然需要指定一个区域(即从哪个区域读取,即使数据将自动复制)。所以你的问题仍然是,使用哪个区域进行读/写?

编辑:只是为了确认一下,您是否担心访问错误的数据库并丢失数据,或者担心获取最近的数据库以减少延迟?如果是前者,全局表对您来说效果很好,因为当您将数据写入本地数据库时,数据将自动跨区域复制。