本文通過介紹常見的池式結構(資料庫連接池、線程池)和IO多路復用結構(redis),對比其中的作用以及原理,探索其中底層的設計思路的共同點 ...
目錄
本文通過介紹常見的池式結構(資料庫連接池、線程池)和IO多路復用結構(redis),對比其中的作用以及原理,探索其中底層的設計思路的共同點
1. 池化技術介紹
池化技術能夠減少資源對象的創建次數,提⾼程式的響應性能,特別是在⾼併發下這種提⾼更加明顯。使用池化技術緩存的資源對象有如下共同特點:
- 對象創建時間長;
- 對象創建需要大量資源;
- 對象創建後可被重覆使用像常見的線程池、記憶體池、連接池、對象池都具有以上的共同特點。
2.連接池
資料庫連接池
定義:資料庫連接池(Connection pooling)是程式啟動時建立足夠的資料庫連接,並將這些連接組成一個連接池,由程式動態地對池中的連接進行申請,使用,釋放。
創建資料庫連接是⼀個很耗時的操作,也容易對資料庫造成安全隱患。所以,在程式初始化的時候,集中創建多個資料庫連接,並把他們集中管理,供程式使用,可以保證較快的資料庫讀寫速度,還更加安全可靠。 這裡講的資料庫,不單隻是指Mysql,也同樣適用於Redis。
對比不使用連接池的流程圖
- TCP建立連接的三次握手(客戶端與MySQL伺服器的連接基於TCP協議)
- MySQL認證的三次握手
- 真正的SQL執行
- MySQL的關閉
- TCP的四次握手關閉
使用連接池的流程圖
作用:
- 資源復用:由於資料庫連接得到復用,避免了頻繁的創建、釋放連接引起的性能開銷,在減少系統消耗的基礎上,另一方面也增進了系統運行環境的平穩性(減少記憶體碎片以及資料庫臨時進程/線程的數量)。
- 更快的系統響應速度:資料庫連接池在初始化過程中,往往已經創建了若幹資料庫連接置於池中備用。此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了從資料庫連接初始化和釋放過程的開銷,從而縮減了系統整體響應時間。
- 統⼀的連接管理:避免資料庫連接泄露,在較為完備的資料庫連接池實現中,可根據預先的連接占用超時設定,強制收回被占用連接。從而避免了常規資料庫連接操作中可能出現的資源泄露。
3.線程池
定義:線程池是一個預先創建並啟動的線程集合,這些線程可以被反覆地重新利用,從而避免重覆創建和銷毀線程的開銷。當需要執行任務時,線程池只需從緩存的任務中調用線程即可,從而提高程式的效率和穩定性。
總體來說,線程池有如下的優勢:
- 資源優化:通過預先創建和緩存線程,線程池可以避免頻繁地創建和銷毀線程,從而減少了系統資源的浪費和消耗。
- 性能優化:線程池可以復用已經執行完畢或失敗的線程,避免了資源的浪費和消耗,提高了程式的性能和響應速度。
- 高效利用CPU:通過批量處理任務,線程池可以提高CPU的使用率,減少了系統的響應時間。
- 併發控制:線程池提供了併發處理的能力,可以在多線程環境下同時處理多個任務,提高系統的處理能力。
- 任務調度:線程池可以預先安排好任務的執行順序和時間,避免了頻繁地創建和銷毀線程帶來的混亂和延遲。
Java中線程池工作原理圖:
4.IO多路復用機制(以redis為例)
定義:Redis 的 IO 多路復用設計是一種基於事件驅動的非阻塞模型,它允許 Redis 同時處理多個客戶端請求,而無需為每個請求創建一個新的線程。通過 IO 多路復用,Redis 可以有效地利用系統資源,提高併發處理能力。
其中我們來介紹幾個概念:
- I/O
網路I/O,尤其在操作系統層面指數據在內核態和用戶態之間的讀寫操作 - 多路
多個客戶端連接(連接就是套接字描述符,即socket或者channel) - 復用
復用一個或者幾個線程連接 - IO多路復用
也就是說一個或者一組線程處理多個TCP,使用單進程就能實現同時處理多個客戶端的連接,無需創建或者維護過多的進程/線程
redisIO多路復用模型
原理
Redis 的 IO 多路復用模型基於非阻塞的文件描述符註冊和事件通知機制。當有新的請求到達時,Redis 會將相關的請求信息註冊到文件描述符上。然後,Redis 可以通過監視文件描述符的狀態來獲取是否有新的請求到達,從而避免了頻繁的線程切換和上下文切換。
此外,Redis 的 IO 多路復用模型還支持非同步處理。當有新的請求到達時,Redis 不會阻塞當前線程的執行,而是將請求放入隊列中,由後臺線程進行處理。這種設計可以進一步提高系統的併發處理能力,並降低系統的響應時間。
作用
- 資源優化:通過非阻塞的文件描述符註冊和事件通知機制,Redis 可以避免頻繁的線程創建和銷毀,從而減少了系統資源的浪費和消耗。
- 高效併發處理:IO 多路復用模型允許 Redis 同時處理多個客戶端請求,避免了線程切換和上下文切換的開銷,提高了系統的併發能力和吞吐量。
- 可擴展性:Redis 的 IO 多路復用模型具有很好的可擴展性,可以根據系統的需求動態調整併發處理能力。
- 降低響應時間:通過非同步處理和隊列機制,Redis 可以更快地響應用戶請求,提高了系統的響應速度和用戶體驗。
5.共同點
資料庫連接池、線程池等池式結構和 Redis 的 IO 多路復用結構在設計思路上有一些相似之處。以下是一些共同點:
- 資源復用:池式結構(如資料庫連接池、線程池)和 IO 多路復用結構都實現了資源的復用。它們都預先創建了一定數量的資源(如資料庫連接、線程),併在需要時從池中獲取,使用完畢後再放回池中供其他請求使用,避免了頻繁創建和銷毀資源的開銷。
- 高效處理併發:池式結構和 IO 多路復用結構都通過高效地管理併發請求來提高系統的性能。它們通過預先分配的資源池,可以同時處理多個請求,避免了線程切換和上下文切換的開銷。
- 減少資源管理開銷:池式結構和 IO 多路復用結構都簡化了資源管理。在池式結構中,連接、線程等資源的創建、銷毀和分配都是由系統自動完成的,減少了開發者手動管理資源的負擔。在 IO 多路復用結構中,通過非阻塞的 I/O 操作,可以避免頻繁的同步和阻塞,提高了系統的響應速度和吞吐量。
- 非同步處理:池式結構和 IO 多路復用結構都支持非同步處理。它們允許一個請求在等待資源的過程中繼續執行其他任務,從而提高系統的併發能力和吞吐量。
- 可擴展性:池式結構和 IO 多路復用結構都具有可擴展性,可以根據系統的需求動態調整資源池的大小和性能。
tips:雖然資料庫連接池、線程池等池式結構和 Redis 的 IO 多路復用結構在設計思路上有相似之處,但它們在具體實現和使用上還是有所區別的。Redis 的 IO 多路復用結構是基於事件驅動的,而資料庫連接池、線程池等池式結構是基於線程的。此外,Redis 還提供了其他一些特性,如數據緩存、數據結構存儲等,因此它們的適用場景也有所不同。
參考文章:https://zhuanlan.zhihu.com/p/642712057