Redis缓存技术和ehcache缓存技术应用

版权声明:原创不易,转载请注明出处,谢谢!!! https://blog.csdn.net/Java_monkeys/article/details/82769307

1.了解缓存cache之前了解一下什么是cache?

所谓cache,就是将程序或系统经常使用的对象存在内存中或在磁盘中创建缓存数据文件,以便再次使用时可以快速调用,有效的减少了再次从数据库中获取数据的开销,从而提高运行效率,减少等待时间。按照存储方式分为内存或磁盘;

如图所示:

通俗点说,当用户访问某个系统,但系统跟服务器的交互比较频繁,但是同时又有10w+的用户都在访问,如果服务器强大的话还能承受的住,但是如果说数据量到100w,1000w的时候怎么处理,这个时候的处理方式就是服务器的集群以及缓存技术的应用,来降低服务器的压力;

常用的cache技术:


 

本文只介绍两种本人使用过的缓存技术EHCache和redis,下边我们了解一下两种缓存技术

1.EHCache

1.1 概念

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


1.2 特点

  1. 快速简单,多种缓存策略
  2. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
  3. 缓存数据会在虚拟机重启的过程中写入磁盘
  4. 可以通过RMI、可插入API等方式进行分布式缓存
  5. 具有缓存和缓存管理器的侦听接口
  6.  支持多缓存管理器实例,以及一个实例的多个缓存区域
  7. 提供Hibernate的缓存实现
  8. 使用磁盘Cache的时候非常占用磁盘空间:这是因为DiskCache的算法简单,该算法简单也导致Cache的效率非常高。它只是对元素直接追加存储。因此搜索元素的时候非常的快。如果使用DiskCache的,在很频繁的应用中,很快磁盘会满;
  9. 不能保证数据的安全:当突然kill掉java的时候,可能会产生冲突,EhCache的解决方法是如果文件冲突了,则重建cache。这对于Cache数据需要保存的时候可能不利。当然,Cache只是简单的加速,而不能保证数据的安全。如果想保证数据的存储安全,可以使用Bekeley DB Java Edition版本。这是个嵌入式数据库。可以确保存储安全和空间的利用率。

1.3应用(框架基于spring+springBoot+maven

第一步

在pom.xml中加入ehcache依赖

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>${ehcache.version}</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-web</artifactId>
            <version>${ehcache-web.version}</version>
        </dependency>

 第二步

编写ehcache.xml文件


属性说明:

  •  name:缓存的名称;
  • maxElementsInMemory:缓存中最大元素个数。0表示不限制 ;
  • eternal:对象是否永久有效,一但设置了,timeout将不起作用,元素永久存在;
  • clearOnFlush:内存数量最大时是否清除;
  • timeToIdleSeconds : 设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大;
  • imeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大;
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒;
  • diskPersistent:是否在VM重启时存储硬盘的缓存数据。默认值是false;
  • maxElementsOnDisk:硬盘最大缓存个数;
  • overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中;
  • diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区;
  • maxEntriesLocalDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中;memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用);

<?xml version="1.0" encoding="UTF-8"?>
<ehcache updateCheck="false" name="defaultCache">

	<diskStore path="../temp/jeesite/ehcache" />

	<!-- 默认缓存配置. 自动失效:最后一次访问时间间隔300秒失效,若没有访问过自创建时间600秒失效。-->
	<defaultCache
			maxElementsInMemory="10000"
			maxEntriesLocalHeap="1000"
			eternal="false"
			timeToIdleSeconds="300"
			timeToLiveSeconds="600"
			overflowToDisk="true"
			statistics="true"/>
	
	<!-- 系统缓存 -->
	<cache name="sysCache" maxEntriesLocalHeap="1000" eternal="true" overflowToDisk="true" statistics="true"/>
	
	<!-- 用户缓存 -->
	<cache name="userCache" maxEntriesLocalHeap="1000" eternal="true" overflowToDisk="true" statistics="true"/>
	
	<!-- 集团缓存 -->
	<cache name="corpCache" maxEntriesLocalHeap="1000" eternal="true" overflowToDisk="true" statistics="true"/>
	
	<!-- 内容管理模块缓存 -->
	<cache name="cmsCache" maxEntriesLocalHeap="1000" eternal="true" overflowToDisk="true" statistics="true"/>
    
	<!-- 工作流模块缓存 -->
	<cache name="actCache" maxEntriesLocalHeap="100" eternal="true" overflowToDisk="true" statistics="true"/>
	
    <!-- 简单页面缓存 -->
    <cache name="pageCachingFilter" maxEntriesLocalHeap="1000" eternal="false" timeToIdleSeconds="120"
    	timeToLiveSeconds="120" overflowToDisk="true" memoryStoreEvictionPolicy="LFU" statistics="true"/>
	
	<!-- 系统活动会话缓存 -->
    <cache name="activeSessionsCache" maxEntriesLocalHeap="10000" eternal="true" overflowToDisk="true"
           diskPersistent="true" diskExpiryThreadIntervalSeconds="600" statistics="true"/>
    	
</ehcache>

第三步

在启动类上添加注解@EnableCaching以开启缓存支持。

@EnableCaching 
@SpringBootApplication 
@MapperScan("com.songguoliang.springboot.mapper") 
public class Application
{ 
  public static void main(String[] args) 
  { 
     SpringApplication.run(Application.class, args); 
  } 
}

 Spring提供了4个声明式缓存注解: 

  1. @Cacheable 在方法执行前Spring先查看缓存中是否存在,如果存在,则直接返回缓存数据,若不存在则调用方法并将方法返回值放进缓存
  2. @CachePut 无论怎样,都会将方法的返回值放到缓存中。@CachePut的属性与@Cacheable保持一致
  3. @CacheEvict 将一条或多条数据从缓存中删除。
  4. @Caching 可以通过@Caching注解组合多个注解策略在一个方法上。

2.Redis缓存技术

2.1概念

Redis(REmote DIctionary Server)是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。


2.2特点

  1. Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  2. Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
  3. Redis支持数据的备份,即master-slave模式的数据备份。
  4. 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
  5. 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
  6. 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
  7. 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

2.3应用(框架基于spring+springBoot+maven


第一步

在windows系统中安装redis,redis下载地址(https://github.com/MicrosoftArchive/redis/releases


第二步

在pom文件中引入redis依赖:

 <!-- springboot整合redis -->  
        <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-data-redis</artifactId>  
        </dependency> 

这里只需引入这一个redis的依赖即可,其他3个自动进行了依赖:


第三步

在application.yml中配置redis

spring:
    application:
        name: spring-boot-redis
    redis:
        host: 192.168.145.132
        port: 6379
        timeout: 20000
        cluster:
            nodes: 192.168.211.134:7000,192.168.211.134:7001,192.168.211.134:7002
            maxRedirects: 6
        pool:
            max-active: 8
            min-idle: 0
            max-idle: 8
            max-wait: -1

第四步

编写redis配置类

/**
 * redis配置类
 *
 * @author zcc ON 2018/3/19
 **/
@Configuration
@EnableCaching//开启注解
public class RedisConfig {
    @Bean
    public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
        CacheManager cacheManager = new RedisCacheManager(redisTemplate);
        return cacheManager;
        /*RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
        // 多个缓存的名称,目前只定义了一个
        rcm.setCacheNames(Arrays.asList("thisredis"));
        //设置缓存默认过期时间(秒)
        rcm.setDefaultExpiration(600);
        return rcm;*/
    }
    // 以下两种redisTemplate自由根据场景选择
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }
}

实现序列化接口(implements Serializable),然后就是逻辑代码;

以上内容主要介绍了EHCache和redis概念以及在本人实际项目中的应用,如有不好的地方请指出!!!


想深入学习redis,请点击以下网址:http://www.runoob.com/redis/redis-intro.html


原创不易,转载请注明出处!!!谢谢

猜你喜欢

转载自blog.csdn.net/Java_monkeys/article/details/82769307