精华内容
下载资源
问答
  • ehcache和redis的区别
    千次阅读
    2019-03-01 18:01:35

    1.概念不同:

    Redis是一个基于内存的高性能key-value数据库,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存

    EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。

     

    2.运行程序不同:

    Redis:属于独立的运行程序,需要单独安装后,使用JAVA中的Jedis来操纵。因为它是独立,所以如果你写个单元测试程序,放一些数据在Redis中,然后又写一个程序去拿数据,那么是可以拿到这个数据的。,
    ehcache:与Redis明显不同,它与java程序是绑在一起的,java程序活着,它就活着。譬如,写一个独立程序放数据,再写一个独立程序拿数据,那么是拿不到数据的。只能在独立程序中才能拿到数据。

    3.特性不同:

    Redis

    1】. 支持持久化

    redis的本地持久化支持两种方式:RDB和AOF。RDB 在redis.conf配置文件里配置持久化触发器,AOF指的是redis没增加一条记录都会保存到持久化文件中(保存的是这条记录的生成命令),如果不是用redis做DB用的话还会不要开AOF ,数据太庞大了,重启恢复的时候是一个巨大的工程!

    2】.丰富的数据类型 redis 支持 String 、Lists、sets、sorted sets、hashes 多种数据类型,新浪微博会使用redis做nosql主要也是它具有这些类型,时间排序、职能排序、我的微博、发给我的这些功能List 和 sorted set 的强大操作功能息息相关

    3】高性能 这点跟memcache很想象,内存操作的级别是毫秒级的比硬盘操作秒级操作自然高效不少,较少了磁头寻道、数据读取、页面交换这些高开销的操作!这也是NOSQL冒出来的原因吧,应该是高性能 是基于RDBMS的衍生产品,虽然RDBMS也具有缓存结构,但是始终在app层面不是我们想要的那么操控的。

    4】replication redis提供主从复制方案,跟mysql一样增量复制而且复制的实现都很相似,这个复制跟AOF有点类似复制的是新增记录命令,主库新增记录将新增脚本发送给从库,从库根据脚本生成记录,这个过程非常快,就看网络了,一般主从都是在同一个局域网,所以可以说redis的主从近似及时同步,同事它还支持一主多从,动态添加从库,从库数量没有限制。 主从库搭建,我觉得还是采用网状模式,如果使用链式(master-slave-slave-slave-slave·····)如果第一个slave出现宕机重启,首先从master 接收 数据恢复脚本,这个是阻塞的,如果主库数据几TB的情况恢复过程得花上一段时间,在这个过程中其他的slave就无法和主库同步了。

    5】更新快

     

    Ehcache主要的特性有:

    1】. 快速

    2】. 简单

    3】. 多种缓存策略

    4】. 缓存数据有两级:内存和磁盘,因此无需担心容量问题

    5】 缓存数据会在虚拟机重启的过程中写入磁盘

    6】. 可以通过RMI、可插入API等方式进行分布式缓存

    7】. 具有缓存和缓存管理器的侦听接口

    8.】 支持多缓存管理器实例,以及一个实例的多个缓存区域

    9】. 提供Hibernate的缓存实现

     

    4.一致性不同:

    Redis(分布式缓存):
                    一致性:由于是db的缓存,内容可能与db不一致,需要容忍不一致性;但所有应用服务器在同一时间,读到的数据都是一样的;
                    性能:较好,get大约在5ms的速度;
    ehcache(本地缓存):
                    一致性:由于是保存在JVM中,每台机器数据都可能不一样,一致性较差;
                    性能:最好,由于是直接读取内存数据,性能可以保证,大约在0.5ms的性能级别。
       5.应用场景不同:


    redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群和分布式缓存方便,有成熟的方案。

    ehcache直接在jvm虚拟机中缓存,速度快,效率高;但是缓存共享麻烦,集群分布式应用不方便。


    如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。

    如果是单个应用或者对缓存访问要求很高的应用,用ehcache。

    补充下:ehcache也有缓存共享方案,不过是通过RMI或者Jgroup多播方式进行广播缓存通知更新,缓存共享复杂,维护不方便;简单的共享可以,但是涉及到缓存恢复,大数据缓存,则不合适。         
          

    参考文:https://www.cnblogs.com/firejava/p/6256788.html

    https://blog.csdn.net/shenbushen/article/details/52140078

    https://blog.csdn.net/xnf1991/article/details/54694620    

        
        

      
      

            


        
            
                
         

     

    更多相关内容
  • 该文章的主要内容为:springboot项目需要整合ehcache和redis,在整合ehcache和redis的过程中,ehcache部分的配置,以及简单的测试使用。该文章主要展示了相关代码,具体的介绍有所省略。

    该文章的主要内容为:springboot项目需要整合ehcache和redis,在整合ehcache和redis的过程中,ehcache部分的配置,以及简单的测试使用。

    该文章主要展示了相关代码,具体的介绍有所省略。

    一、springboot项目中整合ehcache和redis

    springboot项目整合ehcache和redis的思路是,在RedisCacheManager和EhcacheCacheManager的基础上,构建一个整合性质的组件(Component_A),其可以根据缓存key从不同的Manager中获取对应的缓存区域(Cache)。

    整合性质的组件(Component_A)的代码为:

    package com.snail.spt4.basecommon.cache.cachecombine;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.Cache;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.ehcache.EhCacheCacheManager;
    import org.springframework.cache.interceptor.KeyGenerator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.data.redis.cache.RedisCacheManager;

    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Collection;

    /**
     * 缓存集成配置类,当前集成了redis,和ehcache。
     * <p>
     * 该类通过向spring提供统一的{@link CacheManager}以达到集成不同缓存中间件的目的。<br>
     * 该类重写了{@link CachingConfigurerSupport#cacheManager()}和{@link CachingConfigurerSupport#keyGenerator()}的方法。
     *
     * @author 51
     * @version v0.1 2018年2月5日 下午6:45:44 51
     * @see CachingConfigurerSupport
     */
    @EnableCaching
    @Configuration
    public class CombineCacheConfig extends CachingConfigurerSupport {
       
       private static Logger logger = LoggerFactory.getLogger(CombineCacheConfig.class);
       
       /**
        * redis缓存前缀
        * <p>用于通过缓存名前缀识别缓存中间件
        */
       private static final String REDIS_PREFIX = "redis_";
       
       /**
        * ehcache缓存前缀
        */
       private static final String EHCACHE_PREFIX = "ehcache_";
       
       @Autowired(required = false)
       private volatile RedisCacheManager redisCacheManager;
       
       @Autowired(required = false)
       private volatile EhCacheCacheManager ehCacheCacheManager;
       
       /**
        * 构造函数
        */
       public CombineCacheConfig() {
          super();
          logger.info("执行了CombineCacheConfig.CombineCacheConfig()构造方法...\n");
       }
       
       /**
        * 构建CacheManager的实例combineCacheManager
        * <p>combineCacheManager通过缓存名称<b>前缀</b>来识别缓存类型:
        * <ul>
        * <li>"redis_": redis cache</li>
        * <li>"ehcache_": ehcache cache</li>
        * </ul>
        * 该实例是spring操作缓存所必须的,且需要保证唯一,这意味着如果还需要Spring集成其它缓存中间件,
        * 仍然需要集成到combineCacheManager。<br>
        *
        * @see CachingConfigurerSupport#cacheManager()
        */
       @Bean(name = "combineCacheManager")
       @Override
       public CacheManager cacheManager() {
          logger.info("执行了CombineCacheConfig.cacheManager()方法..." + "\nredisCacheManager=" + redisCacheManager
                + " ehCacheCacheManager=" + ehCacheCacheManager + "\n");
          
          return new CacheManager() {
             @Override
             public Collection<String> getCacheNames() {
                logger.info("执行了CombineCacheConfig.cacheManager()#getCacheNames()方法...\n");
                Collection<String> cacheNames = new ArrayList<String>();
                if (redisCacheManager != null) {
                   cacheNames.addAll(redisCacheManager.getCacheNames());
                }
                if (ehCacheCacheManager != null) {
                   cacheNames.addAll(ehCacheCacheManager.getCacheNames());
                }
                return cacheNames;
             }
             
             @Override
             public Cache getCache(String name) {
                logger.info("执行了CombineCacheConfig.cacheManager()#getCache(String name)方法...name=" + name + "\n");
                if (name.startsWith(REDIS_PREFIX)) {
                   return redisCacheManager == null ? null : redisCacheManager.getCache(name);
                }
                if (name.startsWith(EHCACHE_PREFIX)) {
                   return ehCacheCacheManager == null ? null : ehCacheCacheManager.getCache(name);
                }
                return null;
             }
          };
       }
       
       /**
        * 构建默认的键生成器
        *
        * @see CachingConfigurerSupport#keyGenerator()
        */
       @Bean
       @Override
       public KeyGenerator keyGenerator() {
          logger.info("执行了CacheCombineConfig.keyGenerator()方法..." + "\nredisCacheManager=" + redisCacheManager
                + " ehCacheCacheManager=" + ehCacheCacheManager + "\n");
          
          return new KeyGenerator() {
             @Override
             public Object generate(Object target, Method method, Object... params) {
                //logger.info("执行了CombineCacheConfig.keyGenerator()#generate()方法...\n");
                StringBuilder keyStrBuilder = new StringBuilder();
                keyStrBuilder.append(target.getClass().getName()).append(".");
                keyStrBuilder.append(method.getName()).append(":");
                for (Object _param : params) {
                   keyStrBuilder.append(_param.toString()).append(",");
                }
                //logger.info("keyStrBuilder.toString()="+ keyStrBuilder.toString()+ "\n");
                return keyStrBuilder.toString();
             }
          };
       }
       
       public RedisCacheManager getRedisCacheManager() {
          return redisCacheManager;
       }
       
       public void setRedisCacheManager(RedisCacheManager redisCacheManager) {
          //logger.info("执行了setRedisCacheManager()方法...");
          this.redisCacheManager = redisCacheManager;
       }
       
       public EhCacheCacheManager getEhCacheCacheManager() {
          return ehCacheCacheManager;
       }
       
       public void setEhCacheCacheManager(EhCacheCacheManager ehCacheCacheManager) {
          //logger.info("执行了setEhCacheCacheManager()方法...");
          this.ehCacheCacheManager = ehCacheCacheManager;
       }
       
    }

    二、ehcache的相关配置

    2.1、ehcache和spring整合时用到的相关类

    此处列出了ehcache和spring整合时用到的相关类,及其关联。

    (1)关于CacheManager

    Ehcache Jar包中的实现:

    net.sf.ehcache.CacheManager。

    org.springframework:spring-context中的实现:

    org.springframework.cache.ehcache.EhCacheCacheManager;

    Extends AbstractTransactionSupportingCacheManager;

    AbstractTransactionSupportingCacheManager class;

    Extends AbstractCacheManager;

    AbstractCacheManager class;

    Implements CacheManager, InitializingBean;

    org.springframework.cache.ehcache.EhCacheCacheManager class;

    //其内部引入了net sf.ehcache.CacheManager。

    Private net sf.ehcache.CacheManager cacheManager;

    (2)关于Cache

    Ehcache Jar包中的实现:

    Net.sf.ehcache.Cache class;

    Implements InternalEhcache, StoreListener;

    net.sf.ehcache.terracotta.InternalEhcache interface;

    Extends Ehcache;

    net.sf.ehcache.Ehcache interface;

    Extends Cloneable;

    org.springframework:spring-context中的实现:

    org.springframework.cache.ehcache.EhCacheCache class;

    Implements org.springframework.cache.Cache;

    org.springframework.cache.ehcache.EhCacheCache class;

    //其内部引入了net.sf.ehcache.Ehcache,实际上存储的是net.sf.ehcache.Cache对象。

    Private final Ehcache cache;

    2.2、pom中引入

    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-cache</artifactId>
       <version>${spring.boot.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
    <dependency>
       <groupId>net.sf.ehcache</groupId>
       <artifactId>ehcache</artifactId>
       <version>2.10.9.2</version>
    </dependency>

    2.3、ehcache的使用

    EhcacheService的代码:

    package com.snail.spt4.basecommon.cache.ehcache.service;

    import com.xcer.sptservice.utils.strprocess.Constants;
    import net.sf.ehcache.CacheManager;
    import net.sf.ehcache.Ehcache;
    import net.sf.ehcache.Element;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.cache.ehcache.EhCacheCacheManager;
    import org.springframework.stereotype.Service;

    import javax.annotation.Resource;

    /**
     * ehcache服务类。
     * @author cjw 2021/12/30
     */
    @Service
    public class EhcacheService {
       
       private static Logger logger= LoggerFactory.getLogger(EhcacheService.class);
       
       @Resource
       private EhCacheCacheManager ehCacheCacheManager;
       
       
       
       
       /**
        * 向ehcache_temp缓存区域中存入信息。
        * @param timeToLive 存活时间 单位秒
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       public String putInfo(String key, Object value, int timeToLive) {
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache(EhcacheConstant.EHCACHE_TEMP);
          
          Element element= new Element(key, value, timeToLive, timeToLive);
          ehcache.put(element);
          return Constants.SUCCESS;
       }
       
       /**
        * 从ehcache_temp缓存区域中取信息。
        * @params
        * @return
        * @author cjw 2022/1/3
        */
       public Object getInfo(String key) {
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache(EhcacheConstant.EHCACHE_TEMP);
          
          Element element= ehcache.get(key);
          if(element== null) {
             return null;
          }
          Object value= element.getObjectValue();
          return value;
       }
       
       
       

    }

    ContrEhcacheTest的代码:

    package com.snail.spt4.basecommon.cache.ehcache.controller;

    import com.snail.spt4.basecommon.cache.redis.utils.RedisConstant;
    import com.snail.spt4.modules.mcommon.utils.entity.RespStructCustom;
    import com.xcer.sptservice.utils.strprocess.ObjectParse;
    import com.xcer.sptservice.utils.strprocess.StrUtil;
    import net.sf.ehcache.CacheManager;
    import net.sf.ehcache.Ehcache;
    import net.sf.ehcache.Element;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.cache.Cache;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cache.ehcache.EhCacheCacheManager;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;

    import javax.annotation.Resource;
    import java.util.Map;

    /**
     * @author cjw 2022/1/3
     */
    @RequestMapping(value = "/bc/ehcacheTest")
    @RestController
    public class ContrEhcacheTest {
       
       private static Logger logger= LoggerFactory.getLogger(ContrEhcacheTest.class);
       
       public static final String ClassName= "com.snail.spt4.basecommon.cache.ehcache.controller.ContrEhcacheTest";
       
       @Resource
       private EhCacheCacheManager ehCacheCacheManager;
       
       
       /**
        * 测试缓存。
        * @params
        * @return
        * @author cjw 2021/12/29
        */
       @Cacheable(value="ehcache_test", key="'"+ClassName+".testCache:map.uuid='+#map[\"uuid\"]")
       @RequestMapping(value = "/testCache")
       public RespStructCustom testCache(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrint("testCache().map", map);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       @Cacheable(value= RedisConstant.REDIS_HALFHOUR, key="'"+ClassName+".testCache2:map.uuid='+#map[\"uuid\"]")
       @RequestMapping(value = "/testCache2")
       public RespStructCustom testCache2(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrint("testCache2().map", map);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       @RequestMapping(value = "/testCache3")
       public RespStructCustom testCache3(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache3().map", map);
          
          //Collection<String> cacheNames= ehCacheCacheManager.getCacheNames();
          //StrUtil.prettyPrint("cacheNames", cacheNames);
          
          Cache cache= ehCacheCacheManager.getCache("ehcache_test");
          
          cache.put("key_1", "value_1");
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       @RequestMapping(value = "/testCache4")
       public RespStructCustom testCache4(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache4().map", map);
          
          Cache cache= ehCacheCacheManager.getCache("ehcache_test");
          
          Cache.ValueWrapper valueWrapper= cache.get("key_1");
          if(valueWrapper== null) {
             System.out.println("未找到key_1对应的值...");
          }
          Object value= valueWrapper==null? null: valueWrapper.get();
          System.out.println("key_1 value="+ value);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       @RequestMapping(value = "/testCache5")
       public RespStructCustom testCache5(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache5().map", map);
          
          String key= ObjectParse.parse2Str(map.get("key"));
          String value= ObjectParse.parse2Str(map.get("value"));
          int timeToLive= ObjectParse.parse2Int(map.get("timeToLive"));
          
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache("ehcache_test");
          
          Element element= new Element(key, value, timeToLive, timeToLive);
          ehcache.put(element);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2022/1/2
        */
       @RequestMapping(value = "/testCache6")
       public RespStructCustom testCache6(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache6().map", map);
          
          String key= ObjectParse.parse2Str(map.get("key"));
          
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache("ehcache_test");
          
          Element element= ehcache.get(key);
          
          StrUtil.prettyPrintWithTime("element", element);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2021/12/31
        */
       @RequestMapping(value = "/testCache7")
       public RespStructCustom testCache7(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache7().map", map);
          
          String key= ObjectParse.parse2Str(map.get("key"));
          String value= ObjectParse.parse2Str(map.get("value"));
          //int timeToLive= ObjectParse.parse2Int(map.get("timeToLive"));
          
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache("ehcache_test");
          
          Element element= new Element(key, value);
          ehcache.put(element);
          
          return RespStructCustom.success();
       }
       
       /**
        *
        * @params
        * @return
        * @author cjw 2022/1/2
        */
       @RequestMapping(value = "/testCache8")
       public RespStructCustom testCache8(@RequestParam Map<String, Object> map) {
          StrUtil.prettyPrintWithTime("testCache8().map", map);
          
          String key= ObjectParse.parse2Str(map.get("key"));
          
          CacheManager cacheManager= ehCacheCacheManager.getCacheManager();
          Ehcache ehcache= cacheManager.getEhcache("ehcache_test");
          
          Element element= ehcache.get(key);
          
          StrUtil.prettyPrintWithTime("element", element);
          
          return RespStructCustom.success();
       }
       
       
       
    }

    三、总结

    至此,springboot项目整合ehcache和redis的过程中,ehcache部分的配置的介绍,就暂时结束了。

    展开全文
  • Ehcache Redis区别有:前者操作简单易使用,存取速度快,效率更高但是不适合大型的分布式集群部署。而后者更适合用于大数据缓存,数据恢复等。 Ehcache介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速...

    Ehcache 和 Redis的区别有:前者操作简单易使用,存取速度快,效率更高但是不适合大型的分布式集群部署。而后者更适合用于大数据缓存,数据恢复等。


     Ehcache介绍

    EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。另外Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现。它支持注解方式使用缓存,非常方便。

    Ehcache的特点

    (1)快速简单,具有多种缓存策略

    (2)缓存数据有两级为内存和磁盘,缓存数据会在虚拟机重启的过程中写入磁盘

    (3)可以通过RMI、可插入API等方式进行分布式缓存

    (4)具有缓存和缓存管理器的侦听接口

    (5)支持多缓存管理器实例,以及一个实例的多个缓存区域。并提供Hibernate的缓存实现



    Redis介绍

    Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis是一个key-value存储系统。它支持存储的value类型很多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。Redis数据都是缓存在内存中。Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。

    Redis的特点:

    (1)速度快,持久化。并且Redis的所有数据都存储在内存中。

    (2)支持多种数据结构例:String、List、Set、Hash、Zset

    (3)支持多种编程语言例:Java、php、Python、Ruby、Lua、Node.js

    (4)功能丰富 ,除了支持五种数据结构之外,还支持事务、流水线、发布/订阅、消息队列等功能。

    (5)主服务器(master)执行添加、修改、删除,从服务器执行查询。

    Ehcache 和 Redis 比较


     以上就是ehcache和redis有什么区别的详细内容。

    展开全文
  • 一、摘要 1.1、Spring3.1开始内置了五个缓存管理器实现,如下所示: ...二、集成Ehcache 三、集成Redis 注意点:原生的spring cache不支持缓存过期,默认都是没有过期时间的,需要自定义...

    一、摘要

            1.1、Spring3.1开始内置了五个缓存管理器实现,如下所示:

    • SimpleCacheManager
    • NoOpCacheManager
    • ConcurrentMapCacheManager
    • CompositeCacheManager
    • EhcacheCacheManager

            1.2、Spring3.2引入了另外一个缓存管理器,这个管理器可以用在基于Jcache(JSR-107)的缓存供应商之中。除了核心的spring框架,spring data又提供了两个缓存管理器。

    • RedisCacheManager
    • GemfireCacheManager

    JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

    今天我们要讲的是Srping目前集成使用比较广泛的Ehcache和Redis集成方式。

    二、集成Ehcache

    主要依赖包是spring-boot-starter-cache和ehcache,如下:

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.0</version>
            <relativePath/>
        </parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cache</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>spring-cache</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.0-RC1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- mybatis plus 代码生成器 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.2.0</version>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.71</version>
            </dependency>
    
            <!--spring的集成缓存框架的jar-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    
            <!--spring要集成的ehcache缓存jar-->
            <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
            </dependency>
    
        </dependencies>

     resources目录下配置ehcache.xml配置文件():

    <?xml version="1.0" encoding="UTF-8" ?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="../../../../../../ehcache.xsd">
    
        <!-- 磁盘缓存位置 -->
        <diskStore path="java.io.tmpdir"/>
        <!--defaultCache:echcache 的默认缓存策略 -->
    <!--    <defaultCache-->
    <!--            maxElementsInMemory="10000"-->
    <!--            eternal="false"-->
    <!--            timeToIdleSeconds="300"-->
    <!--            timeToLiveSeconds="300"-->
    <!--            maxElementsOnDisk="10000000"-->
    <!--            diskExpiryThreadIntervalSeconds="300"-->
    <!--            memoryStoreEvictionPolicy="LRU">-->
    <!--        <persistence strategy="localTempSwap"/>-->
    <!--    </defaultCache>-->
        <!-- 根据id查询博客方法 -->
        <cache name="blog:queryById"
               maxElementsInMemory="30"
               eternal="false"
               timeToIdleSeconds="30"
               timeToLiveSeconds="30"
               maxElementsOnDisk="10000000"
               diskExpiryThreadIntervalSeconds="300"
               memoryStoreEvictionPolicy="LRU">
            <persistence strategy="localTempSwap"/>
        </cache>
    
    </ehcache>

    ehcache属性注解:
    1、name:缓存名称。
    2、maxElementsInMemory:缓存最大个数。
    3、eternal:对象是否永久有效,一但设置了,timeout将不起作用。
    4、timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
    5、timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
    6、overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
    7、diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
    8、maxElementsOnDisk:硬盘最大缓存个数。
    9、diskPersistent:是否缓存虚拟机重启期数据(Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
    10、diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
    11、memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
    12、clearOnFlush:内存数量最大时是否清除。
     

     ehcache管理器的实现:

    @Component
    public class EhCacheManager {
    
        /**
         * ehcache缓存管理器
         * @return
         */
        @Bean(name = "ehCacheCacheManager")
        EhCacheCacheManager cacheManager() {
            EhCacheCacheManager cacheManager = new EhCacheCacheManager();
            //设置事物失败回滚(如果失败,缓存也会回滚)
            cacheManager.setTransactionAware(Boolean.TRUE);
            return cacheManager;
        }
    
    }

     application.yml关键配置:

      # 关联Ehcache的配置文件
    spring:
       cache:
         ehcache:
            config: classpath:ehcache.xml
         type: ehcache

    三、集成Redis

    主要依赖包是spring-boot-starter-cache和spring-boot-starter-data-redis,如下:

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.6.0</version>
            <relativePath/>
        </parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cache</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>spring-cache</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>2021.0.0-RC1</spring-cloud.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <!-- mybatis plus 代码生成器 -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.2.0</version>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.71</version>
            </dependency>
    
            <!--spring的集成缓存框架的jar-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    
            <!--spring要集成的redis缓存jar-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
        </dependencies>

    注意点:原生的spring cache不支持缓存过期,默认都是没有过期时间的,需要自定义缓存过期时间,所以cache管理器有点特殊。

    redisCache管理器的实现:

    @Slf4j
    @Configuration
    public class CustomizerRedisCacheManager {
    
        @Value("${redis.cache.initialCacheNamesAndDuration}")
        private String[] initialCacheNames;
    
        //分隔符
        private static final String SEPARATOR = "#";
        //有效时间的正则表达式
        private Pattern pattern = Pattern.compile("(?:([-+]?[0-9]+)H)|(?:([-+]?[0-9]+)M)|(?:([-+]?[0-9]+)S)", Pattern.CASE_INSENSITIVE);
    
        @Bean(name = "redisCacheManager")
        @Primary //自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者
        public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
            RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
    
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();
            Map<String, RedisCacheConfiguration> initialCacheConfigurations = new LinkedHashMap();
    
            for (String initialCacheName : initialCacheNames) {
                String cacheName = initialCacheName.substring(0, initialCacheName.indexOf(SEPARATOR));
                String durationStr = initialCacheName.substring(initialCacheName.lastIndexOf(SEPARATOR) + 1);
    
                Duration duration;
                try {
                    duration = parseDuration(durationStr);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    continue;
                }
    
                // redis配置缓存key的有效时间、key的序列化器、value的序列化器
                RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(duration) //设置缓存key有效时间
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(getJackson2JsonRedisSerializer()))
                        .disableCachingNullValues();
    
                initialCacheConfigurations.put(cacheName, cacheConfiguration);
            }
    
            RedisCacheManager cacheManager = RedisCacheManager.builder(redisCacheWriter)
                    .withInitialCacheConfigurations(initialCacheConfigurations)
                    .build();
            return cacheManager;
        }
    
        /**
         * 解析时间单位字符串
         * @param duration
         * @return
         */
        private Duration parseDuration(@Nullable String duration) {
            Matcher matcher = pattern.matcher(duration);
            if(! matcher.matches()){
                throw new RuntimeException("过期时间格式是冒号后面数字跟H/M/S.");
            }
    
            if(duration.endsWith("H")){
                return Duration.ofHours(Long.valueOf(duration.replace("H", "")));
            }
            if(duration.endsWith("M")){
                return Duration.ofHours(Long.valueOf(duration.replace("M", "")));
            }
            if(duration.endsWith("S")){
                return Duration.ofHours(Long.valueOf(duration.replace("S", "")));
            }else{
                throw new RuntimeException("未识别的有效时间单位:" + duration);
            }
        }
    
    
        public RedisSerializer getJackson2JsonRedisSerializer(){
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    
            ObjectMapper objectMapper = new ObjectMapper();
            //反序列化时智能识别变量名(识别没有按驼峰格式命名的变量名)
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    
            //反序列化识别对象类型
            //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 该方法已废弃,使用activateDefaultTyping(...)代替
            objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance ,
                    ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
    
            //反序列化如果未识别的属性,不抛出异常
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            //反序列化如果碰到不识别的枚举值,是否作为空值解释,true:不会抛不识别的异常, 会赋空值,false:会抛不识别的异常
            objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
    
            jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
            return jackson2JsonRedisSerializer;
    
        }
    }

    application.yml的关键配置:

    #redis缓存key的有效时间配置
    redis:
      cache:
        initialCacheNamesAndDuration: blog:queryById#10S
    
    #redis配置
    spring:
      redis:
        host: localhost
        port: 6379
        database: 0

    参考文章:

    1、https://segmentfault.com/a/1190000022548904

    2、springboot使用cache集成redis(自定义每个key过期时间)_JGMa_TiMo的博客-CSDN博客

    展开全文
  • NULL 博文链接:https://greemranqq.iteye.com/blog/1997809
  • ehcacheredis集成,提供数据拦截器解决缓存穿透问题。同时,二级缓存大大降低了缓存雪崩击穿的可能性。此外,还提供了redis超时键本地同步删除功能,缓解了redis与本地缓存的数据一致性问题。 开源项目github ...
  • ehcache结合redis在springBoot下实现二级缓存功能。。。
  • 支持多级缓存进入,这里以ehcache和redis作为例子 1.导入相关依赖 引入spring支持cache的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-
  • ehcache和redis区别

    2018-03-29 13:16:27
    redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群分布式缓存方便,有成熟的方案。如果是单个应用或者对缓存访问要求很高的应用,用ehcache。如果是大型系统,存在缓存共享、分布式...
  • Redis和Ehcache区别

    千次阅读 2019-10-17 11:43:56
    Redis ...EhcacheRedis明显不同,它与java程序是绑在一起的,java程序活着,它就活着。譬如,写一个独立程序放数据,再写一个独立程序拿数据,那么是拿不到数据的。只能在独立程序中才能拿到数据...
  • Ehcache集群模式由于 EhCache 是进程中的缓存系统,一旦将应用部署在集群环境中,每一个节点维护各自的缓存数据,当某个节点对缓存数据进行更新,这些更新的数据无法在其它节点中共享,这不仅会降低节点运行的效率,...
  • Ehcache,Redis的上课知识点整理。由上课老师编写的每一个知识点与整合的概要。非常好的整体复习方案, 需要的赶紧下载
  • EhcacheRedis比较

    千次阅读 2018-03-17 22:06:22
    1. Ehcache简介 EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE轻量级容器。它具有内存...
  • 1.redis已在上一篇中集成,这里就直接上ehcache了 需要jar报:ehcache-2.10.5.jar ehcache-core-2.4.5.jar ehcache-spring-annotations-1.2.0.jar 2.配置ehcache.xml <?xml version="1.0" encoding="UTF-8"?> ...
  • 问题描述场景:我们的应用系统是分布式集群的,可横向扩展的。应用中某个接口操作满足以下一个...考虑到上述条件,我们需要一套高可用分布式的缓存集群,并具备持久化功能,备选的有ehcache集群或redis主备(sentine...
  • Redis和Ehcache区别

    2021-01-15 21:48:24
    redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群分布式缓存方便,有成熟的方案。 如果是单个应用或者对缓存访问要求很高的应用,用ehcache。 如果是大型系统,存在缓存共享、分布式...
  • ehcache和redis差别

    2019-04-03 18:27:11
    redis是独立运行的程序,通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群分布式缓存方便,有成熟的方案。 如果是单个应用或者对缓存访问要求很高的应用,用ehcache。 如果是大型系统,...
  • 主要介绍了SpringBoot中Shiro缓存使用RedisEhcache的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • SecondaryCache 基于ehcacheredis实现的二级缓存系统,用akka实现服务器间缓存数据变化后的通信 详细说明见:
  • 可以单独使用,一般在第三方库中被用到的比较多(如mybatis、shiro等)ehcache 对分布式支持不够好,多个节点不能同步,通常和redis一块使用。redis是通过socket访问到缓存服务,效率比Ehcache低,比数据库要快很多...
  • spring + ehcache + redis两级缓存

    热门讨论 2016-07-19 21:06:21
    spring + ehcache + redis两级缓存
  • 两级缓存在redis的方案上做一步优化,在缓存到远程redis的同时,缓存一份到本地进程ehcache(此处的ehcache不用做集群,避免组播带来的开销),取缓存的时候会先取本地,没有会向redis请求,这样会减少应用服务器<–...
  • 简要说明:ehcache是内存缓存,在本地jvm内存中,十分高效,但是如果缓存数据都存在jvm中,内存是不够用的,于是使用到了redis数据库缓存,redis是键值对数据库,也比较高效,如果仅用redis做缓存,则存在频繁的...
  • Redis和Ehcache缓存的区别 如果是单个应用或者对缓存访问要求很高的应用,用ehcache。 如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。 实际工作中使用Ehcache 我们在项目中使用...
  • 参考文献 ...Ehcache API文档 在线文档-ehcache2.5.2 项目环境 jeecg-boot (2.4.5) + Mybatis-plus_3.1.2 + Shiro_1.4.0 + Jwt_3.7.0 需求描述 因为jeecgboot 当前版本中,缓存绑定.
  • 在pom同时引入cache, ehcache,redis 后 ![图片说明](https://img-ask.csdn.net/upload/202003/09/1583738822_87579.png) 这些缓存注解操作的是 redis还是ehcache ? 或者怎么去设置让它使用redis还是
  • springboot整合ehcache+redis实现双缓存

    万次阅读 2019-03-25 22:43:55
    在一些对并发业务要求较高的场景下,对页面数据的响应是个急需解决的...要么太复杂,要么太简单,最近抽空思考了一下这一思路的简单实现,下面就用springboot整合ehcache和redis来说明一下实现的过程, 需求说明,...
  • ehcache和redis区别

    千次阅读 2018-05-08 12:12:37
    redis是通过socket访问到缓存服务,效率比ecache低,比数据库要快很多,处理集群分布式缓存方便,有成熟的方案。如果是单个应用或者对缓存访问要求很高的应用,用ehcache。如果是大型系统,存在缓存共享、分布式...
  • redis默认情况下就是使用LRU策略的,因为内存是有限的,但是如果你不断地往redis里面写入数据,那肯定是没法存放下所有的数据在内存的 所以redis默认情况下,当内存中写入的数据很满之后,就会使
  • 一、Spring Boot整合Ehcache 如果对Ehcache不了解可以查看一下文档,进行了解 1 修改 pom 文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,513
精华内容 7,405
热门标签
关键字:

ehcache和redis的区别