Redis与 Spring的集成与缓存的实现

1.核心配置文件,特别注意版本,因为版本不同可能导致api的不同,注入方式可能有差别

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xsi:schemaLocation="  
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  

    <!-- 扫描包 -->
    <context:component-scan base-package="cn.itsource.jedis" />
    
    <!-- 连接池的信息 交给spring管理 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="50" />
        <property name="maxIdle" value="8" />
        <property name="maxWaitMillis" value="1000" />
        <property name="testOnBorrow" value="true"/>
        <property name="testOnReturn" value="true"/>
        <!-- <property name="testWhileIdle" value="true"/> -->
    </bean>
  
  <!-- 集群的配置 -->
    <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool"  scope="singleton">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1">
            <list>
                <bean class="redis.clients.jedis.JedisShardInfo">
                <property name="password" value="123456" /><!--set注入  -->
                    <constructor-arg name="host" value="localhost" />
                    <constructor-arg name="port" value="6379" />
                    <constructor-arg name="timeout" value="2000" />
                </bean>
            </list>
        </constructor-arg>
    </bean>
</beans>

二、另外还需要的工具类


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import redis.clients.jedis.ShardedJedis;

@Repository("redisClientTemplate")
public class RedisClientTemplate {

    private static final Logger log = LoggerFactory.getLogger(RedisClientTemplate.class);

    @Autowired
    private RedisDataSource     redisDataSource;

    public void disconnect() {
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        shardedJedis.disconnect();
    }

    /**
     * 设置单个值
     * 
     * @param key
     * @param value
     * @return
     */
    public String set(String key, String value) {
        String result = null;

        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }
        boolean broken = false;
        try {
            result = shardedJedis.set(key, value);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }

    /**
     * 获取单个值
     * 
     * @param key
     * @return
     */
    public String get(String key) {
        String result = null;
        ShardedJedis shardedJedis = redisDataSource.getRedisClient();
        if (shardedJedis == null) {
            return result;
        }

        boolean broken = false;
        try {
            result = shardedJedis.get(key);

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            broken = true;
        } finally {
            redisDataSource.returnResource(shardedJedis, broken);
        }
        return result;
    }
}

import redis.clients.jedis.ShardedJedis;

public interface RedisDataSource {
    public abstract ShardedJedis getRedisClient();
    public void returnResource(ShardedJedis shardedJedis);
    public void returnResource(ShardedJedis shardedJedis,boolean broken);
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

@Repository("redisDataSource")
public class RedisDataSourceImpl implements RedisDataSource {

    private static final Logger log = LoggerFactory.getLogger(RedisDataSourceImpl.class);

    @Autowired
    private ShardedJedisPool    shardedJedisPool;

    public ShardedJedis getRedisClient() {
        try {
            ShardedJedis shardJedis = shardedJedisPool.getResource();
            return shardJedis;
        } catch (Exception e) {
            log.error("getRedisClent error", e);
        }
        return null;
    }

    public void returnResource(ShardedJedis shardedJedis) {
        shardedJedisPool.returnResource(shardedJedis);
    }

    public void returnResource(ShardedJedis shardedJedis, boolean broken) {
        if (broken) {
            shardedJedisPool.returnBrokenResource(shardedJedis);
        } else {
            shardedJedisPool.returnResource(shardedJedis);
        }
    }
}

7.3.Redis经典实用场景-缓存
7.3.1.为什么要使用缓存
把经常查询的数据,很少修改的数据存放到缓存中,减少访问数据库,降低数据库压力并且缓存一般都是内存,访问速度比较快。
7.3.2.哪些数据适合放到缓存中
经常查询:缓存就是提供数据查询高效访问。
很少修改:修改时要同步修改缓存和数据库
例如:地区数据、商品分类、数据字典 菜单(不考虑权限)
7.3.3.选择合适的缓存
Hibernate二级缓存,mybatis二级缓存,redis中央缓存
Hibernate二级缓存,mybatis二级缓存默认不支持集群缓存,要使用redis
7.3.4.怎么存储数据
1) json:把要存放的数据转换为json类型的字符串
保存缓存时:
Java Object----------->json字符串
获取缓存:
json字符串-------->Java Object-
Json框架:jdk-json-lib jackson gson fastjson
在这里插入图片描述

2)二进制存放:把要存放的数据序列化为二进制
序列化框架实现

7.3.5.实现菜单缓存
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.4.淘汰策略
7.4.1.为什么要淘汰数据
淘汰一些数据,达到redis数据量都是有效的。选择合适的淘汰策略进行淘汰.怎么淘汰
volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意(随机)选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据(不删除任意数据.默认策略,但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误)

redis 确定驱逐某个键值对后,会删除这个数据并,并将这个数据变更消息发布到本地(AOF 持久化)和从机(主从连接)。

猜你喜欢

转载自blog.csdn.net/qq_41129811/article/details/84844075