在這篇文章裡我們将比較當需要對緩存方案進行技術選型時,使用程序内緩存與分布式緩存的優劣。
首先來看一下二者的定義。顧名思義,程序内緩存是與應用程式在相同位址空間的緩存。Google Guava是一個提供了簡單程序内緩存API的很好的例子。另一方面,分布式緩存是應用程式的外部擴充,通常部署在多個節點上,共同構成一個大的邏輯緩存。Memcached是一個流行的分布式緩存。Terracotta公司的Ehcache則是一個通過配置可以以任一種方式使用的緩存産品。
一緻性
程序内緩存
當使用程序内緩存時,緩存元素是特定應用程式執行個體本地的。然而,許多中到大型應用通常會做負載均衡,進而不存在一個作為整體的獨立應用。在這種情況下,很可能會建構出一個有多少應用執行個體就有多少緩存的解決方案,每個緩存都有各自的狀态,這就導緻了不一緻性。随着緩存元素的過期或被逐出,所有緩存執行個體間可能達到最終一緻性。
分布式緩存
分布式緩存,雖然部署在由多個節點構成的叢集上,會提供一個單一緩存的邏輯視圖(以及狀态)。多數情況下,分布式緩存中的對象将會存在于叢集中的單個節點。通過雜湊演算法,緩存引擎總是可以判斷出某個鍵值對位于哪個特定節點。由于整個叢集總是會有一個特定狀态,是以從來不會存在不一緻的情況。
備注
如果你需要緩存不變的對象,一緻性将不是一個問題。在這種情況下,程序内緩存是一個更好的解決方案,因為它沒有分布式緩存的典型管理開銷。如果你的應用部署在多個節點上,想要緩存可變的對象同時需要每次讀都是一緻的而不僅僅滿足最終一緻性,則應當采用分布式緩存。
開銷
揭開程序内緩存的奧秘 一文中提到程序内緩存可能會影響垃圾回收進而影響系統性能。而這将會由緩存大小以及對象逐出和過期的頻率決定。
分布式緩存有兩大主要開銷會導緻其慢于程序内緩存(但優于無緩存方案):網絡延遲和對象序列化。
正如之前所提到的,如果你試圖尋求一個多節點部署情況下的強一緻性緩存解決方案,采用分布式緩存。
可靠性
程序内緩存使用與應用程式相同的堆空間,是以必須非常小心地決定緩存所能使用的記憶體大小上限。如果應用程式用光了記憶體,想要試圖恢複并不容易。
分布式緩存作為多個節點的獨立程序運作,是以單點故障并不會導緻緩存失效。丢失的緩存元素将會在下一次緩存未命中時進入存活的節點。分布式緩存情況下,緩存整體失效的最壞後果是降低系統性能,而不是導緻系統整體故障。
程序内緩存适用于較小且頻率可預見的通路場景,尤其适用于不變對象。對于較大且不可預見的規模的通路,最好采用分布式緩存。
建議
對于不變對象的較小規模的、可預見次數的通路,程序内緩存是一個理想解決方案,性能上它優于分布式緩存。然而,對于要緩存的對象數量是未知的并且較大的情況下,同時要求讀一緻性,分布式緩存是一個更好的解決方案,盡管它可能具備與程序内緩存相同的性能。自不用說,應用程式可以同時應用兩種類型的緩存,取決于最适用的應用場景。
原文連結:In-Process Caching vs. Distributed Caching