• Redis 一二事


    Redis真是好,其中的键值用起来真心强大啊有木有,

    之前的文章讲过搭建了redis集群

    那么咋们该如何调用单机版的redis以及集群版的redis来使用缓存服务呢?

    先讲讲单机版的,单机版redis安装非常简单,不多说了,直接使用命令:

     1 [root@nginx bin]# ./redis-server redis.conf 

    启动就行

    在sprig文件中配置如下

     1 <!-- 
     2         TODO:
     3         开发环境使用单机版
     4         生产环境务必切换成集群
     5      -->
     6     <!-- 配置redis客户端单机版 -->
     7     <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
     8         <constructor-arg name="host" value="${redis.single.client.host}"></constructor-arg>
     9         <constructor-arg name="port" value="${redis.single.client.port}"></constructor-arg>
    10     </bean>
    11     <!-- 配置redis客户端实现类 -->
    12     <bean id="jedisClientSingle" class="com.lee.rest.component.impl.JedisClientSingle"/>
    13     
    14     <!-- 配置redis客户端集群版 单机版和集群版的jedis只能存在一个 -->
    15     <!-- <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
    16         <constructor-arg>
    17             <set>
    18                 <bean class="redis.clients.jedis.HostAndPort">
    19                     <constructor-arg name="host" value="${redis01.real.cluster.client.host}"/>
    20                     <constructor-arg name="port" value="${redis01.real.cluster.client.port}"/>
    21                 </bean>
    22                 <bean class="redis.clients.jedis.HostAndPort">
    23                     <constructor-arg name="host" value="${redis02.real.cluster.client.host}"/>
    24                     <constructor-arg name="port" value="${redis02.real.cluster.client.port}"/>
    25                 </bean>
    26                 <bean class="redis.clients.jedis.HostAndPort">
    27                     <constructor-arg name="host" value="${redis03.real.cluster.client.host}"/>
    28                     <constructor-arg name="port" value="${redis03.real.cluster.client.port}"/>
    29                 </bean>
    30                 <bean class="redis.clients.jedis.HostAndPort">
    31                     <constructor-arg name="host" value="${redis04.real.cluster.client.host}"/>
    32                     <constructor-arg name="port" value="${redis04.real.cluster.client.port}"/>
    33                 </bean>
    34                 <bean class="redis.clients.jedis.HostAndPort">
    35                     <constructor-arg name="host" value="${redis05.real.cluster.client.host}"/>
    36                     <constructor-arg name="port" value="${redis05.real.cluster.client.port}"/>
    37                 </bean>
    38                 <bean class="redis.clients.jedis.HostAndPort">
    39                     <constructor-arg name="host" value="${redis06.real.cluster.client.host}"/>
    40                     <constructor-arg name="port" value="${redis06.real.cluster.client.port}"/>
    41                 </bean>
    42             </set>
    43         </constructor-arg>
    44     </bean>
    45     <bean id="jedisClientCluster" class="com.lee.rest.component.impl.JedisClientCluster"/> -->

    这是配置的redis-cli的连接池

    然后定义一个接口,这个接口供两个类实现

    一个是单机版,一个是集群版

    有人会问为啥要2个类实现,因为redis的单机和集群都是不同的实现方法

    一般在开发环境会使用单机版来做测试,生产环境直接上集群

     1 #fake cluster
     2 redis.single.client.host=192.168.1.191
     3 redis.single.client.port=6379
     4 
     5 redis01.cluster.client.host=192.168.1.192
     6 redis01.cluster.client.port=7001
     7 
     8 redis02.cluster.client.host=192.168.1.192
     9 redis02.cluster.client.port=7002
    10 
    11 redis03.cluster.client.host=192.168.1.192
    12 redis03.cluster.client.port=7003
    13 
    14 redis04.cluster.client.host=192.168.1.192
    15 redis04.cluster.client.port=7004
    16 
    17 redis05.cluster.client.host=192.168.1.192
    18 redis05.cluster.client.port=7005
    19 
    20 redis06.cluster.client.host=192.168.1.192
    21 redis06.cluster.client.port=7006

    在你的资源文件中配好如上信息,供spring调用

    说个题外话,资源文件*.properties,在spring的父子容器中不是公用的

    也就是说,在service的spring容器中,只能配service层调用

    在springMVC容器中只能被springmvc自己调用,因为资源文件不是夸容器的

    而spring容器中的对象是可以被springMVC来访问的

    但是springMVC的对象以及资源文件绝对不能被spring来访问,

    举个栗子:你有见过service访问controller的吗?没有吧,哈哈

    咱们先来建一个通用jedis客户端

    (有2个小家伙看不懂最后2个方法什么意思,就加了注释,其实规范点来讲,所有的接口方法都要加注释,而实现类就不需要,但是实现类中的私有方法必须加注释,这是规范)

     1 package com.lee.rest.component;
     2 
     3 /**
     4  * 
     5  * @Title: JedisClient.java
     6  * @Package com.lee.rest.component
     7  * @Description: redis客户端
     8  * Copyright: Copyright (c) 2016
     9  * Company:Nathan.Lee.Salvatore
    10  * 
    11  * @author leechenxiang
    12  * @date 2016年4月27日 下午4:28:46
    13  * @version V1.0
    14  */
    15 public interface JedisClient {
    16 
    17     public String set(String key, String value);
    18     public String get(String key);
    19     public Long hset(String key, String item, String value);
    20     public String hget(String key, String item);
    21     public Long hdel(String key, String item);
    22     public Long incr(String key);
    23     public Long decr(String key);
    24     
    25     /**
    26      * 
    27      * @Description: 设置存存活时间
    28      * @param key
    29      * @param second
    30      * @return
    31      * 
    32      * @author leechenxiang
    33      * @date 2016年4月27日 下午4:34:35
    34      */
    35     public Long expire(String key, int second);
    36     
    37     /**
    38      * 
    39      * @Description: 判断key多久过期
    40      * @param key
    41      * @return42      *             >= 0     剩余秒数
    43      *             = -1    永久存活
    44      *             = -2    已经消除
    45      * 
    46      * @author leechenxiang
    47      * @date 2016年4月27日 下午4:34:22
    48      */
    49     public Long ttl(String key);
    50 }
     1 /**
     2  * 
     3  * @Title: JedisClientSingle.java
     4  * @Package com.lee.rest.component.impl
     5  * @Description: 单机版的jedis客户端操作
     6  * Copyright: Copyright (c) 2016
     7  * Company:Nathan.Lee.Salvatore
     8  * 
     9  * @author leechenxiang
    10  * @date 2016年4月27日 下午4:36:42
    11  * @version V1.0
    12  */
    13 public class JedisClientSingle implements JedisClient {
    14 
    15     @Autowired
    16     private JedisPool jedisPool;
    17 
    18     @Override
    19     public String set(String key, String value) {
    20         Jedis jedis = jedisPool.getResource();
    21         String result = jedis.set(key, value);
    22         jedis.close();
    23         return result;
    24     }
    25 
    26     @Override
    27     public String get(String key) {
    28         Jedis jedis = jedisPool.getResource();
    29         String result = jedis.get(key);
    30         jedis.close();
    31         return result;
    32     }
    33 
    34     @Override
    35     public Long hset(String key, String item, String value) {
    36         Jedis jedis = jedisPool.getResource();
    37         Long result = jedis.hset(key, item, value);
    38         jedis.close();
    39         return result;
    40     }
    41 
    42     @Override
    43     public String hget(String key, String item) {
    44         Jedis jedis = jedisPool.getResource();
    45         String result = jedis.hget(key, item);
    46         jedis.close();
    47         return result;
    48     }
    49     
    50     @Override
    51     public Long hdel(String key, String item) {
    52         Jedis jedis = jedisPool.getResource();
    53         Long result = jedis.hdel(key, item);
    54         jedis.close();
    55         return result;
    56     }
    57 
    58     @Override
    59     public Long incr(String key) {
    60         Jedis jedis = jedisPool.getResource();
    61         Long result = jedis.incr(key);
    62         jedis.close();
    63         return result;
    64     }
    65 
    66     @Override
    67     public Long decr(String key) {
    68         Jedis jedis = jedisPool.getResource();
    69         Long result = jedis.decr(key);
    70         jedis.close();
    71         return result;
    72     }
    73 
    74     @Override
    75     public Long expire(String key, int second) {
    76         Jedis jedis = jedisPool.getResource();
    77         Long result = jedis.expire(key, second);
    78         jedis.close();
    79         return result;
    80     }
    81 
    82     @Override
    83     public Long ttl(String key) {
    84         Jedis jedis = jedisPool.getResource();
    85         Long result = jedis.ttl(key);
    86         jedis.close();
    87         return result;
    88     }
    89 
    90 }
     1 /**
     2  * 
     3  * @Title: JedisClientCluster.java
     4  * @Package com.lee.rest.component.impl
     5  * @Description: 集群版的jedis客户端操作
     6  * Copyright: Copyright (c) 2016
     7  * Company:Nathan.Lee.Salvatore
     8  * 
     9  * @author leechenxiang
    10  * @date 2016年4月27日 下午4:44:02
    11  * @version V1.0
    12  */
    13 public class JedisClientCluster implements JedisClient {
    14 
    15     @Autowired
    16     private JedisCluster jedisCluster;
    17 
    18     @Override
    19     public String set(String key, String value) {
    20         return jedisCluster.set(key, value);
    21     }
    22 
    23     @Override
    24     public String get(String key) {
    25         return jedisCluster.get(key);
    26     }
    27 
    28     @Override
    29     public Long hset(String key, String item, String value) {
    30         return jedisCluster.hset(key, item, value);
    31     }
    32 
    33     @Override
    34     public String hget(String key, String item) {
    35         return jedisCluster.hget(key, item);
    36     }
    37 
    38     @Override
    39     public Long hdel(String key, String item) {
    40         return jedisCluster.hdel(key, item);
    41     }
    42     
    43     @Override
    44     public Long incr(String key) {
    45         return jedisCluster.incr(key);
    46     }
    47 
    48     @Override
    49     public Long decr(String key) {
    50         return jedisCluster.decr(key);
    51     }
    52 
    53     @Override
    54     public Long expire(String key, int second) {
    55         return jedisCluster.expire(key, second);
    56     }
    57 
    58     @Override
    59     public Long ttl(String key) {
    60         return jedisCluster.ttl(key);
    61     }
    62 
    63 }

    使用地方,一般都是在service中调用,把需要加缓存的地方都实现接口

    取之前查询有没有缓存,有直接返回,没有查数据库,然后再放入缓存

    也有企业会这么做,所有的缓存都有一个团队来管理,做一个定时器,每天凌晨固定一个时间点来跑批,把数据放入缓存

    这么做也是可以的

    我们采取的是第一种

    PS:@Autowired 这边是用的类型相同,有人喜欢用@resource,这样的话就得多写一个,区别点

     1 @Autowired
     2 private JedisClient jedisClient;
     3 
     4 @Value("${REDIS_CONTENT_KEY}")
     5 private String REDIS_CONTENT_KEY;
     6 
     7 @Override
     8 public List<Content> gettList(Long id) {
     9 // TODO 这个地方加缓存和不加缓存,单台或者集群的redis,都要进行压力测试
    10 //添加缓存
    11 //查询数据库之前先查询缓存,如果有直接返回
    12 try {
    13 //从redis中取缓存数据
    14 String json = jedisClient.hget(REDIS_CONTENT_KEY, id + "");
    15 if (!StringUtils.isBlank(json)) {
    16 //把json转换成List
    17 List<Content> list = JsonUtils.jsonToList(json, Content.class);
    18 return list;
    19 }
    20 } catch (Exception e) {
    21 e.printStackTrace();
    22 }
    23 
    24 //执行查询
    25 List<?> list = xxxMapper.select(id);
    26 // 返回结果之前,向缓存中添加数据
    27 try {
    28 // 为了规范key可以使用hash
    29 // 定义一个保存内容的key,hash中每个项就是cid
    30 // value是list,需要把list转换成json数据。
    31 jedisClient.hset(REDIS_CONTENT_KEY, id + "", JsonUtils.objectToJson(list));
    32 } catch (Exception e) {
    33 e.printStackTrace();
    34 }
    35 return list;
    36 }

    那么service就好了,集群版的也通用

    那么集群的配置如何呢?

    放开注释

    使用资源文件的配置

    好了,启动一下就可以运行了

    配置好Test或者controller都可以调用

    但是要做好缓存同步,也就是在增加,修改,删除数据后,要同步缓存,把原有的del,在放入新的

    这样就可以了`~

  • 相关阅读:
    cache 元素 数据类型类(1)
    cache 存储数据访问
    cache类的元素
    COS(cache objectscript)语言及语法cache对象及对象类型
    cache创建数据库
    cache 元素 数据类型类(2)
    usaco1.3.3 Calf Flac 我的题解
    USACO the castle
    Ordered Fractions usaco
    【转】IBM Rational Rose 操作指南(下)
  • 原文地址:https://www.cnblogs.com/leechenxiang/p/5447927.html
Copyright © 2020-2023  润新知