C# Web API SQL Server 2012:负载测试下的错误(1400万+条记录)



我正在尝试构建一个Web API,该API连接到SQL Server 2012数据库,该数据库在单个表中具有1400万+条记录。API 的唯一操作是 GET,并将作为开放数据 API 向公众开放,因此它需要能够处理许多并发用户。

该表有七个字段:

field1 bigint  
field2 nvarchar(50)  
field3 nvarchar(10)  
field4 float  
field5 datetime  
field6 nvarchar(20)  
field7 nvarchar(10)  

我用以下语言编写了简单的测试 API:
- C# .NET 4.6.1
- C# .NET Core 2

我还尝试过将ApirIO作为Nuget包和命令行应用程序。

我也尝试过将Python Eve与SQLAlchemy一起使用,但结果相似。

API 的工作原理是我可以在我的浏览器、邮递员、cURL 等上看到结果。但是当我尝试以每秒 30 个请求(测试持续时间 30 秒)的速度使用 Vegeta 加载测试时,我遇到了多个连接错误,延迟上升到 30 秒左右。

我已经在 AperIO 命令行应用程序上运行的 API 上粘贴了负载测试的结果:

Requests      [total, rate]            900, 30.03
Duration      [total, attack, wait]    59.9700536s, 29.966666367s, 30.003387233s
Latencies     [mean, 50, 95, 99, max]  29.903549803s, 30.002625352s, 30.004389905s, 30.012575115s, 30.03090955s
Bytes In      [total, mean]            49579, 55.09
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  1.22%
Status Codes  [code:count]             200:11  0:889  
Error Set:
Get http://localhost:18092/xyz?pageSize=25: net/http: timeout awaiting response headers

我尝试过带或不带 OData 的 C#,以及最大页面大小设置为 50、25、10、5 的手动编码分页类,但结果都大致相似。

注意:我截断了表并重新填充了 5000 条记录,负载测试没有问题。我重新填充了 1400 万条记录,错误再次出现。

有没有办法优化SQL Server,以非常低的延迟(约0.015秒)将记录集超过1400万的数据库提供给具有多个并发用户(例如1000个用户)的API?

提前感谢,

编辑(从评论中澄清):

服务器有 RAM 32GB/内存 160GB/4 个 CPU

  • 大约 100 秒后,CPU 达到 5%,我们暂时将服务器增加到 8 个 CPU,但它们也上升到 100%

表上有聚集索引和非聚集索引

控制器中 Get 方法的 Linq 代码为:

var source = (from aqm in _context.aqm_context.
OrderBy(a => a.field1)
select aqm).AsQueryable();
var items = source.Skip((CurrentPage - 1) * PageSize).Take(PageSize).ToList();
return items;

从 SQL Server Profiler 中,正在执行的 SQL 是

SELECT 
[Extent1].[field1] AS [field1], 
[Extent1].[field2] AS [field2], 
[Extent1].[field3] AS [field3], 
[Extent1].[field4] AS [field4], 
[Extent1].[field5] AS [field5], 
[Extent1].[field6] AS [field6], 
[Extent1].[field7] AS [field7]
FROM [dbo].[table] AS [Extent1]
ORDER BY [Extent1].[field1] ASC
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY 

我最初将MongoDB与Python Eve(具有相同的记录集)一起使用,并且我获得了0.015秒的延迟,并且在运行相同的测试时没有错误。MongoDB不在我的组织批准的技术列表中,所以我被要求尝试SQL Server作为后端。我使用连接到SQL Server的SQLAlchemy尝试了相同的Eve配置,并立即收到了糟糕的延迟和连接错误。

所以问题也可能是:
SQL Server是否是一个有效的选择,可以向公众提供具有1400万记录集的开放数据API,并可能有数千个并发用户?还是像MongoDB这样的NoSQL文档存储更适合?

要回答您的问题,SQL Server 可以处理如此多的数据吗?

是的,我们已经在 4 亿行中使用它。以下是我们遵循的步骤:

  1. 我们选择了多核服务器,并在那里划分了tempdb并放在SSD上。
  2. 对我们来说,读取操作很重要,因此索引是基于此完成的。
  3. 我们通过偏移量获取启用了分页,并确保我们点击了正确的索引。
  4. 强制要求客户端
  5. 应用程序仅允许提取一定数量(并非一次性全部提取)。只允许仓储应用程序,但在非高峰时间(即凌晨 2 点)再次允许
  6. 索引可以发挥魔力,如果读取操作是优先级。
  7. 此外,我们还进行了存档,可将超过 2 年的记录移动到存档表中。这使我们桌子的大小几乎保持不变。

我想而不是问你在做什么,这对我来说不是 100% 清楚,因为有几个问题。我想分享我们如何实现绩效。同样,这不是完全证明的;但是,适用于我们的情况。对你来说,其他东西可能会起作用。

最新更新