2011-03-03 20 views
13

对我的Web服务器和数据库服务器之间的流量进行TCP分析时,我发现网络缓冲区(TCP窗口)经常被填满。 Web服务器然后发送TCP消息到数据库服务器,告诉它它的缓冲区已满并且在给定更新之前不发送更多的数据。加快IIS/.NET/LINQ从网络缓冲区检索数据的速度

例如,这是字节网络缓冲区的用于越长寿命到数据库服务器连接中的一个的大小随时间:

Network Buffer Graph

web服务器运行的.NET 4.0应用程序在Windows 2008 R2 Web服务器上以IIS集成模式运行。 SQL服务器是2008 R2服务器。

我的解释是,SQL服务器将数据更快地返回到Web服务器,然后Web服务器上的应用程序可以从缓冲区收集数据。我尝试过调整网络驱动程序中的所有内容来解决此问题。特别是增加RSS队列,禁用中断审核以及设置Windows 2008 R2服务器以更积极地增加缓冲区大小。

所以,如果我的理解是正确的,让我想了解一下两种可能性:

  1. 是否有.NET没有办法告诉它来增加网络缓冲区的大小? “增强的2008 R2 TCP堆栈”很少决定为此连接启用窗口缩放(使缓冲区大于65 kB)(可能是由于延迟较低)。它看起来像手动设置这个系统范围的能力在Windows Server 2008 r2中没有了(以前是注册表项,现在被忽略了)。那么有没有一种方法可以在代码中强制执行?
  2. 是否有任何可以调整的方法来加快应用程序读取网络缓冲区信息的速度,特别是SQL连接的速度?

编辑:
要求DMV查询切断在ASYNC_NETWORK_IO:

SELECT * FROM sys.dm_os_wait_stats ORDER BY waiting_tasks_count desc; 
 
wait_type waiting_tasks_count wait_time_ms max_wait_time_ms signal_wait_time_ms 
CXPACKET   1436226309 2772827343    39259   354295135 
SLEEP_TASK   231661274  337253925    10808   71665032 
LATCH_EX    214958564  894509148    11855   84816450 
SOS_SCHEDULER_YIELD 176997645  227440530    2997   227332659 
ASYNC_NETWORK_IO  112914243  84132232    16707   16250951 
+2

这是我将谈论微软的一个问题直接上。打开支持服务单或使用免费的MSDN电话(如果有的话)。 – 2011-03-03 12:54:52

+0

凯尔的后续行动:http://blog.serverfault.com/post/views-of-the-same-problem-network-admin-dba-and-developer/ – 2011-03-20 19:52:19

回答

11

1)是什么让你认为这是TCP流量控制,而不是到SQL Server不产数据在没有流量的时间间隔内?检查sys.dm_exec_requests是否看wait_type。等待类型在Waits and Queues中描述。如果确实是应用TCP流量控制的客户端,那么您将看到等待类型ASYNC_NETWORK_IO

2)如果的问题确实是网络等待类型,那么解决的办法不是增加带宽,而是显然要减少流量。客户端没有业务请求来自服务器的太多数据以导致TCP流量控制。这可能是由于在客户端做了可怕的错误事件,比如计数行或客户端分页。移动服务器上的处理,只需要获取所需数据的小结果集。

编辑

消费数据库调用结果最终定归结为某种形式的这样:

FetchNextRow 
while (not EnfOfResults) 
{ 
    ProcessRow; 
    FetchNextRow; 
} 

什么,这可能意味着,在现实条件,也可能是foreach row in IQueryableSqlDataReader.Read() 。但基本的想法是一样的,客户端从结果中获取行,处理它们,然后获取更多的行。如果客户端代码的中有,那么ProcessRow会阻塞,那么客户端代码将不会到达它再次获取下一行的位置,从而最终将触发TCP流量控制,从而导致SQL Server暂停查询(因为它没有地方把结果写入)。在TCP方面你没有办法做到这一点。实际上,增加窗口大小实际上可能会使主机变得更糟,因为现在所有先前在源(DB)处被抑制的结果都将被创建并且必须存储在某处,这最终意味着分配给存储器的实时内存并可能使事情变得更糟比现在更糟糕。

如果我现在在你的鞋子里,我会专注于识别,其中确实会阻止ProcessRow发生阻塞。我提出的一个假设是,处理将是一个MVC视图写入响应缓冲区,并被用户代理不使用HTTP响应导致的TCP流量控制轮流阻止(例如,Ajax调用已完成,但浏览器未运行由于主线程正在忙于其他事务,因此消耗响应的完成代码)。一如既往,最好的方法是有条不紊地衡量。一些可能的工具:

+0

RE 1)为什么TCP流量控制?我看到很多从Web服务器到SQL服务器的“零窗口消息”(每个Web服务器每分钟大约500个)。我也经常看到缓冲区在〜200-300字节左右徘徊。所以我想这是窗口接近于零的时间刻度。然而,当它达到零时,窗口更新非常快(2-3MS)。我现在去看看等待的DMV现在... – 2011-03-03 01:18:28

+0

更新我的问题,包括DMV查询。 ASYNC_NETWORK_IO正在显示,但如果这比应该更高,我有点无知。想要查看我的“SQL Server 2008内部”新副本,看看我是否无法学习如何深入了解导致此问题的查询。 – 2011-03-03 01:32:08

+0

最大等待时间16707 ms意味着至少有一项任务需要等待+16秒才能释放网络,这将证实您的初步结论。但是这也表明应用程序执行了一个DB请求,然后在读取结果(空闲缓冲区)的时间长达16秒时没有任何麻烦。鉴于这是ASP,需要研究的一件事是用户代理拥塞是否可以阻止您的IIS/ASP缓冲区,这会导致您的ASP线程等待输出缓冲区,从而使其忽略数据库请求。 – 2011-03-03 01:37:44