Dot-Net

加快 IIS/.NET/LINQ 從網路緩衝區檢索數據的速度

  • March 3, 2011

在對我的 Web 伺服器和數據庫伺服器之間的流量進行 TCP 分析時,我看到網路緩衝區(TCP 視窗)經常被填滿。然後,Web 伺服器向數據庫伺服器發送 TCP 消息,告訴它其緩衝區已滿,並且在得到更新之前不要發送更多數據。

例如,這是網路緩衝區的大小(以字節為單位),用於與數據庫伺服器的較長壽命連接之一:

網路緩衝區圖

Web 伺服器在 Windows 2008 R2 Web 伺服器上執行以 IIS 集成模式執行的 .NET 4.0 應用程序。SQL 伺服器是 2008 R2 伺服器。

我對此的解釋是,SQL 伺服器向 Web 伺服器返回數據的速度比 Web 伺服器上的應用程序可以從緩衝區收集數據的速度更快。我已經嘗試調整網路驅動程序中的所有內容來解決這個問題。特別是增加 RSS 隊列、禁用中斷調節以及設置 Windows 2008 R2 伺服器以更積極地增加緩衝區大小。

因此,如果我的解釋是正確的,那讓我想知道兩種可能性:

  1. .NET 中有什麼方法可以告訴它增加網路緩衝區的大小嗎?“增強的 2008 R2 TCP 堆棧”很少決定為此連接啟用視窗縮放(使緩衝區大於 65 kBytes)(可能是由於低延遲)。看起來手動設置這個系統範圍的能力在 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
睡眠任務 231661274 337253925 10808 71665032
LATCH_EX 214958564 894509148 11855 84816450
SOS_SCHEDULER_YIELD 176997645 227440530 2997 227332659
ASYNC_NETWORK_IO 112914243 84132232 16707 16250951
  1. 是什麼讓您認為這是 TCP 流量控制,而不是 SQL Server 在沒有流量的時間間隔內不生成數據?檢查是否sys.dm_exec_requests查看wait_type。等待類型在等待和隊列中描述。如果確實是客戶端應用 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 視圖寫入響應緩衝區並被 TCP 流控制依次阻止,這是由於使用者代理未使用 HTTP 響應(例如,Ajax 呼叫已完成但瀏覽器未執行)使用響應的完成程式碼,因為主執行緒正在忙於其他事情)。與往常一樣,最好的方法是有條不紊地進行測量。一些可能的工具:

引用自:https://stackoverflow.com/questions/5175238