项目中Redis单机版本与集群版本的配置与功能的实现

近期在项目中使用到了Redis用作缓存, 减少了MySQL的压力, 为什么会用redis用作缓存? 一点是因为redis能够支持多种数据类型(String , list, Set, Hash, Zset), 二是redis中的数据都是加载到内存中进行缓存, 可以设置数据有效时间, 故响应速度非常之快, 而且还有各种非常强大的功能例如数据淘汰机制, 过多的这里就不再做陈述; 主要是记录自己在项目中使用到的redis的配置与功能接口的开发; 方便后期的整理与回顾; 

项目使用到的是Maven来进行整个的项目搭建, 使用聚合工程的方式方便了各种jar包的统一管理与服务之间的依赖调用; 那么鉴于以上所说, redis缓存服务可能会被用于多个服务做缓存, 那么我就将redis服务的接口与实现类放到了统一的公共工程下common; 

项目结构

服务调用方

在common工程下的pom.xml文件添加依赖

 

1. 配置redis.properties文件

#单机版Redis
jedisPool.host=192.168.12.128
jedisPool.port=6379

#集群版Redis
cluster.redis1.host=192.168.12.128
cluster.redis1.port=7001
cluster.redis2.host=192.168.12.128
cluster.redis2.port=7002
cluster.redis3.host=192.168.12.128
cluster.redis3.port=7003
cluster.redis4.host=192.168.12.128
cluster.redis4.port=7004
cluster.redis5.host=192.168.12.128
cluster.redis5.port=7005
cluster.redis6.host=192.168.12.128
cluster.redis6.port=7006

 

2. 准备RedisService接口

/**
 * Redis服务接口
 * @author 黄家大少
 *
 */
public interface RedisService {
    
    /**
     * 设置键与值
     * @param key   键
     * @param value 值
     * @return
     */
    String set(String key, String value);
        
    /**
     * 设置键与值的有效时间
     * @param key      键
     * @param value    值
     * @param seconds  时间: 秒
     * @return
     */
    String setex(String key, String value, int seconds);
     
    /**
     * 设置键的有效时间
     * @param key     键
     * @param seconds 时间: 秒
     * @return
     */
    Long expire(String key, int seconds);
      
    /**
     * 获取一个键的值
     * @param key  键
     * @return     值
     */
    String get(String key);
   
    /**
     * 删除一个键
     * @param key 键
     * @return    状态码
     */
    Long del(String key);
    
    /**
     * 获取一个键的自增长的值
     * @param key
     * @return
     */
    Long incr(String key); 
}
 

接口实现类中, 会出现很多重复的操作, 这里我使用了命令模式将公共操作模式抽取出来;

                                                   

                                                     

 

Redis集群操作实现类JedisClusterServiceImpl

import javax.annotation.Resource;
import ******.common.redis.RedisService;
import redis.clients.jedis.JedisCluster;


/**
 * Redis集群操作实现类
 * @author 黄家大少
 *
 */
public class JedisClusterServiceImpl implements RedisService{
    
    /**
     * 全自动类型注入JedisCluster
     */
    @Resource
    private JedisCluster jedisCluster;
    

    @Override
    public String set(String key, String value) {
        return jedisCluster.set(key, value);
    }

    @Override
    public String setex(String key, String value, int seconds) {
        return jedisCluster.setex(key, seconds, value);
    }

    @Override
    public Long expire(String key, int seconds) {
        return jedisCluster.expire(key, seconds);
    }

    @Override
    public String get(String key) {
        return jedisCluster.get(key);
    }

    @Override
    public Long del(String key) {
        return jedisCluster.del(key);
    }

    @Override
    public Long incr(String key) {
        return jedisCluster.incr(key);
    }

}

 

Redis单机版服务接口实现类

import javax.annotation.Resource;

import com.******.common.redis.RedisFunction;
import com.******.common.redis.RedisService;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


/**
 * Redis单机版操作业务实现类
 * @author 黄家大少
 *
 */
@SuppressWarnings("all")
public class JedisPoolServiceImpl implements RedisService {
    
    //注入JedisPool
    @Resource
    private JedisPool jedisPool;
    
    
    /** 通用的执行方法 */
    private <T> T execute(RedisFunction<T> redisFunction){
        Jedis jedis = null;
        try{
            jedis = jedisPool.getResource(); 
            /** 命令模式  */
            return redisFunction.callback(jedis);
        }finally{
            /** 关闭jedis */
            if (jedis != null) jedis.close();
        }
    }

    /**
     * 设置键与值
     */
    @Override
    public String set(final String key, final String value) {    
        return execute(new RedisFunction<String>(){
            @Override
            public String callback(Jedis jedis) {
                return jedis.set(key, value);
            }        
        });
    }

    
    /**
     * 设置键值的有效时间
     */
    @Override
    public String setex(final String key, final String value, final int seconds) {    
        return execute(new RedisFunction<String>(){
            @Override
            public String callback(Jedis jedis) {
                return jedis.setex(key, seconds, value);
            }
        });
    }

    
    /**
     * 设置键的有效时间
     */
    @Override
    public Long expire(final String key, final int seconds) {    
        return execute(new RedisFunction<Long>(){
            @Override
            public Long callback(Jedis jedis) {
                return jedis.expire(key, seconds);
            }
        });
    }

    
    /**
     * 根据键获取值
     */
    @Override
    public String get(final String key) {    
        return execute(new RedisFunction<String>(){
            @Override
            public String callback(Jedis jedis) {
                return jedis.get(key);
            }
        });
    }

    
    /**
     * 删除一个键
     */
    @Override
    public Long del(final String key) {    
        return execute(new RedisFunction<Long>(){
            @Override
            public Long callback(Jedis jedis) {
                return jedis.del(key);
            }        
        });
    }

    
    /**
     * 获取一个键的自增长值
     */
    @Override
    public Long incr(final String key) {    
        return execute(new RedisFunction<Long>(){
            @Override
            public Long callback(Jedis jedis) {
                return jedis.incr(key);
            }
        });
    }

}
 

配置服务调用层的redis配置文件applicationContext-redis.xml

                                                            

applicationContext-redis.xml

在实际使用中, 如果需要使用单机版, 那么把集群版注释即可, 反之亦然;

 

在实际业务开发中, redis的业务逻辑是不影响原有的功能下进行添加, 即先从redis中查询是否存在相关数据, 如果没有, 就从数据库中查询出来然后放入redis中; 以下是示例:

如果没有, 则从数据库中查询出来:

那么完成这一系列操作后, 下次再进行以上操作, redis缓存中就会有相关数据, 就会直接访问redis中的目标数据; 以上一系列的操作必须建立在自己本机(我自己是在本机的liunx上安装了集群跟单机版的redis), 有相关的集群跟单机redis并成功启动正常运行的条件下; 

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值