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

时间:2019-04-04 20:14:48

标签: amazon-dynamodb aws-lambda-edge

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

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

这使我无法在lambda环境中使用AWS_REGION。例如,如果一个请求在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明智地选择一个存在我的数据的区域。

编辑

此后,我发现了this,这是一个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;    
    }   
}

上述研讨会的readme仅讨论了使用全局表来减少延迟的选项,但没有提供有关如何选择最接近的具有数据的表的见识。

编辑2

我已经从云中获取了延迟数据的副本,并整理了目前有效的以下要点。

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

明显的缺点是数据过时了。不幸的是,clouding的api不够快,为此,一旦我转到远程资源以获取最新数据,我可能还只是去了任何区域的DynamoDB表¯\ _(ツ)_ /

1 个答案:

答案 0 :(得分:0)

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

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

如果不复制表,则过程将稍有不同:

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

请注意,数据管道不支持新的按需DynamoDB设置。如果您沿这条路线走,则在导出时需要重新配置表以使用旧样式的设置。

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

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

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