數據庫連接瓶頸問題的思考

數據庫連接瓶頸問題的思考

背景:客戶提出如果客戶端總的連接數如果超過數據庫服務端的最大連接數,連接會不會成爲瓶頸?

Client連接池大小設置

參考來自Oracle 性能小組 : https://www.youtube.com/watch?v=xNDnVOCdvQ0&list=PLDacGuMCXBJoXiEBkULq2mn-VwwxEPK_M&index=2&t=0s
視頻中對 Oracle 數據庫進行了壓力測試,模擬 9600 個併發線程來操作數據庫,每兩次數據庫操作之間 sleep 550ms,開始設置的線程池大小爲 2048。
當數據庫連接池的大小爲 2048 性能測試結果:
每個請求要在連接池隊列裏等待 33ms,獲得連接之後,執行SQL需要耗時77ms, CPU 消耗維持在 95% 左右;
當數據庫連接池的大小爲1024 性能測試結果:
獲取連接等待時長基本不變,但是 SQL 的執行耗時降低
當數據庫連接池的大小爲 96 性能測試結果:
每個請求在連接池隊列中的平均等待時間爲 1ms, SQL 執行耗時爲 2ms.
結論:連接池數量並非越大越好

數據庫瓶頸的三個因素:CPU、磁盤IO、網絡IO

磁盤IO越慢,意味着單次查詢任務需要的時間越長,線程池數量增加;網絡IO越慢,同樣拉長單次查詢時間,線程數量同樣增加

Alt text

上圖是 PostgreSQL 的基準性能測試數據,從圖中我們可以看到,TPS 在連接數達到 50 時開始變緩。回過頭來想下,在上面 Oracle 的性能測試視頻中,測試人員們將連接數從 2048 降到了 96,實際上 96 還是太高了,除非你的服務器 CPU 核心數有 16 或 32。

參考連接數計算公式,有PostgreSQL提供:連接數 = ((核心數 * 2) + 有效磁盤數)

數據庫server連接設置

數據庫server一般是需要設定最大連接數,當連接資源耗盡,客戶端將不再能跟數據庫建立連接。mysql會拋出 has already more than ‘max_user_connections’ active connections 的錯誤,這時需要調大數據庫的max_user_connections或者將請求放入等待隊列。
應用程序建立連接:網絡連接三次握手、用戶登錄認證、用戶讀寫鑑權

mysql允許在運行時修改最大連接數,不重啓服務;oracle修改最大連接數必須重啓服務;sybase允許運行時修改最大連接數,但需要充分考慮磁盤、內存情況。

連接不足時的臨時處理方案:

  1. 通過查看當前佔着連接的線程,處理掉一些不需要保持連接的空閒連接(多個應用程序連接同一數據庫,犧牲某些應用程序以保障核心程序的運行)
  2. 減少連接過程的損耗,如使用-skip-grant-tables參數跳過權限驗證階段

建議:上文所述,對於每個數據庫客戶端的基本連接池數量與最大連接池數量,在上生產環境服務器的時候可以根據服務器的配置明確計算出來,對於一個數據庫server的最大連接數量也是可以確定的。通過提前計算出最大連接數量,儘量不要隨意增加數據庫客戶端

長效解決方案

  1. 引入緩存層,增加緩存命中率
  2. sql優化,降低sql執行時間
  3. 增加硬件配置:提升服務器性能,降低網絡開銷
  4. 根據業務場景,如果sql操作insert、update、delete的平均時間遠大於select的時間,則可以配置讀連接池與寫連接池,並專門調整每個連接池的大小,系統吞吐量會有較大幅度的提升
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章