5

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

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

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

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

我想也许我可以按照下面的示例在代码中映射区域

const process = { env: { AWS_REGION: 'us-east-1' } };

const regions = {
  'eu-west-1': ['eu-west-1', 'eu-central-1', '...'],
  'us-east-2': ['us-west-1', 'us-east-1', '...'],
};

const activeRegions = Object.keys(regions);

const region = activeRegions.find(
  key => regions[key].includes(process.env.AWS_REGION)
) || activeRegions[0];

console.log(region) // us-east-2

这感觉就像它的维护比它的价值更多,并且依赖于我对最佳选择区域的假设。我还必须更新我的地区列表。

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

const process = { env: { AWS_REGION: 'ca-central-1' } };

const regions = {
  'eu-west-1': ['eu', 'sa', 'ap', '...'],
  'us-east-2': ['us', 'ca', 'sa', '...'],
};

const activeRegions = Object.keys(regions);

const key = activeRegions.find(
  key => regions[key].includes(
    process.env.AWS_REGION.substring(0, 2) // Just the first 2 letters
  )
) || activeRegions[0];

console.log(key); // us-east-2

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

编辑

从那以后我发现了这个,一个已被删除的 aws lambda@edge 研讨会,它提出了与上述类似的方法。为什么它被删除我不知道。

function updateDynamoDbClientRegion(request) {  
    let region; 

     // Check if viewer country header is available 
    if (request.headers['cloudfront-viewer-country']) { 
        const countryCode = request.headers['cloudfront-viewer-country'][0].value;  
        region = countryToRegionMapping[countryCode];   
    }   

     // Update DynamoDB client with nearer region   
    if (region) {   
        ddb = ddbUS;    
    }   
}

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

编辑 2

我从 cloudping 中获取了延迟数据的副本,并将以下要点拼凑在一起,现在可以使用。

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

这样做的缺点显然是数据陈旧。不幸的是,cloudping 的 api 对于此目的还不够快,一旦我去远程资源获取最新数据,我还不如去任何地区的 DynamoDB 表¯\_(ツ)_/ ¯

4

1 回答 1

0

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

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

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

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

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

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

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

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

于 2019-04-05T07:24:13.857 回答