查询和更新 dynamoDb 的最有效方式
Most efficient way to query and update dynamoDb
我有一个 dynamo DB table 将用于存储失败的请求,稍后另一个 lambda 将要读取请求并重新处理它们。
目前我正在使用打字稿 CDK
创建这样的 table
const myTable = new dynamodb.Table(this, "my-table", {
tableName: "my-table-name",
partitionKey: { name: "file_id", type: dynamodb.AttributeType.STRING },
});
我在 python lambda
中像这样将数据发送到 table
dynamodb = boto3.resource("dynamodb", region_name=region)
my_table = dynamodb.Table("my-table-name")
failedRecord = {
"file_id": str(file_id),
"processed": "false",
"payload": str(payload),
}
my_table.put_item(Item=failedRecord)
现在我想从另一个 lambda 做的是 table 中的所有条目 processed = false 我想阅读它们,对它们做一些事情,然后更新它们的 processed = true。
我需要在这里添加二级索引才能提高效率吗?如何执行此操作的示例会很棒。
谢谢
假设您的 filenote_id
已经是唯一的(假设您已将其设置为分区键),使用您共享的记录格式和 table 架构 GSI 而无需添加排序键不会有任何区别。
您可以考虑的另一种方法是启用 DynamoDB Stream for the Table in question and set it as a trigger of the second Lambda Function。
使用这种方法,您基本上会捕获 table 上的所有活动,并且在您的逻辑中,您可以过滤掉所有不是 INSERT
的事件,并按照您自己的节奏处理您感兴趣的事件。
这样您就可以完全避免查询 table。
考虑创建一个包含仅 未处理项目的全局二级索引。您可以通过 adding/removing GSI 主键从 GSI 中 add/remove 项目。例如,考虑以下 table 结构:
请注意,只有 file_id
3 和 4 定义了 GSIPK。 GSI 在逻辑上看起来像这样:
DynamoDB 只会将项目投影到该项目上存在 GSIPK 的索引中。您的 lambda 可以从 GSI 读取,做一些工作,将 processed
属性设置为 true
并删除 GSIPK
值。这将有效地从二级索引中删除该项目。
update
调用 DynamoDB 来执行此操作看起来像这样:
const params = {
TableName: YOUR_TABLE_NAME_HERE,
Key: {
PK: FILE_ID_HERE
},
UpdateExpression: "SET #processed = :true REMOVE #gsipk",
ExpressionAttributeNames: {
"#processed": "processed",
"#gsi1pk": "GSIPK",
},
ExpressionAttributeValues: {
":true": true
}
};
ddbClient.update(params);
我有一个 dynamo DB table 将用于存储失败的请求,稍后另一个 lambda 将要读取请求并重新处理它们。
目前我正在使用打字稿 CDK
创建这样的 tableconst myTable = new dynamodb.Table(this, "my-table", {
tableName: "my-table-name",
partitionKey: { name: "file_id", type: dynamodb.AttributeType.STRING },
});
我在 python lambda
中像这样将数据发送到 tabledynamodb = boto3.resource("dynamodb", region_name=region)
my_table = dynamodb.Table("my-table-name")
failedRecord = {
"file_id": str(file_id),
"processed": "false",
"payload": str(payload),
}
my_table.put_item(Item=failedRecord)
现在我想从另一个 lambda 做的是 table 中的所有条目 processed = false 我想阅读它们,对它们做一些事情,然后更新它们的 processed = true。
我需要在这里添加二级索引才能提高效率吗?如何执行此操作的示例会很棒。
谢谢
假设您的 filenote_id
已经是唯一的(假设您已将其设置为分区键),使用您共享的记录格式和 table 架构 GSI 而无需添加排序键不会有任何区别。
您可以考虑的另一种方法是启用 DynamoDB Stream for the Table in question and set it as a trigger of the second Lambda Function。
使用这种方法,您基本上会捕获 table 上的所有活动,并且在您的逻辑中,您可以过滤掉所有不是 INSERT
的事件,并按照您自己的节奏处理您感兴趣的事件。
这样您就可以完全避免查询 table。
考虑创建一个包含仅 未处理项目的全局二级索引。您可以通过 adding/removing GSI 主键从 GSI 中 add/remove 项目。例如,考虑以下 table 结构:
请注意,只有 file_id
3 和 4 定义了 GSIPK。 GSI 在逻辑上看起来像这样:
DynamoDB 只会将项目投影到该项目上存在 GSIPK 的索引中。您的 lambda 可以从 GSI 读取,做一些工作,将 processed
属性设置为 true
并删除 GSIPK
值。这将有效地从二级索引中删除该项目。
update
调用 DynamoDB 来执行此操作看起来像这样:
const params = {
TableName: YOUR_TABLE_NAME_HERE,
Key: {
PK: FILE_ID_HERE
},
UpdateExpression: "SET #processed = :true REMOVE #gsipk",
ExpressionAttributeNames: {
"#processed": "processed",
"#gsi1pk": "GSIPK",
},
ExpressionAttributeValues: {
":true": true
}
};
ddbClient.update(params);