程序員修神之路--高並發下為什么更喜歡進程內緩存



菜菜哥,告訴你一個好消息

YY妹子,什么好消息,你有男票了?

不是啦,我做的一個網站,以前經常由於訪問量太大而崩潰,現在我加上了緩存,很穩定啦

加的什么緩存呢?

我用的redis,號稱業界最快的緩存組件了

你覺得現在的緩存操作應該是最快的了嗎?

是的,我覺得沒有緩存能比這種模式更快了

你先停停,我給你先講個故事

進程內緩存是指緩存和應用程序在相同地址空間。即同一個進程內。分布式緩存是指緩存和應用程序位於不同進程的緩存,通常部署在不同服務器上。


        從前有個機構,機構的主人叫做 CPU,這個機構專門派仆人取一些東西然后做相應的處理。下面是這個機構日常的場景。


cpu

趕緊去我的倉庫L1緩存取點東西

mmbizgif

仆人

主人你要的東西,那里離我們最近,所以很快,但是空間比較小。

941fe5f62ab45aaf73452642568bcf5490e5db9e89fa-WIFUEZ_fw658.jpg

cpu

你丫還挺快,只用了大約一秒

mmbizgif


cpu

趕緊去倉庫 L2緩存取點東西

mmbizgif

仆人

主人你要的東西,那里離我們也很近,比L1緩存遠一點,但是也很快,空間比較小,但是比L1緩存的空間大。

941fe5f62ab45aaf73452642568bcf5490e5db9e89fa-WIFUEZ_fw658.jpg

cpu

速度還可以,大約20秒就回來了

mmbizgif

cpu

街上有一個地方叫內存,趕緊去取點東西

mmbizgif

仆人

主人你要的東西,內存這個地方空間很大呀,就是稍微遠了點

941fe5f62ab45aaf73452642568bcf5490e5db9e89fa-WIFUEZ_fw658.jpg

cpu

居然用了5分鍾,等你這段時間我都刷了好幾個段子了

mmbizgif

cpu

有一個叫做磁盤的小鎮,趕緊去取點東西

mmbizgif

仆人

主人你要的東西,磁盤這個地方空間太大呀,取點東西很慢呀

941fe5f62ab45aaf73452642568bcf5490e5db9e89fa-WIFUEZ_fw658.jpg

cpu

居然用了5天,等你這段時間我都能報團來一個周邊游了

mmbizgif

cpu

有一個叫做互聯網的國度,趕緊去取點東西

mmbizgif

仆人

主人你要的東西,互聯網太遠了,取點東西太費勁了

941fe5f62ab45aaf73452642568bcf5490e5db9e89fa-WIFUEZ_fw658.jpg

cpu

居然用了15天,等你去互聯網取東西,簡直就是在浪費我的生命

mmbizgif

cpu

當我做完一個委托人的任務,切換到另外一個委托人的任務時候,我需要把上一個委托人的一些信息先記錄下來,然后還需要把新委托人的信息讀取一遍,這個過程我是很耗時的,大約需要一個小時呢

以上故事純屬預估數據,真實數據會根據不同的硬件配置和網絡環境有誤差。


        通過以上不正經的小故事,我們可以了解到cpu取各個設備數據的大體差距。至於YY妹子的問題,大家也應該了解了。


1.  首先把數據從磁盤加載到內存做緩存,這個是對的。畢竟磁盤的IO速度比內存要慢的多。就拿我們現在使用的大多數PC機以及服務器來說,磁盤往往是性能的瓶頸。

2.  如果有條件或者框架支持可以實現進程內緩存,我還是推薦使用進程內緩存,畢竟類似Redis這樣的kv存儲和應用程序多數情況不在一台服務器上,雖然局域網的速度肉眼看起來非常快,但是對於cpu來講,還是讓cpu休了一個大假。


    至於什么情況下適合應用進程內緩存,我覺得有幾點需要注意:

1.  相同的請求或者設置的相同緩存key的請求每次都是同一個服務器上的同一個程序去處理,這樣這個請求的緩存正常情況下只會產生一份。 如果每次請求都會路由到不同的服務器,便會產生多個緩存的副本,維護這些緩存數據的一致性是需要代價的。

2.  當有新的服務器節點加入或者服務器節點退出的時候,不能發生雪崩現象,所有緩存請求都穿透到達數據庫,那是比較要命的。比如可以看一下菜菜以前的文章:分布式緩存的一條明路(附代碼)

3.  如果緩存的處理服務器發生變化,比如:由於某種原因,開始請求是由服務器A來處理,后來A服務器down了,現在由服務器B來處理,在緩存轉移的過程中,必須能保證數據的正確性和一致性。

4. 程序的進程內緩存必須有過期策略,在有限內存大小的情況下,合理的使用。推薦使用LRU淘汰算法來保證內存不會撐爆。

5.  系統的並發量及其大,對性能的要求及其高,可以考慮使用進程內緩存。

6.  如果是小部分只讀數據,並且訪問量比較大,例如經常使用的字典數據等,可以考慮使用進程內緩存。


    相對於分布式緩存,比如Redis,進程內緩存有哪些優勢呢?

1.  進程內緩存性能比較高,延遲會更小,更節省帶寬,畢竟分布式緩存網絡調用的性能和本地調用比起來慢太多,

2.  由於和應用程序位於同一進程,共享相同的虛擬內存,所以在狀態維護上更容易一些,

3.  其次進程內的緩存不設計到網絡傳輸,所以沒有序列化的過程,在性能上更勝一籌。

4.  進程內緩存的數據類型幾乎可以是語言級別支持的任意類型,數據類型設計上比大多數分布式緩存設備支持要靈活許多。


        在應對高並發的情況下,如果有適當的環境菜菜還是覺得進程內緩存為首選,另外一點程序要盡量避免線程切換,盡量異步化。如果可以最好能預估出緩存數據的大小,避免內存泄漏等現象發生。

        當然分布式緩存有自己的優勢,在監控,容災,擴展性,易用性等方面更勝一籌。至於用進程內還是分布式緩存,沒有定論,能解決業務痛點就是最好的結果


寫在最后

程序如果要想最大程度的提升並發量,縮短響應時間, 就把用戶需要的數據放在離用戶最近的地方


 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM