Redis6搭建集群并在SpringBoot中使用RedisTemplate的實(shí)現(xiàn)
原理
Redis Cluster 一般由多個節(jié)點(diǎn)組成,節(jié)點(diǎn)數(shù)量至少為 6 個才能保證組成完整高可用的集群,其中三個為主節(jié)點(diǎn),三個為從節(jié)點(diǎn)。三個主節(jié)點(diǎn)會分配槽,處理客戶端的命令請求,而從節(jié)點(diǎn)可用在主節(jié)點(diǎn)故障后,頂替主節(jié)點(diǎn)。
如上圖所示,該集群中包含6個Redis節(jié)點(diǎn)3個主服務(wù)器3個從服務(wù)器,分別為M1,M2,M3,S1,S2,S3。除了主從 Redis 節(jié)點(diǎn)之間進(jìn)行數(shù)據(jù)復(fù)制外,所有 Redis 節(jié)點(diǎn)之間采用 Gossip 協(xié)議進(jìn)行通信,交換維護(hù)節(jié)點(diǎn)元數(shù)據(jù)信息。一般來說,主Redis節(jié)點(diǎn)會處理Clients的讀寫操作,而從節(jié)點(diǎn)只處理讀操作。
搭建集群
1.進(jìn)入redis目錄中,打開redis.conf文件,注釋掉bind 127.0.0.1,bind自己服務(wù)器的IP。并將protected -mode yes改為no。daemonize 默認(rèn)是no,需要改成yes,以守護(hù)進(jìn)程運(yùn)行。
2.分別創(chuàng)建6個conf文件對應(yīng)不同的端口號,正常每個節(jié)點(diǎn)對應(yīng)一臺服務(wù)器,為了方便測試本次使用一臺服務(wù)來搭建集群模式。
redis6379.conf
include redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6379.conf
redis6380.conf
include redis.conf pidfile /var/run/redis_6380.pid port 6380 dbfilename dump6380.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6380.conf
redis6381.conf
include redis.conf pidfile /var/run/redis_6381.pid port 6381 dbfilename dump6381.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6381.conf
redis6389.conf
include redis.conf pidfile /var/run/redis_6389.pid port 6389 dbfilename dump6389.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6389.conf
redis6390.conf
include redis.conf pidfile /var/run/redis_6390.pid port 6390 dbfilename dump6390.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6390.conf
redis6391.conf
include redis.conf pidfile /var/run/redis_6391.pid port 6391 dbfilename dump6391.rdb cluster-enabled yes cluster-node-timeout 15000 cluster-config-file nodes-6391.conf
3.進(jìn)入到redis安裝目錄啟動redis服務(wù)(如之前有nodes、rdb、aof文件請先刪除,非則可能會報錯)。
4.進(jìn)入src目錄中執(zhí)行如下命令搭建集群。
redis-cli --cluster create --cluster-replicas 1 IP:6379 IP:6380 IP:6381 IP:6389 IP:6390 IP:6391
5.進(jìn)入其中任意一個節(jié)點(diǎn),執(zhí)行命令查看當(dāng)前節(jié)點(diǎn)狀態(tài)
redis-cli - h ip -p 端口info replication
SpringBoot中使用RedisTemplate
1.pom文件中加入依賴。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2.創(chuàng)建redis配置類.
package com.wzy.demo.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Autowired private RedisTemplate redisTemplate; /** * 解決redis插入中文亂碼 * @return */ @Bean public RedisTemplate redisTemplateInit() { //設(shè)置序列化Key的實(shí)例化對象 redisTemplate.setKeySerializer(new StringRedisSerializer()); //設(shè)置序列化Value的實(shí)例化對象 redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } }
3.創(chuàng)建RedisUtil工具類
package com.wzy.demo.util; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; @Component public class RedisUtil { @Resource private RedisTemplate<String, Object> redisTemplate; public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } //=============================common============================ /** * 指定緩存失效時間 * * @param key 鍵 * @param time 時間(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根據(jù)key 獲取過期時間 * * @param key 鍵 不能為null * @return 時間(秒) 返回0代表為永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判斷key是否存在 * * @param key 鍵 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除緩存 * * @param key 可以傳一個值 或多個 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } //============================String============================= /** * 普通緩存獲取 * * @param key 鍵 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通緩存放入 * * @param key 鍵 * @param value 值 * @return true成功 false失敗 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通緩存放入并設(shè)置時間 * * @param key 鍵 * @param value 值 * @param time 時間(秒) time要大于0 如果time小于等于0 將設(shè)置無限期 * @return true成功 false 失敗 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 遞增 * * @param key 鍵 * @param delta 要增加幾(大于0) * @return */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("遞增因子必須大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 遞減 * * @param key 鍵 * @param delta 要減少幾(小于0) * @return */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("遞減因子必須大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } //================================Map================================= /** * HashGet * * @param key 鍵 不能為null * @param item 項 不能為null * @return 值 */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 獲取hashKey對應(yīng)的所有鍵值 * * @param key 鍵 * @return 對應(yīng)的多個鍵值 */ public Map<Object, Object> hmget(String key) { return redisTemplate.opsForHash().entries(key); } /** * HashSet * * @param key 鍵 * @param map 對應(yīng)多個鍵值 * @return true 成功 false 失敗 */ public boolean hmset(String key, Map<String, Object> map) { try { redisTemplate.opsForHash().putAll(key, map); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * HashSet 并設(shè)置時間 * * @param key 鍵 * @param map 對應(yīng)多個鍵值 * @param time 時間(秒) * @return true成功 false失敗 */ public boolean hmset(String key, Map<String, Object> map, long time) { try { redisTemplate.opsForHash().putAll(key, map); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建 * * @param key 鍵 * @param item 項 * @param value 值 * @return true 成功 false失敗 */ public boolean hset(String key, String item, Object value) { try { redisTemplate.opsForHash().put(key, item, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 向一張hash表中放入數(shù)據(jù),如果不存在將創(chuàng)建 * * @param key 鍵 * @param item 項 * @param value 值 * @param time 時間(秒) 注意:如果已存在的hash表有時間,這里將會替換原有的時間 * @return true 成功 false失敗 */ public boolean hset(String key, String item, Object value, long time) { try { redisTemplate.opsForHash().put(key, item, value); if (time > 0) { expire(key, time); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 刪除hash表中的值 * * @param key 鍵 不能為null * @param item 項 可以使多個 不能為null */ public void hdel(String key, Object... item) { redisTemplate.opsForHash().delete(key, item); } /** * 判斷hash表中是否有該項的值 * * @param key 鍵 不能為null * @param item 項 不能為null * @return true 存在 false不存在 */ public boolean hHasKey(String key, String item) { return redisTemplate.opsForHash().hasKey(key, item); } /** * hash遞增 如果不存在,就會創(chuàng)建一個 并把新增后的值返回 * * @param key 鍵 * @param item 項 * @param by 要增加幾(大于0) * @return */ public double hincr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, by); } /** * hash遞減 * * @param key 鍵 * @param item 項 * @param by 要減少記(小于0) * @return */ public double hdecr(String key, String item, double by) { return redisTemplate.opsForHash().increment(key, item, -by); } //============================set============================= /** * 根據(jù)key獲取Set中的所有值 * * @param key 鍵 * @return */ public Set<Object> sGet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 根據(jù)value從一個set中查詢,是否存在 * * @param key 鍵 * @param value 值 * @return true 存在 false不存在 */ public boolean sHasKey(String key, Object value) { try { return redisTemplate.opsForSet().isMember(key, value); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將數(shù)據(jù)放入set緩存 * * @param key 鍵 * @param values 值 可以是多個 * @return 成功個數(shù) */ public long sSet(String key, Object... values) { try { return redisTemplate.opsForSet().add(key, values); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 將set數(shù)據(jù)放入緩存 * * @param key 鍵 * @param time 時間(秒) * @param values 值 可以是多個 * @return 成功個數(shù) */ public long sSetAndTime(String key, long time, Object... values) { try { Long count = redisTemplate.opsForSet().add(key, values); if (time > 0) expire(key, time); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 獲取set緩存的長度 * * @param key 鍵 * @return */ public long sGetSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 移除值為value的 * * @param key 鍵 * @param values 值 可以是多個 * @return 移除的個數(shù) */ public long setRemove(String key, Object... values) { try { Long count = redisTemplate.opsForSet().remove(key, values); return count; } catch (Exception e) { e.printStackTrace(); return 0; } } //===============================list================================= /** * 獲取list緩存的內(nèi)容 * * @param key 鍵 * @param start 開始 * @param end 結(jié)束 0 到 -1代表所有值 * @return */ public List<Object> lGet(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 獲取list緩存的長度 * * @param key 鍵 * @return */ public long lGetListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { e.printStackTrace(); return 0; } } /** * 通過索引 獲取list中的值 * * @param key 鍵 * @param index 索引 index>=0時, 0 表頭,1 第二個元素,依次類推;index<0時,-1,表尾,-2倒數(shù)第二個元素,依次類推 * @return */ public Object lGetIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { e.printStackTrace(); return null; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @return */ public boolean lSet(String key, Object value) { try { redisTemplate.opsForList().rightPush(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, Object value, long time) { try { redisTemplate.opsForList().rightPush(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @return */ public boolean lSet(String key, List<Object> value) { try { redisTemplate.opsForList().rightPushAll(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 將list放入緩存 * * @param key 鍵 * @param value 值 * @param time 時間(秒) * @return */ public boolean lSet(String key, List<Object> value, long time) { try { redisTemplate.opsForList().rightPushAll(key, value); if (time > 0) expire(key, time); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根據(jù)索引修改list中的某條數(shù)據(jù) * * @param key 鍵 * @param index 索引 * @param value 值 * @return */ public boolean lUpdateIndex(String key, long index, Object value) { try { redisTemplate.opsForList().set(key, index, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 移除N個值為value * * @param key 鍵 * @param count 移除多少個 * @param value 值 * @return 移除的個數(shù) */ public long lRemove(String key, long count, Object value) { try { Long remove = redisTemplate.opsForList().remove(key, count, value); return remove; } catch (Exception e) { e.printStackTrace(); return 0; } } }
4.在controller中測試redis。
@RequestMapping("/testRedis") public String testRedis(Model model) throws Exception{ redisUtil.set("myid","123456"); Object object = redisUtil.get("myid"); model.addAttribute("redisKey",String.valueOf(object)); return "redis.html"; }
5.頁面中顯示redis的返回結(jié)果。
到此這篇關(guān)于Redis6搭建集群并在SpringBoot中使用RedisTemplate的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot使用RedisTemplate內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Redis使用RedisTemplate和StringRedisTemplate
- springboot使用redisTemplate操作lua腳本
- SpringBoot整合Redis使用@Cacheable和RedisTemplate
- springboot使用redisRepository和redistemplate操作redis的過程解析
- 詳解SpringBoot使用RedisTemplate操作Redis的5種數(shù)據(jù)類型
- SpringBoot使用RedisTemplate.delete刪除指定key失敗的解決辦法
- Spring Boot單元測試中使用mockito框架mock掉整個RedisTemplate的示例
- Spring Boot中RedisTemplate的使用示例詳解
相關(guān)文章
Springboot前后端分離項目配置跨域?qū)崿F(xiàn)過程解析
這篇文章主要介紹了Springboot前后端分離項目配置跨域?qū)崿F(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題
這篇文章主要介紹了解決啟用 Spring-Cloud-OpenFeign 配置可刷新項目無法啟動的問題,本文重點(diǎn)給大家介紹Spring-Cloud-OpenFeign的原理及問題解決方法,需要的朋友可以參考下2021-10-10springboot項目攔截器重定向循環(huán)問題的解決
這篇文章主要介紹了springboot項目攔截器重定向循環(huán)問題的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09feign參數(shù)過多導(dǎo)致調(diào)用失敗的解決方案
這篇文章主要介紹了feign參數(shù)過多導(dǎo)致調(diào)用失敗的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例
本文詳細(xì)講解了Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12HttpClient實(shí)現(xiàn)表單提交上傳文件
這篇文章主要為大家詳細(xì)介紹了HttpClient實(shí)現(xiàn)表單提交上傳文件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08