成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

大廠都在用EhCache,它到底比Redis強在哪里?

存儲 存儲軟件 Redis
這篇文章就帶大家認識除Redis之外的另一種緩存框架:EhCache。之所以要寫寫,也是因為項目中運用了此框架,同時又遇到點問題,于是決定深入研究一下。研究之后,發現還真有點意思。

本文轉載自微信公眾號「程序新視界」,作者二師兄。轉載本文請聯系程序新視界公眾號。

故事背景

隨著硬件價格的走低,大家對硬件的依賴越來越高。甚至聽說,代碼不重要,不行就加機器唄。比如緩存的使用,通常有基于虛擬機內存、基于磁盤存儲、基于中間件(Redis內存)等方式,我們都知道,最適合的才是最好的,但實踐中,往往是動不動就直接上Redis。

那么,Redis一定是最好的選擇嗎?單不說對內存的要求,從效率和性能上來說,也未必是最優的。所以,不同的場景使用不同的緩存策略才是高手應該追求的。

這篇文章就帶大家認識除Redis之外的另一種緩存框架:EhCache。之所以要寫寫,也是因為項目中運用了此框架,同時又遇到點問題,于是決定深入研究一下。研究之后,發現還真有點意思。

EhCache簡介

EhCache是一個純Java的進程內緩存框架,具有快速、精干的特點。注意的這里的關鍵字進程,基于進程的緩存直覺告訴我們效率肯定要高一些,因為它直接在進程之內進行操作,但不同應用之間緩存的共享可能就會有問題。

EhCache是Hibernate中默認的CacheProvider,Spring Boot也對其進行了支持,Spring中提供的緩存抽象也支持對EhCache緩存框架的綁定,而且支持基于注解的方式來使用。因此,EhCache是一款被廣泛使用的基于Java的高速緩存框架,使用起來也非常方便。

EhCache提供了多種緩存策略,主要分為內存和磁盤兩級,是一款面向通用緩存、Java EE和輕量級容器的緩存框架。

EhCache的特點

簡單說一下該框架的特點:

  • 簡單、快速,擁有多種緩存策略;
  • 緩存數據有兩級:內存和磁盤,無需擔心容量問題;
  • 緩存數據會在虛擬機重啟的過程中寫入磁盤;
  • 可以通過RMI、可插入API等方式進行分布式緩存;
  • 具有緩存和緩存管理器的偵聽接口;
  • 支持多緩存管理器實例,以及一個實例的多個緩存區域,并提供Hibernate的緩存實現。

EhCache可以單獨使用,但通常會與Mybatis、Shiro等三方類庫結合使用。本人項目中使用EhCache就是結合Shiro來使用的。

除了優點,EhCache也還有一些缺點。比如,非常占用磁盤空間,這是因為DiskCache的算法簡單,只是對元素直接追加存儲。這樣雖然可以提高效率,但在使用頻繁的系統中,磁盤很快會滿。

另外就是不能保證數據安全,當然突然kill掉Java進程時,可能會產生沖突。EhCache解決沖突的方法是重建Cache,這對Cache數據需要保持時可能會產生影響。Cache只是簡單的加速,不能保證數據的安全。

EhCache與Redis

EhCache直接在JVM中進行緩存,速度快,效率高。與Redis相比,操作簡單、易用、高效,雖然EhCache也提供有緩存共享的方案,但對分布式集群的支持不太好,緩存共享實現麻煩。

Redis是通過Socket訪問到緩存服務,效率比EhCache低,比數據庫要快很多,處理集群和分布式緩存方便,有成熟的方案。

所以,如果是單體應用,或對緩存訪問要求很高,可考慮采用EhCache;如果是大型系統,存在緩存共享、分布式部署、緩存內容很大時,則建議采用Redis。

EhCache架構圖

看一下EhCache的架構圖,大概了解一下它由幾部分組成。

Ehcache-architecture

Cache Replication部分提供了緩存復制的機制,用于分布式環境。EhCache最初是獨立的本地緩存框架組件,在后期的發展中,結合Terracotta服務陣列模型,可以支持分布式緩存集群,主要有RMI、JGroups、JMS和Cache Server等傳播方式進行節點間通信。

In-process APIs則提供了基于JSR、JMX等標準的支持,能夠較好的兼容和移植,同時對各類對象有較完善的監控管理機制。

Network APIs則對外提供了基于RESTful API、JMS API、Cache Server等方式的支持。

在使用過程中,需要關注的核心部分便是中間的Core部分了。它包含了核心的API和概念:

  • CacheManager:緩存管理器,可以通過單例或者多例的方式創建,也是Ehcache的入口類。
  • Cache:每個CacheManager可以管理多個Cache,每個Cache可以采用hash的方式管理多個Element。所有cache都實現了Ehcache接口;
  • Element:單條緩存數據的組成單位,用于存放真正緩存內容的。

三者的管理可以用下圖表示:

CacheManager

緩存過期策略

在架構圖中還可以看到Memory Store LRU、Memory Store LFU、Memory Store FIFO等內存存儲算法。也就是當緩存占用空間接近臨界值時,會采用上面的淘汰策略來清理掉一部分數據。

EhCache提供了三種淘汰算法:

  • FIFO:First In First Out,先進先出。判斷被存儲的時間,離目前最遠的數據優先被淘汰。
  • LRU:Least Recently Used,最近最少使用。判斷最近被使用的時間,目前最遠的數據優先被淘汰。
  • LFU:Least Frequently Used,最不經常使用。在一段時間內,數據被使用次數最少的,優先被淘汰。

Ehcache采用的是懶淘汰機制,每次往緩存放入數據時,都會存一個時間,在讀取時要和設置的時間做TTL比較來判斷是否過期。

EhCache實戰解析

了解了上面的基礎知識之后,來實驗一下EhCache如何使用。其中EhCache2.x和EhCache3.x的使用差距較大。

這里采用比較新的3.9.6版本,不同的版本在API的使用上會有所差異。

基于API使用EhCache

EhCache提供了基于API和xml兩種形式創建CacheManger和Cache。先來看基于API的形式:

在pom文件中引入EhCache依賴:

  1. <dependency> 
  2.       <groupId>org.ehcache</groupId> 
  3.       <artifactId>ehcache</artifactId> 
  4.       <version>3.9.6</version> 
  5. </dependency>  

創建并使用的代碼如下:

  1. public class EhCacheTest { 
  2.  
  3.  @Test 
  4.  public void test() { 
  5.   // 1、先創建一個CacheManagerBuilder; 
  6.   // 2、使用CacheManagerBuilder創建一個預配置(pre-configured)緩存:第一個參數為別名,第二個參數用來配置Cache; 
  7.   // 3、build方法構建并初始化;build中true參數表示進行初始化。 
  8.   CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() 
  9.     .withCache("preConfigured"
  10.       CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, 
  11.         ResourcePoolsBuilder.heap(100)).build()) 
  12.     .build(true); 
  13.  
  14.   // 取回在設定的pre-configured,對于key和value值類型,要求是類型安全的,否則將拋出ClassCastException異常。 
  15.   Cache<Long, String> preConfigured = cacheManager.getCache("preConfigured", Long.class, String.class); 
  16.  
  17.   System.out.println("從緩存中獲取key為preConfigured:" + preConfigured); 
  18.  
  19.   // 根據需求,通過CacheManager創建出新的Cache。實例化和完整實例化的Cache將通過CacheManager.getCache API返回。 
  20.   Cache<Long, String> myCache = cacheManager.createCache("myCache"
  21.     CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, 
  22.       ResourcePoolsBuilder.heap(100)).build()); 
  23.   // 使用put方法存儲數據 
  24.   myCache.put(1L, "da one!"); 
  25.   // 使用get方法獲取數據 
  26.   String value = myCache.get(1L); 
  27.   System.out.println("從緩存中獲取key為1L:" + value); 
  28.   // close方法將釋放CacheManager所管理的緩存資源 
  29.   cacheManager.close(); 
  30.  } 

上述代碼基于API的形式演示了如何創建CacheManager及Cache,并對Cache進行設置和獲取。

基于XML使用EhCache

依賴Jar包不變,在src/main/resources/目錄下創建配置文件 ehcache.xml。

  1. <config 
  2.         xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
  3.         xmlns='http://www.ehcache.org/v3' 
  4.         xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd"
  5.  
  6.     <cache alias="foo"
  7.         <key-type>java.lang.String</key-type> 
  8.         <value-type>java.lang.String</value-type> 
  9.         <resources> 
  10.             <heap unit="entries">20</heap> 
  11.             <offheap unit="MB">10</offheap> 
  12.         </resources> 
  13.     </cache> 
  14.  
  15.     <cache-template name="myDefaults"
  16.         <key-type>java.lang.Long</key-type> 
  17.         <value-type>java.lang.String</value-type> 
  18.         <heap unit="entries">200</heap> 
  19.     </cache-template> 
  20.  
  21.     <cache alias="bar" uses-template="myDefaults"
  22.         <key-type>java.lang.Number</key-type> 
  23.     </cache> 
  24.  
  25.     <cache alias="simpleCache" uses-template="myDefaults" /> 
  26.  
  27. </config> 

3.x版本與2.x版本有所區別,在xml配置文件上非常明顯。2.x中以ehcache元素為根節點,而3.x則以config為根節點。

在上述xml中包含三部分:

  • 普通緩存cache-foo:別名為foo的緩存,緩存的Key-Value值類型均為String。如果沒有指定,默認就是Object類型。
  • 緩存模板cache-template:實現一個配置抽象,以便在未來可以進行擴展;
  • 基于緩存模板的cache-bar:使用了cache-template模板myDefaults,并且覆蓋了key-type類型,myDefaults的key-type是Long類型,覆蓋后成了Number類型;

cache中其他屬性及元素:

  • name為名稱;
  • alias為別名;
  • key-type為key的類型;
  • value-type為value的類型;
  • heap指定堆中可創建的實體格式,其中unit="entries",表示后面的20是實體;
  • offheap表示在開始淘汰過期緩存項之前,可以分配多達10M的堆內存;
  • uses-template表示使用模板的名稱;

當然,也可以通過persistence元素來配置緩存的目錄等。其他屬性的使用,大家可以慢慢探索。

基于Spring Boot使用EhCache

前面已經提到,Spring對緩存進行了支持,Spring Boot也對緩存進行了自動配置的支持。下面就基于Spring Boot來完成EhCache的集成以及使用案例演示。

在Spring Boot中引入對應的starter:

  1. <!-- ehcache依賴--> 
  2. <dependency> 
  3.  <groupId>org.springframework.boot</groupId> 
  4.  <artifactId>spring-boot-starter-cache</artifactId> 
  5. </dependency> 
  6. <dependency> 
  7.  <groupId>org.ehcache</groupId> 
  8.  <artifactId>ehcache</artifactId> 
  9.  <version>3.9.6</version> 
  10. </dependency> 

在application.properties中配置添加如下配置:

  1. spring.cache.ehcache.config=ehcache.xml 

在Spring Boot啟動類上添加@EnableCaching注解:

  1. @EnableCaching 
  2. @SpringBootApplication 
  3. @MapperScan("com.secbro.mapper"
  4. public class SpringBootMainApplication { 
  5.  public static void main(String[] args) { 
  6.   SpringApplication.run(SpringBootMainApplication.class, args); 
  7.  } 

創建一個用戶緩存的實體類Person:

  1. @Data 
  2. public class Person { 
  3.  
  4.  public Person(int id,String name){ 
  5.   this.id = id; 
  6.   this.name = name
  7.  } 
  8.  
  9.  private int id; 
  10.  
  11.  private String name

對應的Service方法實現:

  1. public interface PersonService { 
  2.  Person getById(int id); 
  3.  
  4. @Slf4j 
  5. @Service("personService"
  6. public class PersonServiceImpl implements PersonService { 
  7.  
  8.  @Cacheable(value = "personCache"key = "#id"
  9.  @Override 
  10.  public Person getById(int id) { 
  11.   log.info("查詢id={}的用戶", id); 
  12.   if (id == 1) { 
  13.    return new Person(1, "Tom"); 
  14.   } else if (id == 2) { 
  15.    return new Person(2, "Jim"); 
  16.   } 
  17.   return new Person(3, "Other"); 
  18.  } 

通過Spring提供@Cacheable注解指定了緩存的名稱為personCache,key為id。在方法內打印日志,如果調用到方法內,則會打印。

編寫單元測試類:

  1. @Slf4j 
  2. @SpringBootTest 
  3. @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 
  4. class PersonServiceTest { 
  5.  
  6.  @Resource 
  7.  private PersonService personService; 
  8.  
  9.  @org.junit.jupiter.api.Order(1) 
  10.  @Test 
  11.  void testCache() throws InterruptedException { 
  12.   log.info("第1次查詢id=1的數據"); 
  13.   personService.getById(1); 
  14.   log.info("第2次查詢id=1的數據"); 
  15.   personService.getById(1); 
  16.   Thread.sleep(3000); 
  17.  } 

兩次調用對應的方法,打印日志如下:

  1. c.s.s.PersonServiceTest                  : 第1次查詢id=1的數據 
  2. c.s.s.i.PersonServiceImpl                : 查詢id=1的用戶 
  3. c.s.s.PersonServiceTest                  : 第2次查詢id=1的數據 

可以看到,第一進入方法內進行查詢,第二次便走了緩存。

關于Spring提供的cache注解的使用還有很多使用方法和場景,這里就不再展開了。

小結 

因為工作恰好用到該技術,就鉆研并寫成文章帶大家領略了EhCache的基本知識、技術架構、使用場景、API使用以及基于Spring Boot的集成。整體而言,算是入門級別的,大家可以在此基礎上進一步學習擴展。至于EhCache對分布式的支持部分,本文并未涉及,主要原因是使用起來并沒那么好用,如果感興趣的話可自行研究。

 

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2021-02-17 21:04:03

Ehcache緩存Java

2012-09-13 14:11:07

Windows Ser微軟云平臺

2023-09-04 13:55:44

分支masterhotfix

2021-10-06 19:02:36

Keil編譯器Armclang

2021-02-26 10:46:11

接口測試DiffUnix系統

2021-02-26 07:17:47

MySQLMariaDB

2024-04-10 08:15:17

模型語言模型GPT

2012-09-20 09:07:45

英特爾Xeon E5Xeon 5600

2022-03-26 21:34:54

邊緣計算云計算物聯網

2017-06-22 16:18:58

IBM光譜存儲軟件定義存儲

2022-03-27 23:50:46

云計算邊緣計算技術

2019-05-22 10:38:00

5G芯片中興

2022-07-11 08:33:51

容器技術Docker

2014-01-07 13:54:40

Hadoop日志

2019-07-15 09:09:29

RedisJava操作系統

2024-10-28 13:07:35

MVP分析法產品

2021-10-08 14:43:24

WiFi 5WiFi 6遠程

2020-10-13 21:23:52

數據

2020-10-30 12:41:14

PostgreSQL數據庫MySQL

2020-02-17 21:52:19

微信支付寶健康碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美日韩在线视频一区 | 91久久精品一区二区二区 | av国产在线观看 | 日本天天操 | 亚洲永久 | 久久在线| 青青久久 | 国产精品日产欧美久久久久 | 91视频麻豆| 麻豆视频国产在线观看 | 国产乱码精品一区二区三区av | 一二三四在线视频观看社区 | 精品国产一二三区 | 97色在线观看免费视频 | 国产精品一区久久久久 | 日韩a v在线免费观看 | 天天天天天天天干 | 五月综合激情婷婷 | 国产91综合一区在线观看 | 国产黄色小视频 | 亚洲人成一区二区三区性色 | 日韩在线资源 | 国产超碰人人爽人人做人人爱 | 麻豆久久久久久久 | 亚洲欧美在线视频 | 欧美aa在线| 精品国产乱码久久久久久闺蜜 | 欧美aaa一级片 | 欧美一区二区三区在线观看视频 | 天天操夜夜操 | 色姑娘av| 日韩欧美精品在线 | 色欧美综合 | 91国产在线视频在线 | 91视视频在线观看入口直接观看 | 天堂中文在线播放 | 男女羞羞免费网站 | 91久久看片 | 91中文视频| 免费黄色网址视频 | 国产精品一区在线观看 |