SQL Server 連接池和最大連接數(shù)占用內(nèi)存和CPU硬件資源分析研究
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
連接到數(shù)據(jù)源可能需要很長時間。為了最大程度地降低打開連接的成本,ADO.NET 使用一種稱為 連接池的優(yōu)化技術(shù),這會最大程度地降低重復(fù)打開和關(guān)閉連接的成本。.NET Framework 數(shù)據(jù)提供程序處理連接池的方式有所不同。 連接到數(shù)據(jù)庫服務(wù)器通常由幾個需要很長時間的步驟組成。必須建立物理通道(例如套接字或命名管道),必須與服務(wù)器進(jìn)行初次握手,必須分析連接字符串信息,必須由服務(wù)器對連接進(jìn)行身份驗證,必須運行檢查以便在當(dāng)前事務(wù)中登記,等等。 實際上,大多數(shù)應(yīng)用程序僅使用一個或幾個不同的連接配置。這意味著在執(zhí)行應(yīng)用程序期間,許多相同的連接將反復(fù)地打開和關(guān)閉。為了最大程度地降低打開連接的成本,ADO.NET 一種稱為連接 池 的優(yōu)化技術(shù)。 連接池使新連接必須打開的次數(shù)得以減少。池程序維持物理連接的所有權(quán)。通過為每個給定的連接配置保留一組活動連接來管理連接。每當(dāng)用戶在連接上調(diào)用 Open 時,池進(jìn)程就會查找池中可用的連接。如果某個池連接可用,會將該連接返回給調(diào)用者,而不是打開新連接。應(yīng)用程序在該連接上調(diào)用 Close 時,池進(jìn)程會將連接返回到活動連接池集中,而不是關(guān)閉連接。連接返回到池中之后,即可在下一個 Open 調(diào)用中重復(fù)使用。 在 SQL Server 中,user connections 選項可配置實例建立的最大用戶連接數(shù),默認(rèn)值為 0,表示最大連接數(shù)為 32767。實際上允許的用戶連接數(shù)還取決于正使用的 SQL Server 版本以及應(yīng)用程序和硬件的限制。 那么,數(shù)據(jù)庫的連接數(shù),與客戶端連接池有什么樣的關(guān)系呢? 帶著這個疑問,我設(shè)計了一個方案,想了解它們之間有什么相互影響。
測試代碼如下:
我們可以查看 SQL Server 設(shè)置的最大連接數(shù),[userconnections] run_value=0(默認(rèn)值為0即最大值32767) 測試一: 設(shè)置max poolsize=40000,即連接池40000,MSSQL 連接限制32767 以上監(jiān)控可以看到,MSSL 連接峰值為32717,加上數(shù)據(jù)庫系統(tǒng)自己默認(rèn)占有的50個連接,總數(shù)為32767,即為數(shù)據(jù)庫的最大連接數(shù)。在連接過程中,CPU和內(nèi)存開銷很大! 在出錯的情況下還繼續(xù)創(chuàng)建對象,但是數(shù)據(jù)庫連接數(shù)是沒有增加的,連接對象都保存到連接池中,還在等待連接數(shù)據(jù)庫。 當(dāng)連接池連接數(shù)達(dá)到最大值時,如下圖到達(dá) 39999 時,程序?qū)⒆詣雨P(guān)閉并退出!本人電腦幾乎卡死!數(shù)據(jù)庫連接數(shù)回到正常,數(shù)據(jù)庫內(nèi)存仍然很大,還是很卡!最后重啟數(shù)據(jù)庫服務(wù)釋放內(nèi)存! 測試二: 設(shè)置max poolsize=3000,即連接池3000,MSSQL 連接限制32767 客戶端連接池最大連接為3000,再新建連接時,會因超時不能添加到連接池中,結(jié)果失敗! 數(shù)據(jù)庫系統(tǒng)當(dāng)前最多可連接32767,現(xiàn)在只連接3000+系統(tǒng)session,為3019。此時數(shù)據(jù)庫系統(tǒng)還可以繼續(xù)創(chuàng)建連接,只是此客戶端連接池限制而已。正常業(yè)務(wù)情況下,連接池會盡快處理沒有用的連接,讓客戶端建立新的連接。 在數(shù)據(jù)庫中,我刪除1000個 sleeping 的 session:
數(shù)據(jù)庫連接是降下來了,但是連接池還是沒有降。因為新的連接還是無法通過連接池。所以也不要刪除數(shù)據(jù)庫中 sleeping 的 session,因為連接池如果再重用連接的話,找不到數(shù)據(jù)庫中的對應(yīng)連接就斷開了! 測試三: 設(shè)置max poolsize=40000,即連接池40000,MSSQL 連接限制3000 MSSQL 中執(zhí)行以下代碼,然后重啟數(shù)據(jù)庫服務(wù):
當(dāng)通過連接池連接數(shù)據(jù)達(dá)到2982時,發(fā)生了錯誤。加上數(shù)據(jù)庫系統(tǒng)中的18個session,連接總數(shù)為3000. 這個錯誤網(wǎng)上很常見,連接池雖然可以繼續(xù)創(chuàng)建新的連接,但是無法與數(shù)據(jù)庫端連接。出現(xiàn)此錯誤可以判斷是數(shù)據(jù)庫端沒法連接到。如果不是最大連接數(shù)出錯,可能是tcp/ip協(xié)議未開啟、端口未打開或被隔離等。 成功與服務(wù)器建立連接,但是在登錄前的握手期間發(fā)生錯誤。(provider:tcp provider error:0 –指定的網(wǎng)絡(luò)名不可再用。) 接下來在數(shù)據(jù)庫中,刪除1000個sleeping的session:
連接又可以正常進(jìn)行了。 以上測試總結(jié)如下: 現(xiàn)在,我們再做多幾個測試,驗證物理連接和連接池重用連接的耗時。 測試四: 連接池重用: 設(shè)置max poolsize=40000,即連接池40000,MSSQL 連接限制0(32767)。循環(huán)次數(shù):40000 物理連接重建: 設(shè)置max poolsize=4000,即連接池4000,MSSQL 連接限制0(32767)。循環(huán)次數(shù):4000 本打算物理連接都設(shè)置40000,不過時間較久,這里測試4000,屆時可多十倍時間來對比重用連接池的時間。
如重建次數(shù)增加10倍為40000,則平均時間比為 13:421,即重建/重用=32。重建連接比重用連接池所花費時間多32倍!所以現(xiàn)在的各種系統(tǒng)連接數(shù)據(jù)庫,基本使用連接池。但是連接池也不能過多,否則一直占用系統(tǒng)資源,又用不上。 測試五:關(guān)閉連接池后數(shù)據(jù)庫會話狀態(tài) 現(xiàn)在把連接池關(guān)閉 pooling=false,每次打開或者關(guān)閉連接時,console暫停。
此時我們查看MSSQL中的連接session。(在c#連接我是sa登錄的)
關(guān)閉連接時再查看。Session 已經(jīng)關(guān)閉了。下次再連接,就是新的一個物理連接了。 總結(jié): 連接池與MSSQL連接關(guān)系: 連接池連接與物理連接耗時對比: 關(guān)閉連接池: 每次連接數(shù)據(jù)庫都是一次物理連接,關(guān)閉連接時,數(shù)據(jù)庫session也關(guān)閉 閱讀原文:原文鏈接 該文章在 2025/1/10 10:35:44 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |