![](/img/trans.png)
[英]How to add IAM permission to cloudfront in order to associate lambda@edge?
[英]How to select the correct region with Dynamodb Global Tables and Lambda@edge?
我創建了一個 Lambda function 從 DynamoDB 檢索一些數據,它會 output 一些 JSON。我想做的是在 lambda@edge 中運行這個 function 並生成一個響應,我可以使用 Cloudfront 緩存它。
我面臨的問題是我在 DynamoDB 中的數據使用全局表在(當前)兩個區域(us-east-2 和 eu-west-1)中復制,而 lambda@edge 顯然在許多區域運行。
這使我無法在 lambda 環境中使用AWS_REGION
。 例如,如果一個請求在 us-west-1 中運行,環境變量將反映這一點,並且它會嘗試從 us-west-1 檢索數據,實際上它應該是 go 到 us-east-2。
誠然,我還沒有嘗試過這個(但)我想知道是否可以在 Route53 中設置我自己的基於延遲的路由,以在我使用的區域中指向 DynamoDB 的端點說 ddb.mydomain.com,假設設置了 SAN 證書它會工作嗎?
我想也許我可以按照下面的示例在代碼中使用 map 個區域
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 workshop 已經被刪除,這表明與上述類似的方法。 為什么它被刪除我不知道。
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 速度不夠快,一旦我將 go 連接到遠程資源以獲取最新數據,我還不如去任何地區的 DynamoDB 表 ¯\_(ツ)_/ ¯
關於您對Global Tables的最后評論; 當前無法將表從特定區域重新配置為全局表。 當前有兩個選項,具體取決於是否復制表(即是否包含相同的數據)。 如果它們包含相同的數據:
如果不復制表,則過程將稍有不同:
請注意,數據管道不支持新的按需DynamoDB設置。 如果沿着這條路線走,則在導出時需要重新配置表以使用舊樣式的設置。
我希望這有幫助。 我認為您的問題到最后是關於移到全局表的,此時lambda @ edge將只使用最近的表。 但是我不確定這是否是您需要的幫助?
編輯:看看,我現在意識到這並不能真正解決您的問題。 即使使用全局表,您仍需要指定一個區域(即,即使將自動復制數據,也要從哪個區域讀取)。 因此,您的問題仍然是,要使用哪個區域進行讀/寫?
編輯:只是為了確認,您是否擔心命中錯誤的數據庫並丟失數據,或者獲取最近的數據庫以減少延遲? 如果是前者,則全局表的所有內容對您來說都可以正常工作,因為當您將數據寫入本地數據庫時,數據將自動跨區域復制。
抱歉,這真的很舊,但萬一有人需要解決方案。 假設您有 3 個副本區域: us-west-2
、 us-east-1
和eu-west-2
。
在您的 CDK 堆棧中(或在控制台中手動創建它):
REGIONS.map(region => {
new CfnRecordSet(stack, `Latency ${region}`, {
setIdentifier: `lbr_${region}`,
name: `lbr.example.com`,
type: 'TXT',
hostedZoneId: '<Zone ID>',
region,
ttl: '31540000', // 1 year in seconds
resourceRecords: [`"${region}"`]
})
})
這將在每個區域中創建 3 個 TXT 延遲記錄,其中包含該區域的值。
在您的服務器代碼中:
import dns from 'dns/promises'
const res = await dns.resolveTxt('lbr.example.com')
// TODO: handle errors, eg catch and default to us-east-1
const lowestLatencyRegion = res[0][0]
// connect to dynamo
new DynamoDBClient({region: lowestLatencyRegion})
您可以通過部署然后從不同區域的代理服務訪問服務器來驗證這一點。 記錄“lowestLatencyRegion”以查看它確實靠近您的副本區域之一。
編輯:您可能想要運行process.env.AWS_REGION
的預檢查以查看它是否在您的副本區域之一中以跳過 TXT 查找。 這將為您節省幾毫秒的查找時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.