.net - Npgsql 在高负载场景下使用 Redshift 的低数据检索性能
问题描述
应用程序使用 Npgsql 4.1.5 和 .NET 框架 4.6.2。此应用程序对 Redshift DB具有只读访问模式。
应用程序托管在 IIS 7.5 windows server 2016 上,位于私有云中的 16 个 CPU 内核 256 GB RAM 实例上,通过 VPC 访问 AWS Redshift。
与 Redshift 查询执行统计数据相比,主要问题是应用程序端的数据检索时间较长。在高负载情况下,每分钟 3K 查询。在此期间,使用了 100 个 DB 连接,CPU 利用率为 80-100%。每个查询通常检索 1K-50K 行,最多包含 10 个字段。
Redshift 查询总执行时间(按百分位),秒
p50 | p80 | p90 | p99
0,16 | 0,3 | 0,59 | 5,31
NpgSQL 命令执行时间(按百分位),秒
p50 | p80 | p90 | p99
1,23 | 4,92 | 9,81 | 18,13
NpgSQL 命令执行时间是通过文档中描述的记录器实现来收集的。“开始用户操作”和“最终用户操作”之间的时间。
以下是连接字符串演示的最佳结果:
Minimum Pool Size=5; Maximum Pool Size=100; Connection Idle Lifetime=300; Command Timeout=0; Timeout=120; Keepalive = disabled; Max Auto Prepare = 5000; Auto Prepare Min Usages=5; Enlist=false; No Reset On Close = true
典型的访问模式:
using (DbConnection connection = NpgsqlFactory.Instance.CreateConnection())
{
connection.ConnectionString = connectionString;
if (connection.State != ConnectionState.Open)
connection.Open();
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = query;
using (var dataReader = command.ExecuteReader())
{
while (dataReader.Read())
{
object[] values = new object[dataReader.FieldCount];
for (int i = 0; i < dataReader.FieldCount; i++)
{
values[i] = dataReader.GetFieldValue<object>(i);
}
}
}
}
}
感谢有关如何针对这种情况改进 npgsql 性能的任何建议。
UPD: 经过API profiling可以确认API端延迟的实际原因是网络读取操作。通常从套接字读取查询结果需要 50-200 毫秒,但在负载下,它会达到 3-15 秒的峰值。
从网络流中读取发生在这里: https ://github.com/npgsql/npgsql/blob/main/src/Npgsql/NpgsqlReadBuffer.cs line 179 buffer.Underlying.Read(...)
解决方案
推荐阅读
- java - 如何更改我的正则表达式以拒绝下划线
- windows - BAT 文件中的“输入行太长”错误
- android - Android:将数据从 RecyclerView 传递到另一个 Activity
- javascript - 将firebase云功能拆分为不同文件的正确方法是什么?
- python - Python Pandas 使用 for 循环添加行的问题
- python - 如何将 DASK 数据帧放入 MySQL 数据表?
- python - SWIG 将 C++ 扩展到 Python,未定义的枚举
- reactjs - 在反应中显示表格数据的更好方法
- python - REGEX - 查找特定的 XML 标记并通过它进行解析
- java - 如何把数字时间变成英文名字