高併發下爲何更喜歡進程內緩存

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

從前有個機構,機構的主人叫作 CPU,這個機構專門派僕人取一些東西而後作相應的處理。下面是這個機構平常的場景。數據庫

CPU:趕忙去個人倉庫L1緩存取點東西
僕人:主人你要的東西,那裏離咱們最近,因此很快,可是空間比較小。
CPU:你丫還挺快,只用了大約一秒
CPU:趕忙去倉庫 L2緩存取點東西
僕人:主人你要的東西,那裏離咱們也很近,比L1緩存遠一點,可是也很快,空間比較小,可是比L1緩存的空間大。
CPU:速度還能夠,大約20秒就回來了
CPU:街上有一個地方叫內存,趕忙去取點東西
僕人:主人你要的東西,內存這個地方空間很大呀,就是稍微遠了點
CPU:竟然用了5分鐘,等你這段時間我都刷了好幾個段子了
CPU:有一個叫作磁盤的小鎮,趕忙去取點東西
僕人:主人你要的東西,磁盤這個地方空間太大呀,取點東西很慢呀
CPU:竟然用了5天,等你這段時間我都能報團來一個周邊遊了
CPU:有一個叫作互聯網的國度,趕忙去取點東西
僕人:主人你要的東西,互聯網太遠了,取點東西太費勁了
CPU:竟然用了15天,等你去互聯網取東西,簡直就是在浪費個人生命緩存

當我作完一個委託人的任務,切換到另一個委託人的任務時候,我須要把上一個委託人的一些信息先記錄下來,而後還須要把新委託人的信息讀取一遍,這個過程我是很耗時的,大約須要一個小時呢服務器

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

經過以上不正經的小故事,咱們能夠了解到cpu取各個設備數據的大致差距。至於YY妹子的問題,你們也應該瞭解了。架構

    1. 首先把數據從磁盤加載到內存作緩存,這個是對的。畢竟磁盤的IO速度比內存要慢的多。就拿咱們如今使用的大多數PC機以及服務器來講,磁盤每每是性能的瓶頸。
    1. 若是有條件或者框架支持能夠實現進程內緩存,我仍是推薦使用進程內緩存,畢竟相似Redis這樣的kv存儲和應用程序多數狀況不在一臺服務器上,雖然局域網的速度肉眼看起來很是快,可是對於cpu來說,仍是讓cpu休了一個大假。想免費學習Java工程化、分佈式架構、高併發、高性能、深刻淺出、微服務架構、SpringMyBatisNetty源碼分析等技術的朋友,能夠加企鵝羣:834962734,羣裏有阿里大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給你們,歡迎進羣一塊兒深刻交流學習無論你是轉行,仍是工做中想提高本身能力均可以

至於什麼狀況下適合應用進程內緩存,我以爲有幾點須要注意:併發

    1. 相同的請求或者設置的相同緩存key的請求每次都是同一個服務器上的同一個程序去處理,這樣這個請求的緩存正常狀況下只會產生一份。 若是每次請求都會路由到不一樣的服務器,便會產生多個緩存的副本,維護這些緩存數據的一致性是須要代價的。
    1. 當有新的服務器節點加入或者服務器節點退出的時候,不能發生雪崩現象,全部緩存請求都穿透到達數據庫,那是比較要命的。好比能夠看一下菜菜之前的文章:分佈式緩存的一條明路(附代碼)
    1. 若是緩存的處理服務器發生變化,好比:因爲某種緣由,開始請求是由服務器A來處理,後來A服務器down了,如今由服務器B來處理,在緩存轉移的過程當中,必須能保證數據的正確性和一致性。
    1. 程序的進程內緩存必須有過時策略,在有限內存大小的狀況下,合理的使用。推薦使用LRU淘汰算法來保證內存不會撐爆。
    1. 系統的併發量及其大,對性能的要求及其高,能夠考慮使用進程內緩存。
    1. 若是是小部分只讀數據,而且訪問量比較大,例如常用的字典數據等,能夠考慮使用進程內緩存。

相對於分佈式緩存,好比Redis,進程內緩存有哪些優點呢?框架

    1. 進程內緩存性能比較高,延遲會更小,更節省帶寬,畢竟分佈式緩存網絡調用的性能和本地調用比起來慢太多,
    1. 因爲和應用程序位於同一進程,共享相同的虛擬內存,因此在狀態維護上更容易一些,
    1. 其次進程內的緩存不設計到網絡傳輸,因此沒有序列化的過程,在性能上更勝一籌。
    1. 進程內緩存的數據類型幾乎能夠是語言級別支持的任意類型,數據類型設計上比大多數分佈式緩存設備支持要靈活許多。

在應對高併發的狀況下,若是有適當的環境菜菜仍是以爲進程內緩存爲首選,另一點程序要儘可能避免線程切換,儘可能異步化。若是能夠最好能預估出緩存數據的大小,避免內存泄漏等現象發生。異步

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

相關文章
相關標籤/搜索