Redis真是好,其中的鍵值用起來真心強大啊有木有, 之前的文章講過搭建了redis集群 那麼咋們該如何調用單機版的redis以及集群版的redis來使用緩存服務呢? 先講講單機版的,單機版redis安裝非常簡單,不多說了,直接使用命令: 1 [root@nginx bin]# ./redis-se ...
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 * @return 秒 42 * >= 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,在放入新的
這樣就可以了`~