【发布时间】:2020-02-19 23:45:43
【问题描述】:
Edit x1:将 sn-p 替换为完整文件
我目前正在 DynamoDB 中播种 1.8K 行。创建用户时,需要生成并插入这些行。它们不需要立即阅读(比方说,在不到 3 - 5 秒内)。我目前正在使用 AWS Lambda,但遇到了超时异常(可能是因为消耗的 WCU 多于预置的 WCU,我有 5 个禁用了 Auto-Scaling)。
我尝试在 Google 和 StackOverflow 周围进行搜索,这似乎是一个灰色区域(这有点奇怪,考虑到 DynamoDB 被宣传为每秒处理大量数据的令人难以置信的解决方案),其中不存在明确的路径.
我们知道 DynamoDB 限制每批 25 个项目的插入,以防止 HTTP 开销。这意味着我们可以调用无限数量的 batchWrite 并增加 WCU。
我尝试通过触发它而不等待它们来调用无限数量的batchWrite(这会算吗?我已经读过,由于JS是单线程的,所以无论如何都会一个一个地处理请求,除非我不会如果我不使用承诺,则不必等待响应......目前使用节点 10 和 Lambda),似乎什么都没有发生。如果我承诺调用并等待它,我会得到一个 Lambda 超时异常(可能是因为它用完了 WCU)。
我目前有 5 个 WCU 和 5 个 RCU(对于这些随机尖峰操作来说这些太小了吗?)。
我有点卡住了,因为我不想在短时间内随机增加 WCU。此外,我了解到 Auto-Scaling 不会自动启动,亚马逊每天只会调整容量单位 4 次。
- How to write more than 25 items/rows into Table for DynamoDB?
- https://www.keithrozario.com/2017/12/writing-millions-of-rows-into-dynamodb.html
我该怎么办?
这是我用来插入 DynamoDB 的完整文件
const aws = require("aws-sdk");
export async function batchWrite(
data: {
PutRequest: {
Item: any;
};
}[]
) {
const client = new aws.DynamoDB.DocumentClient({
region: "us-east-2"
});
// 25 is the limit imposed by DynamoDB's batchWrite:
// Member must have length less than or equal to 25.
// This verifies whether the data is shaped correctly and has no duplicates.
const sortKeyList: string[] = [];
data.forEach((put, index) => {
const item = put.PutRequest.Item;
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
const hasPk = has.call(item, "pk");
const hasSk = has.call(item, "sk");
// Checks if it doesn't have a sort key. Unless it's a tenant object, which has
// the accountType attribute.
if (!hasPk || !hasSk) {
throw `hasPk is ${hasPk} and hasSk is ${hasSk} at index ${index}`;
}
if (typeof item["pk"] !== "string" || typeof item["sk"] !== "string") {
throw `Item at index ${index} pk or sk is not a string`;
}
if (sortKeyList.indexOf(item.sk) !== -1) {
throw `The item @ index ${index} and sortkey ${item.sk} has duplicate values`;
}
if (item.sk.indexOf("undefined") !== -1) {
throw `There's an undefined in the sortkey ${index} and ${item.sk}`;
}
sortKeyList.push(put.PutRequest.Item.sk);
});
// DynamoDB only accepts 25 items at a time.
for (let i = 0; i < data.length; i += 25) {
const upperLimit = Math.min(i + 25, data.length);
const newItems = data.slice(i, upperLimit);
try {
await client
.batchWrite({
RequestItems: {
schon: newItems
}
})
.promise();
} catch (e) {
console.log("Total Batches: " + Math.ceil(data.length / 25));
console.error("There was an error while processing the request");
console.log(e.message);
console.log("Total data to insert", data.length);
console.log("New items is", newItems);
console.log("index is ", i);
console.log("top index is", upperLimit);
break;
}
}
console.log(
"If no errors are shown, creation in DynamoDB has been successful"
);
}
【问题讨论】:
-
拆分它们并将它们发送到 SQS,然后有一个 lambda 触发器。这将允许一些 lambda 并发
-
@LostJon 您是指 Lambda 到 SQS,然后是 Lambda 到 DynamoDB?
-
是的!您将有一个 lambda 来将消息分发到 SQS,然后是一个由 SQS 消息触发的 lambda,类似于您在此处的内容,以写入 DDB
标签: javascript node.js aws-lambda amazon-dynamodb