如何优化 DynamoDB 查询响应时间?
How to optimize DynamoDB Query response time?
我们使用API 网关+Lambda 函数+DynamoDB 来获取数据并使用DynamoDB 查询方法。对于 260.4KB 数据(项目总数 count:675 | 扫描计数:3327),它需要 3.49 秒。
要求:
我们有4个以上的客户,我们每天都在计算客户销售用户的数据并将其存储在数据库中。
Table结构:
- 主键: ClientId
- 排序键:日期+用户ID
- 其他属性:日期
在查询中 - 我们正在使用主键 ClientId 和日期来获取数据。
目前,我们正在为 DynamoDB 使用按需模式,但我们觉得响应时间 > 1s 太多了。
我们有什么方法可以使用任何 AWS 配置来改进它吗?
更新[24/03/2021]
在 Lambda 中 - 我们正在使用 NodeJs。
module.exports.executeQuery = async(dynamoDbClient, queryInput) => {
return await new Promise((resolve, reject) => {
dynamoDbClient.query(queryInput, (err, users) => {
if (err) {
reject(handleQueryError(err));
}
else {
resolve({
statusCode: 200,
users,
});
}
});
});
};
配置给 Lambda 的内存 = 128 MB
你得到了 3327 个结果,所以 ~3.5 秒的响应时间并不让我感到惊讶。根据我的经验,听起来不错。
这里的根本问题是缺乏线程或并行处理。您可以很容易地证明是这样,运行 这个 CLI 命令:
aws dynamodb scan --table-name YOURTABLENAME --total-segments X --segment 0 --select COUNT
替换 YOURTABLENAME
和 X
,其中 X 应该是 table 中数据的 MB 数。所以如果你有 100MB 的数据,使用 100.
这将使用 X 线程进行并行扫描。它将在大约 1 秒内 return 并获取您 table 中的所有项目。
然后您可以尝试使用 --total-segments 1
进行扫描(其中 运行 使用一个线程),看看需要多长时间。
这表明需要在并行线程中获取大量数据。
您的分区太大。如果您尝试使用较少数据的键,可能是 10 条记录,我希望查询速度很快。
您可能想要研究 sharding techniques 以减少分区中的数据量,然后您可以并行查询这些分区。请注意,DynamoDB 不提供 BatchQuery 方法,这是一种耻辱,因此您必须编写自己的并行 Query 方法。
按照评论中的建议,我将从增加 Lambda 函数的内存大小开始。
Lambda CPU 性能随内存而变化,根据我的经验,解析来自 DynamoDB 的较大响应从更高的 CPU 性能中获益良多。
几天前我做了一个性能分析 in a blog(免责声明:我的雇主技术博客,它是主题 - 尽管是 python),发现不同内存大小的性能之间存在显着差异.
我们使用API 网关+Lambda 函数+DynamoDB 来获取数据并使用DynamoDB 查询方法。对于 260.4KB 数据(项目总数 count:675 | 扫描计数:3327),它需要 3.49 秒。
要求:
我们有4个以上的客户,我们每天都在计算客户销售用户的数据并将其存储在数据库中。
Table结构:
- 主键: ClientId
- 排序键:日期+用户ID
- 其他属性:日期
在查询中 - 我们正在使用主键 ClientId 和日期来获取数据。
目前,我们正在为 DynamoDB 使用按需模式,但我们觉得响应时间 > 1s 太多了。
我们有什么方法可以使用任何 AWS 配置来改进它吗?
更新[24/03/2021] 在 Lambda 中 - 我们正在使用 NodeJs。
module.exports.executeQuery = async(dynamoDbClient, queryInput) => {
return await new Promise((resolve, reject) => {
dynamoDbClient.query(queryInput, (err, users) => {
if (err) {
reject(handleQueryError(err));
}
else {
resolve({
statusCode: 200,
users,
});
}
});
});
};
配置给 Lambda 的内存 = 128 MB
你得到了 3327 个结果,所以 ~3.5 秒的响应时间并不让我感到惊讶。根据我的经验,听起来不错。
这里的根本问题是缺乏线程或并行处理。您可以很容易地证明是这样,运行 这个 CLI 命令:
aws dynamodb scan --table-name YOURTABLENAME --total-segments X --segment 0 --select COUNT
替换 YOURTABLENAME
和 X
,其中 X 应该是 table 中数据的 MB 数。所以如果你有 100MB 的数据,使用 100.
这将使用 X 线程进行并行扫描。它将在大约 1 秒内 return 并获取您 table 中的所有项目。
然后您可以尝试使用 --total-segments 1
进行扫描(其中 运行 使用一个线程),看看需要多长时间。
这表明需要在并行线程中获取大量数据。
您的分区太大。如果您尝试使用较少数据的键,可能是 10 条记录,我希望查询速度很快。
您可能想要研究 sharding techniques 以减少分区中的数据量,然后您可以并行查询这些分区。请注意,DynamoDB 不提供 BatchQuery 方法,这是一种耻辱,因此您必须编写自己的并行 Query 方法。
按照评论中的建议,我将从增加 Lambda 函数的内存大小开始。
Lambda CPU 性能随内存而变化,根据我的经验,解析来自 DynamoDB 的较大响应从更高的 CPU 性能中获益良多。
几天前我做了一个性能分析 in a blog(免责声明:我的雇主技术博客,它是主题 - 尽管是 python),发现不同内存大小的性能之间存在显着差异.