摘要:由于需要跨進程訪問網(wǎng)絡上的高速緩存,因此延遲,故障和對象序列化會導致性能下降。應用程序高速緩存會自動清除條目以保持其內(nèi)存占用。緩存統(tǒng)計高速緩存統(tǒng)計信息可幫助識別高速緩存的運行狀況并提供有關高速緩存行為和性能的信息。
前言
這篇文章探索了現(xiàn)有的各種JAVA緩存基數(shù),它們對各種場景下提高應用的性能起著重要的作用。
近十年來,信息技術極高的提升了業(yè)務流程,它已經(jīng)成為了全球企業(yè)的戰(zhàn)略性方案。它從“可有可無”演變到現(xiàn)在的“不可或缺”。因此,響應時間變得越發(fā)的重要。數(shù)據(jù)獲取時間對用戶體驗影響極大,它在所有的商業(yè)應用中幾乎都是關鍵性需求。影響響應時間的因素很多,包括網(wǎng)絡管道,協(xié)議,硬件,軟件以及網(wǎng)速。龐大的IT基礎設施和苛刻的系統(tǒng)性能要求嚴重影響了任何組織的戰(zhàn)略目標。
本文旨在強調(diào)通過Java緩存機制提升應用的性能。
緩存的概念緩存是指一塊內(nèi)存緩沖區(qū),用來臨時存儲經(jīng)常訪問的數(shù)據(jù)。因為數(shù)據(jù)無需從原始來源重新獲取,因此提升了性能。緩存這個概念應用在計算機/網(wǎng)絡產(chǎn)業(yè)的各個領域,因此根據(jù)不同的用例,有不同的實現(xiàn)緩存的方法。事實上,像路由器,交換機,PC這樣的設備使用緩存來加速內(nèi)存訪問。還有一個常見的場景,幾乎存在于所有的PC,即瀏覽器緩存最近請求獲取的對象,這樣就無需多次獲取同樣的數(shù)據(jù)了。在一個分布式的JEE應用中,客戶端/服務器端緩存對于提升性能也起著至關重要的作用。客戶端緩存用來臨時存儲從服務器傳來的靜態(tài)數(shù)據(jù),從而避免不必要的對服務器的方位。另一方面,服務器端的緩存會將它從別的地方獲取的數(shù)據(jù)存儲在內(nèi)存中。
緩存可以建立在單點/多點JVM或是集群環(huán)境上。可以使用緩存來滿足不同伸縮性程度的場景如下。
垂直伸縮可以通過升級單個機器,賦予其更多的有效資源(CPU,RAM,HDD,SSD),并且開啟緩存來實現(xiàn)。但是有個局限性,緩存升級的程度是有限的。在下面的用例中,可以通過增加內(nèi)存并在應用層實現(xiàn)緩存來提升應用的性能。
水平伸縮它可以通過添加更多的機器并在每臺機器的應用層開啟緩存來實現(xiàn)。但是它也存在局限,因為與之交互的下游應用并沒有增加額外的機器。在下面的用例中,通過給每一個應用添加一個服務器/緩存來提高整體的性能。數(shù)據(jù)庫可能會成為性能瓶頸,但是可以通過在緩存中存儲靜態(tài)/主數(shù)據(jù)來緩解。
進程中緩存進程內(nèi)緩存使對象可以與應用程序存儲在同一實例中,即本地緩存可供應用程序使用,并共享相同的內(nèi)存空間。
考慮進程緩存時的重點:
如果應用程序僅部署在一個節(jié)點中,即具有單個實例,那么進程內(nèi)緩存是存儲經(jīng)常訪問的數(shù)據(jù)以及快速訪問數(shù)據(jù)的合適選擇。
如果進程內(nèi)高速緩存將部署在應用程序的多個實例中,那么在所有實例之間保持數(shù)據(jù)同步可能是一個挑戰(zhàn),并且會導致數(shù)據(jù)不一致。
如果服務器配置有限,那么這種類型的緩存會降低所有應用程序的性能,因為它共享相同的內(nèi)存和CPU。垃圾收集器經(jīng)常會被調(diào)用來清理可能導致性能開銷的對象。如果不能有效管理緩存移除,則可能會發(fā)生內(nèi)存不足報錯。
內(nèi)存中分布式緩存分布式緩存(鍵/值對象)可以在支持從/向數(shù)據(jù)存儲庫讀取/寫入的應用程序的外部構建。它會頻繁的從RAM中訪問數(shù)據(jù),避免從數(shù)據(jù)源獲取數(shù)據(jù)。這樣的緩存可以部署在集群的多個節(jié)點中,構成單一邏輯視圖。緩存的客戶端使用哈希算法來得出集群中對象的位置。
考慮分布式緩存的重點:
內(nèi)存分布式緩存對于中型到大型,在集群中有多個實例,并且性能至關重要的應用是最佳的解決方案。數(shù)據(jù)不一致以及共享內(nèi)存不再是性能的焦點,因為部署在集群中的分布式緩存可以展現(xiàn)出單一邏輯狀態(tài)。
由于需要跨進程訪問網(wǎng)絡上的高速緩存,因此延遲,故障和對象序列化會導致性能下降。
實現(xiàn)的難度大于進程內(nèi)緩存。
內(nèi)存數(shù)據(jù)庫這種類型的數(shù)據(jù)庫也稱為主存數(shù)據(jù)庫。數(shù)據(jù)存儲在RAM中而不是硬盤上,以實現(xiàn)更快的響應。數(shù)據(jù)以壓縮格式存儲并且支持SQL。相關的數(shù)據(jù)庫驅動程序可以用來代替現(xiàn)有的RDBMS。使用內(nèi)存數(shù)據(jù)庫替換RDBMS可以在不改變應用程序層的情況下提高應用程序的性能。只有垂直伸縮可用于擴展內(nèi)存數(shù)據(jù)庫。
內(nèi)存數(shù)據(jù)網(wǎng)格這種分布式緩存解決方案可以快速訪問常用數(shù)據(jù)。數(shù)據(jù)可以在多個節(jié)點上緩存,復制和分區(qū)。
實現(xiàn)內(nèi)存數(shù)據(jù)網(wǎng)格可以提高應用程序的性能并在不改變RDBMS的情況下擴展應用程序。
核心功能:
并行計算內(nèi)存中的數(shù)據(jù)
在內(nèi)存中搜索,聚合和排序數(shù)據(jù)
內(nèi)存中的事務管理
事件處理
In-memory database vs In-memory data grid緩存用例
內(nèi)存中數(shù)據(jù)庫通過替換和升級底層RDBMS的基礎上提升性能,它將應用和底層數(shù)據(jù)庫的變更隔離開來。
內(nèi)存中數(shù)據(jù)網(wǎng)格通過調(diào)整應用程序來提升速度,將應用的變更和底層數(shù)據(jù)庫隔離開來。
在任何一個企業(yè)級應用中都可以通過配置商業(yè)或者開源的框架來提升應用的性能。下面是幾個常見的緩存用例。
應用緩存應用程序緩存是應用程序保存在內(nèi)存中用來頻繁訪問的數(shù)據(jù)的本地緩存。應用程序高速緩存會自動清除條目以保持其內(nèi)存占用。
Level 1 (L1) 緩存這是每個會話的默認事務緩存。它可以由任何Java持久性框架(JPA)或對象關系映射(ORM)工具來管理。L1緩存存儲屬于特定會話的實體對象,并在會話關閉后清除。如果一個會話內(nèi)有多個事務,則所有這些事務都將被存儲。
Level 2 (L2) 緩存二級緩存可以配置為提供自定義緩存,可以保存要緩存的所有實體的數(shù)據(jù)。它可能與屬性,關聯(lián)和集合有關。它在會話工廠中配置,并且只要會話工廠可用,它就存在。
二級緩存可以配置為可在以下場景中共享:
應用的會話
具有相同數(shù)據(jù)庫的在相同服務器上的應用程序
擁有同一數(shù)據(jù)庫的在不同服務器上不同的應用程序
L1 / L2緩存的使用流程標準ORM框架首先會在L1緩存中查找實體,然后在L2緩存中查找。L1緩存是查找開始的地方。如果找到一個實體的緩存,就會返回該實體。
如果在L1緩存中沒有找到,就會去L2緩存查找
如果在L2緩存中找到,則會存到L1緩存,并且返回實體
如果在L1和L2中找不到實體,則它將從數(shù)據(jù)庫中提取并存儲在兩個高速緩存中,然后再返回給調(diào)用方。
當任何會話在實體上機型任何修改時,L2緩存驗證/刷新自身。
如果數(shù)據(jù)庫完全由外部進程修改,即沒有應用程序會話,則不能隱式刷新L2高速緩存,除非某些高速緩存刷新策略通過框架API或某個自定義API實現(xiàn)。
下面的通信圖展現(xiàn)了使用L1/L2緩存:
混合高速緩存混合高速緩存是標準ORM框架提供的高速緩存和開源/定制/ JDBC API實現(xiàn)的組合。應用可以使用混合高速緩存來調(diào)整局限于標準ORM框架的緩存能力。這種緩存用于響應時間至關重要的任務關鍵型應用。
緩存設計注意事項緩存設計注意事項包括數(shù)據(jù)加載/更新,性能/內(nèi)存大小,緩存移除策略,并發(fā)性和緩存統(tǒng)計信息。
數(shù)據(jù)加載和更新將數(shù)據(jù)加載到緩存中是保持所有緩存內(nèi)容一致性的重要設計決策。加載數(shù)據(jù)可以考慮以下方法:
使用標準框架(如hibernate,openJPA)提供的默認的功能或配置
使用開源緩存API(如Google Guava或是COTS的產(chǎn)品如Coherence, Ehcache或 Hazelcast.)實現(xiàn)鍵值映射。
利用編程自動或是顯式插入加載實體
外部的應用可以通過同步或異步通信
性能/內(nèi)存大小 32/64位可用內(nèi)存是實現(xiàn)性能SLA的一個重要因素,它取決于32/64位JRE,而JRE又依賴于32/64位機器的CPU架構。在32位的機器中,應用程序可用的堆大小大約是1.5G,而在64位機器中,堆的大小依賴于RAM的大小。
內(nèi)存的高可用性確實會在運行時產(chǎn)生成本,并可能產(chǎn)生負面影響。
由于存儲器布局,64位所需要的堆大小比32位多出30-50%。
保持更多的堆需要更多的GC任務來清理可能降低性能的未使用的對象。通過微調(diào)GC可以減少由GC導致的暫停運行。
緩存移除策略緩存移除策略使緩存能夠確保緩存的大小不超過最大限制。為了實現(xiàn)這一點,元素將根據(jù)緩存移除策略從緩存中刪除,它還可以根據(jù)應用的需求自定義。緩存解決方案中有各種流行的緩存移除策略。
最近最少使用 (LRU):首先淘汰最長時間未被使用的緩存
最不常使用 (LFU):首先淘汰在一段時間內(nèi)使用次數(shù)最少的緩存
先進先出 (FIFO)
并發(fā)并發(fā)性是企業(yè)應用程序中的常見問題。它會引入沖突并且使系統(tǒng)位于不一致的狀態(tài)中。當多個客戶端嘗試在緩存刷新期間同時更新相同的數(shù)據(jù)對象時,可能會發(fā)生這種情況。通常使用鎖來解決,但是鎖會影響性能。因此,需要針對這個考慮優(yōu)化策略。
緩存統(tǒng)計高速緩存統(tǒng)計信息可幫助識別高速緩存的運行狀況并提供有關高速緩存行為和性能的信息。通常,以下屬性可用于統(tǒng)計緩存:
Hit count:找到對象所需要的查找次數(shù)
Miss Count:沒有找到對象所需要的查找次數(shù)
Load success count:成功加載的條目數(shù)
Total load time:加載元素的總時間
Load exception count:加載條目時拋出的異常數(shù)
Eviction count:從緩存中移除的條目數(shù)量
總結:各種緩存方案有各種Java緩存解決方案可供選擇 - 正確的選擇取決于使用案例。以下是一些問題和比較,可以幫助找出最具成本效益和可行的緩存解決方案。
你需要一個輕量級還是全面的緩存解決方案?
你需要開源的,商業(yè)的或框架提供的緩存解決方案?
你需要進程中緩存還是分布式緩存?
一致性和延遲要求之間的折衷是什么?
你需要維護事務/主數(shù)據(jù)的緩存嗎?
你需要一個緩存復制嗎?
性能,可靠性,可伸縮性和可用性如何?
參考資料In-memory database vs In-memory datagrid
LRU 和 LFU的區(qū)別
想要了解更多開發(fā)技術,面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關注我的微信公眾號!將會不定期的發(fā)放福利哦~
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/61936.html
摘要:有可能一個線程中的動作相對于另一個線程出現(xiàn)亂序。當實際輸出取決于線程交錯的結果時,這種情況被稱為競爭條件。這里的問題在于代碼塊不是原子性的,而且實例的變化對別的線程不可見。這種不能同時在多個線程上執(zhí)行的部分被稱為關鍵部分。 為什么要額外寫一篇文章來研究volatile呢?是因為這可能是并發(fā)中最令人困惑以及最被誤解的結構。我看過不少解釋volatile的博客,但是大多數(shù)要么不完整,要么難...
摘要:是指可能導致程序終止的非常嚴重的時間。具有最高的級別,旨在關閉中的日志功能。因此為每一個消息選擇一個合適的日志級別是非常重要的。日志的個小建議將日志訪日代碼塊它能顯著的減少因為字符串拼接而帶來的性能的影響。 前言 首先,這篇文章沒有進行任何的日志功能的詳細介紹,而是對日志提出了幾種最佳實踐。適合對日志記錄有所了解的同學閱讀。下面是正文: JAVA日志管理既是一門科學,又是一門藝術。科學...
摘要:簡介從創(chuàng)建以來,就支持核心的并發(fā)概念如線程和鎖。這篇文章會幫助從事多線程編程的開發(fā)人員理解核心的并發(fā)概念以及如何使用它們。請求操作系統(tǒng)互斥,并讓操作系統(tǒng)調(diào)度程序處理線程停放和喚醒。 簡介 從創(chuàng)建以來,JAVA就支持核心的并發(fā)概念如線程和鎖。這篇文章會幫助從事多線程編程的JAVA開發(fā)人員理解核心的并發(fā)概念以及如何使用它們。 (博主將在其中加上自己的理解以及自己想出的例子作為補充) 概念 ...
摘要:常出現(xiàn)的錯誤前十位為了可讀性,錯誤名稱進行了一定的簡寫。讓我們深入了解每個錯誤發(fā)生的原因以及解決方法。這個問題很容易解決。當未捕獲的錯誤跨越違法跨域策略的域邊界時,會發(fā)生腳本錯誤。這是當你在中試圖調(diào)用的方法時出現(xiàn)的錯誤。 JavaScript常出現(xiàn)的錯誤前十位 showImg(https://segmentfault.com/img/bV3Z1z?w=1116&h=691); 為了可讀...
摘要:什么是為執(zhí)行字節(jié)碼提供一個運行環(huán)境。它的實現(xiàn)主要包含三個部分,描述實現(xiàn)規(guī)格的文檔,具體實現(xiàn)和滿足要求的計算機程序以及實例具體執(zhí)行字節(jié)碼。該類先被轉化為一組字節(jié)碼并放入文件中。字節(jié)碼校驗器通過字節(jié)碼校驗器檢查格式并找出非法代碼。 什么是Java Development Kit (JDK)? JDK通常用來開發(fā)Java應用和插件。基本上可以認為是一個軟件開發(fā)環(huán)境。JDK包含Java Run...
閱讀 2485·2021-11-15 18:14
閱讀 1709·2021-10-14 09:42
閱讀 3744·2021-10-11 10:58
閱讀 3937·2021-10-09 09:44
閱讀 2409·2021-09-26 09:55
閱讀 2430·2021-09-24 10:38
閱讀 2024·2021-09-04 16:48
閱讀 3267·2021-09-02 15:21