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


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


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


加的什么緩存呢?


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


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


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


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



進程內緩存是指緩存和應用程序在相同地址空間。即同一個進程內。分布式緩存是指緩存和應用程序位於不同進程的緩存,通常部署在不同服務器上。
從前有個機構,機構的主人叫做 CPU,這個機構專門派仆人取一些東西然后做相應的處理。下面是這個機構日常的場景。

cpu
趕緊去我的倉庫L1緩存取點東西
仆人
主人你要的東西,那里離我們最近,所以很快,但是空間比較小。


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

cpu
趕緊去倉庫 L2緩存取點東西
仆人
主人你要的東西,那里離我們也很近,比L1緩存遠一點,但是也很快,空間比較小,但是比L1緩存的空間大。


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

cpu
街上有一個地方叫內存,趕緊去取點東西
仆人
主人你要的東西,內存這個地方空間很大呀,就是稍微遠了點


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

cpu
有一個叫做磁盤的小鎮,趕緊去取點東西
仆人
主人你要的東西,磁盤這個地方空間太大呀,取點東西很慢呀


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

cpu
有一個叫做互聯網的國度,趕緊去取點東西
仆人
主人你要的東西,互聯網太遠了,取點東西太費勁了


cpu
居然用了15天,等你去互聯網取東西,簡直就是在浪費我的生命
當我做完一個委托人的任務,切換到另外一個委托人的任務時候,我需要把上一個委托人的一些信息先記錄下來,然后還需要把新委托人的信息讀取一遍,這個過程我是很耗時的,大約需要一個小時呢
通過以上不正經的小故事,我們可以了解到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. 進程內緩存的數據類型幾乎可以是語言級別支持的任意類型,數據類型設計上比大多數分布式緩存設備支持要靈活許多。
在應對高並發的情況下,如果有適當的環境菜菜還是覺得進程內緩存為首選,另外一點程序要盡量避免線程切換,盡量異步化。如果可以最好能預估出緩存數據的大小,避免內存泄漏等現象發生。
當然分布式緩存有自己的優勢,在監控,容災,擴展性,易用性等方面更勝一籌。至於用進程內還是分布式緩存,沒有定論,能解決業務痛點就是最好的結果
程序如果要想最大程度的提升並發量,縮短響應時間, 就把用戶需要的數據放在離用戶最近的地方
