database的connect

xuexiaogang發表於2021-12-13

自己原文公眾號: https://mp.weixin.qq.com/s/xGmMgbTm9D5gsFE1jeTW4g

幾天我被問到連線數的問題。一般來說開發都希望設定一個較大的連線數以確保程式不會出問題。

    想起我以前經歷公司,我有一次模擬併發場景,測試資料庫壓力。當時我4個會話不停壓update和insert的場景。最後結論是每秒處理2000個事務(單機Oracle)沒有問題。當時我的領導問,我們有幾千個使用者,你只模擬4個不合適吧?我回答,請問我們有幾千臺伺服器嗎?我們應該只有4個tomcat吧?就算有再多的手機連線最後還是匯聚在4個tomcat上,哪裡能有幾千個連線?我領導想想說也是。

    再說一個案例,我之前做公安行業的,一個城市幾百上千個攝像頭太正常了。做省級平臺的時候就監控裝置就快上萬了,攝像頭要十幾萬了。很顯然我沒有上萬臺伺服器,有的只是幾臺甚至十幾臺通訊伺服器。每個通訊伺服器連線幾十臺到上百臺監控裝置,不停的採集車輛和人員的資料。也就是說我有上萬的裝置到了資料中心也就幾十臺通訊伺服器。而每個通訊伺服器不停向資料庫寫入資料。其實每個用一個會話就夠了。再加上公安使用者使用一個web系統登入。整個資料庫活動會話也不超過40個。

      那麼日常我們為什麼大家習慣於設定較大?主要是一個SQL執行不完,又來一個請求,那麼這個會話不能複用,所以要再來一個會話,如果密集的話那麼就瞬間高了。然後就故障了。

   曾經看到一個文章大致是這樣的:(網上可以找到)模擬  9600 個併發執行緒來運算元據庫,每兩次資料庫操作之間 sleep 550ms,

每個請求要在連線池佇列裡等待 33ms,獲得連線之後,執行SQL需要耗時77ms, CPU 消耗維持在 95% 左右;

接下來,我們將連線池的大小改小點,連線池的大小降低到 96,併發數等其他引數不變,看看結果如何:

每個請求在連線池佇列中的平均等待時間為 1ms, SQL 執行耗時為 2ms.

我們沒調整任何東西,僅僅只是將資料庫連線池的大小降低了,這樣,就能把之前平均 100ms 響應時間縮短到了 3ms。

      是不是覺得反常規?

    Nginx 內部僅僅使用了 4 個執行緒,其效能就大大超越了 100 個程式的 Apache HTTPD 呢?追究其原因的話,回想一下電腦科學的基礎知識,答案其實非常明顯。

    因為我的計算機體系是馮諾依曼體系。就是計算機都是順序執行的。

    即使是單核 CPU 的計算機也能“同時”執行著數百個執行緒。但我們其實都知道,這只不過是作業系統快速切換時間片,跟我們玩的一個小把戲罷了。 一核 CPU同一時刻只能執行一個執行緒,然後作業系統切換上下文,CPU 核心快速排程,執行另一個執行緒的程式碼,不停反覆,給我們造成了所有程式同時執行假象。

    我爸爸就經常說我不要開很多東西,計算機是分時處理系統。

     其實,在一核 CPU 的機器上,順序執行 A B 永遠比透過時間分片切換“同時”執行 A B 要快,其中原因,學過作業系統這門課程的童鞋應該很清楚。一旦執行緒的數量超過了 CPU 核心的數量,再增加執行緒數系統就只會更慢,而不是更快,因為這裡涉及到上下文切換耗費的額外的效能。

所以我們沒必要開很多閒置會話,沒什麼用。redis單執行緒也很快啊!對不對?

  今天先說到這裡吧。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/637517/viewspace-2847328/,如需轉載,請註明出處,否則將追究法律責任。

相關文章