貓頭鷹的深夜翻譯:爲什麼須要緩存以及如何實現緩存

前言

這篇文章探索了現有的各類JAVA緩存基數,它們對各類場景下提升應用的性能起着重要的做用。面試

近十年來,信息技術極高的提高了業務流程,它已經成爲了全球企業的戰略性方案。它從「無關緊要」演變到如今的「不可或缺」。所以,響應時間變得愈加的重要。數據獲取時間對用戶體驗影響極大,它在全部的商業應用中幾乎都是關鍵性需求。影響響應時間的因素不少,包括網絡管道,協議,硬件,軟件以及網速。龐大的IT基礎設施和苛刻的系統性能要求嚴重影響了任何組織的戰略目標。算法

本文旨在強調經過Java緩存機制提高應用的性能。數據庫

緩存的概念

緩存是指一塊內存緩衝區,用來臨時存儲常常訪問的數據。由於數據無需從原始來源從新獲取,所以提高了性能。緩存這個概念應用在計算機/網絡產業的各個領域,所以根據不一樣的用例,有不一樣的實現緩存的方法。事實上,像路由器,交換機,PC這樣的設備使用緩存來加速內存訪問。還有一個常見的場景,幾乎存在於全部的PC,即瀏覽器緩存最近請求獲取的對象,這樣就無需屢次獲取一樣的數據了。在一個分佈式的JEE應用中,客戶端/服務器端緩存對於提高性能也起着相當重要的做用。客戶端緩存用來臨時存儲從服務器傳來的靜態數據,從而避免沒必要要的對服務器的方位。另外一方面,服務器端的緩存會將它從別的地方獲取的數據存儲在內存中。編程

緩存能夠創建在單點/多點JVM或是集羣環境上。可使用緩存來知足不一樣伸縮性程度的場景以下。瀏覽器

垂直伸縮

能夠經過升級單個機器,賦予其更多的有效資源(CPU,RAM,HDD,SSD),而且開啓緩存來實現。可是有個侷限性,緩存升級的程度是有限的。在下面的用例中,能夠經過增長內存並在應用層實現緩存來提高應用的性能。緩存

clipboard.png

水平伸縮

它能夠經過添加更多的機器並在每臺機器的應用層開啓緩存來實現。可是它也存在侷限,由於與之交互的下游應用並無增長額外的機器。在下面的用例中,經過給每個應用添加一個服務器/緩存來提升總體的性能。數據庫可能會成爲性能瓶頸,可是能夠經過在緩存中存儲靜態/主數據來緩解。服務器

clipboard.png

進程中緩存

進程內緩存使對象能夠與應用程序存儲在同一實例中,即本地緩存可供應用程序使用,並共享相同的內存空間。
考慮進程緩存時的重點:微信

  • 若是應用程序僅部署在一個節點中,即具備單個實例,那麼進程內緩存是存儲常常訪問的數據以及快速訪問數據的合適選擇。
  • 若是進程內高速緩存將部署在應用程序的多個實例中,那麼在全部實例之間保持數據同步多是一個挑戰,而且會致使數據不一致。
  • 若是服務器配置有限,那麼這種類型的緩存會下降全部應用程序的性能,由於它共享相同的內存和CPU。垃圾收集器常常會被調用來清理可能致使性能開銷的對象。若是不能有效管理緩存移除,則可能會發生內存不足報錯。

clipboard.png

內存中分佈式緩存

分佈式緩存(鍵/值對象)能夠在支持從/向數據存儲庫讀取/寫入的應用程序的外部構建。它會頻繁的從RAM中訪問數據,避免從數據源獲取數據。這樣的緩存能夠部署在集羣的多個節點中,構成單一邏輯視圖。緩存的客戶端使用哈希算法來得出集羣中對象的位置。網絡

考慮分佈式緩存的重點:架構

  • 內存分佈式緩存對於中型到大型,在集羣中有多個實例,而且性能相當重要的應用是最佳的解決方案。數據不一致以及共享內存再也不是性能的焦點,由於部署在集羣中的分佈式緩存能夠展示出單一邏輯狀態。
  • 因爲須要跨進程訪問網絡上的高速緩存,所以延遲,故障和對象序列化會致使性能降低。
  • 實現的難度大於進程內緩存。

clipboard.png

內存數據庫

這種類型的數據庫也稱爲主存數據庫。數據存儲在RAM中而不是硬盤上,以實現更快的響應。數據以壓縮格式存儲而且支持SQL。相關的數據庫驅動程序能夠用來代替現有的RDBMS。使用內存數據庫替換RDBMS能夠在不改變應用程序層的狀況下提升應用程序的性能。只有垂直伸縮可用於擴展內存數據庫。

內存數據網格

這種分佈式緩存解決方案能夠快速訪問經常使用數據。數據能夠在多個節點上緩存,複製和分區。

實現內存數據網格能夠提升應用程序的性能並在不改變RDBMS的狀況下擴展應用程序。

核心功能:

  • 並行計算內存中的數據
  • 在內存中搜索,聚合和排序數據
  • 內存中的事務管理
  • 事件處理
In-memory database vs In-memory data grid
內存中數據庫經過替換和升級底層RDBMS的基礎上提高性能,它將應用和底層數據庫的變動隔離開來。
內存中數據網格經過調整應用程序來提高速度,將應用的變動和底層數據庫隔離開來。

緩存用例

在任何一個企業級應用中均可以經過配置商業或者開源的框架來提高應用的性能。下面是幾個常見的緩存用例。

應用緩存

應用程序緩存是應用程序保存在內存中用來頻繁訪問的數據的本地緩存。應用程序高速緩存會自動清除條目以保持其內存佔用。

clipboard.png

Level 1 (L1) 緩存

這是每一個會話的默認事務緩存。它能夠由任何Java持久性框架(JPA)或對象關係映射(ORM)工具來管理。L1緩存存儲屬於特定會話的實體對象,並在會話關閉後清除。若是一個會話內有多個事務,則全部這些事務都將被存儲。

Level 2 (L2) 緩存

二級緩存能夠配置爲提供自定義緩存,能夠保存要緩存的全部實體的數據。它可能與屬性,關聯和集合有關。它在會話工廠中配置,而且只要會話工廠可用,它就存在。

二級緩存能夠配置爲可在如下場景中共享:

  • 應用的會話
  • 具備相同數據庫的在相同服務器上的應用程序
  • 擁有同一數據庫的在不一樣服務器上不一樣的應用程序

L1 / L2緩存的使用流程

  • 標準ORM框架首先會在L1緩存中查找實體,而後在L2緩存中查找。L1緩存是查找開始的地方。若是找到一個實體的緩存,就會返回該實體。
  • 若是在L1緩存中沒有找到,就會去L2緩存查找
  • 若是在L2緩存中找到,則會存到L1緩存,而且返回實體
  • 若是在L1和L2中找不到實體,則它將從數據庫中提取並存儲在兩個高速緩存中,而後再返回給調用方。
  • 當任何會話在實體上機型任何修改時,L2緩存驗證/刷新自身。
  • 若是數據庫徹底由外部進程修改,即沒有應用程序會話,則不能隱式刷新L2高速緩存,除非某些高速緩存刷新策略經過框架API或某個自定義API實現。

下面的通訊圖展示了使用L1/L2緩存:

clipboard.png

混合高速緩存

混合高速緩存是標準ORM框架提供的高速緩存和開源/定製/ JDBC API實現的組合。應用可使用混合高速緩存來調整侷限於標準ORM框架的緩存能力。這種緩存用於響應時間相當重要的任務關鍵型應用。

clipboard.png

緩存設計注意事項

緩存設計注意事項包括數據加載/更新,性能/內存大小,緩存移除策略,併發性和緩存統計信息。

數據加載和更新

將數據加載到緩存中是保持全部緩存內容一致性的重要設計決策。加載數據能夠考慮如下方法:

  • 使用標準框架(如hibernate,openJPA)提供的默認的功能或配置
  • 使用開源緩存API(如Google Guava或是COTS的產品如Coherence, Ehcache或 Hazelcast.)實現鍵值映射。
  • 利用編程自動或是顯式插入加載實體
  • 外部的應用能夠經過同步或異步通訊

性能/內存大小 32/64位

可用內存是實現性能SLA的一個重要因素,它取決於32/64位JRE,而JRE又依賴於32/64位機器的CPU架構。在32位的機器中,應用程序可用的堆大小大約是1.5G,而在64位機器中,堆的大小依賴於RAM的大小。

內存的高可用性確實會在運行時產生成本,並可能產生負面影響。

  • 因爲存儲器佈局,64位所須要的堆大小比32位多出30-50%。
  • 保持更多的堆須要更多的GC任務來清理可能下降性能的未使用的對象。經過微調GC能夠減小由GC致使的暫停運行。

緩存移除策略

緩存移除策略使緩存可以確保緩存的大小不超過最大限制。爲了實現這一點,元素將根據緩存移除策略從緩存中刪除,它還能夠根據應用的需求自定義。緩存解決方案中有各類流行的緩存移除策略。

  • 最近最少使用 (LRU):首先淘汰最長時間未被使用的緩存
  • 最不常使用 (LFU):首先淘汰在一段時間內使用次數最少的緩存
  • 先進先出 (FIFO)

併發

併發性是企業應用程序中的常見問題。它會引入衝突而且使系統位於不一致的狀態中。當多個客戶端嘗試在緩存刷新期間同時更新相同的數據對象時,可能會發生這種狀況。一般使用鎖來解決,可是鎖會影響性能。所以,須要針對這個考慮優化策略。

緩存統計

高速緩存統計信息可幫助識別高速緩存的運行情況並提供有關高速緩存行爲和性能的信息。一般,如下屬性可用於統計緩存:

  • Hit count:找到對象所須要的查找次數
  • Miss Count:沒有找到對象所須要的查找次數
  • Load success count:成功加載的條目數
  • Total load time:加載元素的總時間
  • Load exception count:加載條目時拋出的異常數
  • Eviction count:從緩存中移除的條目數量

總結:各類緩存方案

有各類Java緩存解決方案可供選擇 - 正確的選擇取決於使用案例。如下是一些問題和比較,能夠幫助找出最具成本效益和可行的緩存解決方案。

  • 你須要一個輕量級仍是全面的緩存解決方案?
  • 你須要開源的,商業的或框架提供的緩存解決方案?
  • 你須要進程中緩存仍是分佈式緩存?
  • 一致性和延遲要求之間的折衷是什麼?
  • 你須要維護事務/主數據的緩存嗎?
  • 你須要一個緩存複製嗎?
  • 性能,可靠性,可伸縮性和可用性如何?

clipboard.png

參考資料

In-memory database vs In-memory datagrid
LRU 和 LFU的區別

clipboard.png
想要了解更多開發技術,面試教程以及互聯網公司內推,歡迎關注個人微信公衆號!將會不按期的發放福利哦~

相關文章
相關標籤/搜索