Java操作Redis的方式

  Java 操作 Redis 的方式有下面两种:

  一、jedis

  (1)maven 配置

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

  (2)相关类

  • 单节点:redis.clients.jedis.Jedis
  • 集群:redis.clients.jedis.JedisCluster

  (3)说明

  • 使用的类和 api 不一样, 导致对 redis 单节点和集群要特地区别对待。
  • 无法集成 springCache。
  • JedisCluster 没有对象序列化 / 反序列化 api,需要自己实现。
  • jedis2.7 版本才正式支持 JedisCluster。

  二、spring-data-redis

  (1)maven 配置

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.8.4.RELEASE</version>
</dependency>

  (2)相关类

  • 单节点:org.springframework.data.redis.core.RedisTemplate
  • 集群:org.springframework.data.redis.core.RedisTemplate

  (3)说明

  • 使用方式统一,如:
redisTemplate.opsForValue().set(key, object);
redisTemplate.opsForHash().put(key, hashKey, object);
  • 可以集成 SpringCache。

  • 自带序列化功能,4 种:
stringRedisSerializer
JdkSerializationRedisSerializer
Jackson2JsonRedisSerializer
OxmSerializer

  (4)SpringCache 功能

  Spring 3.1 引入了基于注解(annotation)的缓存(cache)技术,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果,支持和主流的专业缓存例如 EHCache,Memcache,Redis 等集成, 也支持以自行扩展。注解可以标记在一个类上,也可以标记在方法上。

  • 开启 SpringCache 功能:@EnableCaching
  • SpringCache 注解:
@Cacheable   --执行方法前, 判断有无缓存,如果有直接从缓存中获取结果进行返回, 否则放入缓存
@CacheEvict  --触发缓存的清除操作
@CachePut    -- 每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中
  • 优点:
  1. 减少手写缓存代码量,通过少量的注释标签和配置文件,即可达到使代码具备缓存的能力。
  2. 底层 Cache 类型更换代码无需改动,如由 EHCache 换成 Redis。

  • 缺点:
  1. 注解无过期时间 expire 属性, 需自行扩展。
  2. 使用限制:基于 proxy 的 spring aop 带来的内部调用问题,如 this 内部调用,非 public 方法调用等。

  3. 放入缓存方法只使用 connection.set,即缓存存入 Redis 都是 String 字符串类型。

  (5)Tomcat 插件 RedisSessionManager

  分布式系统要将 HttpSession 放入 Redis 共享,代码又不想改动的话,那么可以通过 RedisSessionManager 来集成,可以引入第三方插件 RedisSessionManager 和相关 jar,在 tomcat 下配置即可。

  • 配置
引入插件:
\Tomcat7\conf\context.xml 下配置
    <Valve className="com.r.tomcat.session.management.RequestSessionHandlerValve"/>
    <Manager className="com.r.tomcat.session.management.RequestSessionManager"/>

\Tomcat7\conf\RedisDataCache.properties 配置
redis.hosts=127.0.0.1:6379, 127.0.0.2:6379, 127.0.0.2:6380, ....
redis.password
=
redis.cluster.enabled
=true

  • 优点

  session 的代码写法不用动,依然使用传统写法 session.setAttribute(key,value);引入插件后 session 由本地 tomcat 存储改为了 Redis,重启 tomcat 也不用担心 session 消失。

  • 缺点

  只能用于 tomcat。

  (6)SpringSession

  这个技术重写了 HttpSession,以 SpringSession 来做,Spring Session 提供了集群 Session(Clustered Sessions)功能, 默认采用外置的 Redis 来存储 Session 数据,以此来解决 Session 共享的问题。

  • 配置
maven:
    <dependency>  
       <groupId>org.springframework.session</groupId>  
       <artifactId>spring-session-data-redis</artifactId>  
    </dependency>
开启 Reids 键空间通知功能: notify-keyspace-events AKE

开启 Redis 存储 springSession:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=1800)

  • 优点
  1. 和 web 服务器无关,甚至可以不用 web 服务器,也能支持 session,是一种独立于应用服务器的方案。
  2. 配合 spring-data-redis.jar 使用,能够支持 Redis 单节点、Sentinel、Redis3.x 集群等。
  3. HttpSession 代码无需做任何改动,依然使用传统写法 session.setAttribute(key,value)。
  4. SpringSession 最新版本支持 HttpSessionListener。
  • 缺点
  1. 依赖 Spring。

  2. Spring 版本要是 4.1.6 以上,servlet 要是 3.0.1 以上,这样对 JDK(1.6+)和 web 服务器 (tomcat7+) 版本有限制。

  (7)SpringSession 使用 session 监听器

  SpringSession 最新版本支持 HttpSessionListener,该监听器可以捕捉到 session 创建和销毁,内部采用 Redis 的 Sub/Pub+ 键空间通知功能实现。

  • 监听器类
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=1800)
public class RedisHttpSessionConfig {
    /**
     * 注入监听器
     */
    @Bean
    public SessionEventHttpSessionListenerAdapter listenerAdapter() {
        List<HttpSessionListener> listenerList = new ArrayList<>();
        listenerList.add(new SessionListener()); // 注入自己的 SessionListener 类
        return new SessionEventHttpSessionListenerAdapter(listenerList);       
    }
}
  • 说明
  1. HttpSessionListener 不推荐在 RedisCluster 下使用:因 sessionDestoryed 采取的是 Redis 键空间通知功能,键空间通知功能是在 Redis2.8 开始新推出的,但在 RedisCluster 下键空间通知功能有 bug,event 触发时不会 publish 通知到所有节点,只对本节点的 master/slave 通知,故使用 redisCluster 的环境下,有可能会订阅收不到 sessionDestroyed 消息,故不推荐在 RedisCluster 下使用 HttpSessionListener。需要自己去实现 SUBSCRIBE 各个 Redis 节点捕捉 sessionDestoryed 功能。

  2. 重复监听:当一个 session 销毁时,那么我们的 listener 的 sessionDestroyed 方法、所有微服务实例都会收到事件通知。会导致重复,故需要注意这点,需要应用自行控制重复问题。