因爲內存大小的限制,使用一臺 Redis 實例顯然沒法知足需求,這時就須要使用多臺 Redis做爲緩存數據庫。可是如何保證數據存儲的一致性呢,這時就須要搭建redis集羣.採用合理的機制,保證用戶的正常的訪問需求.node
採用redis集羣,能夠保證數據分散存儲,同時保證數據存儲的一致性.而且在內部實現高可用的機制.實現了服務故障的自動遷移.redis
主從劃分: 3臺主機 3臺從機共6臺 端口劃分7000-7005算法
通用的概念(不適用redis集羣)spring
一般狀況下,集羣(哨兵)的數量都是奇數臺(包含主從)數據庫
集羣(哨兵)正常工做的條件 存活的服務器數量 > 總數N/2vim
1臺 不能搭建集羣緩存
2臺 不能搭建集羣服務器
3臺 2 > 1.5 搭建集羣最小單位3臺 最多宕機1臺函數
4臺 3 > 2 也能夠搭建集羣 最多宕機1臺優化
因此集羣的數量通常都是奇數臺
1.準備集羣文件夾 Mkdir cluster
2.在cluster文件夾中分別建立7000-7005文件夾
3.複製配置文件
將redis根目錄中的redis.conf文件複製到cluster/7000/ 並以原名保存 cp redis.conf cluster/7000
4.編輯配置文件
1)註釋本地綁定IP地址
2)關閉保護模式
3)修改端口號
4)啓動後臺啓動
5)修改pid文件
6)修改持久化文件路徑
7)設定內存優化策略
8)關閉AOF模式
9)開啓集羣配置
10)開啓集羣配置文件
11)修改集羣超時時間
2.複製修改後的配置文件
將7000文件夾下的redis.conf文件分別複製到7001-7005中
3.批量修改
分別將7001-7005文件中的7000改成對應的端口號的名稱
4. 經過腳本編輯啓動/關閉指令
1)建立啓動腳本 vim start.sh
2)編輯關閉的腳本 vim shutdown.sh
5.啓動redis節點 sh start.sh
6.建立redis集羣
#5.0版本執行 使用C語言內部管理集羣
redis-cli --cluster create --cluster-replicas 1 192.168.21.129.130:7000 192.168.35.130:7001 192.168.21.129:7002 192.168.21.129:7003 192.168.21.129:7004 192.168.21.129:7005
Redis的全部節點都會保存當前redis集羣中的所有主從狀態信息.而且每一個節點都可以相互通訊.當一個節點發生宕機現象.則集羣中的其餘節點經過PING-PONG檢測機制檢查Redis節點是否宕機.當有半數以上的節點認爲宕機.則認爲主節點宕機.同時由Redis剩餘的主節點進入選舉機制.投票選舉連接宕機的主節點的從機.實現故障遷移.
集羣中若是主機宕機,那麼從機能夠繼續提供服務,
當主機中沒有從機時,則向其它主機借用多餘的從機.繼續提供服務.若是主機宕機時沒有從機可用,則集羣崩潰.
.例如:9個redis節點,節點宕機5-7次時集羣才崩潰.
RedisCluster採用此分區,全部的鍵根據哈希函數(CRC16[key]&16383)映射到0-16384槽內,共16384個槽位,每一個節點維護部分槽及槽所映射的鍵值數據.根據主節點的個數,均衡劃分區間.
算法:哈希函數: Hash()=CRC16[key]&16383按位與
當向redis集羣中插入數據時,首先將key進行計算.以後將計算結果匹配到具體的某一個槽的區間內,以後再將數據set到管理該槽的節點中。
效率高:
分片效率高: 發生在服務器中 redis只負責存取
Redis集羣: 發生在redis內部 效率低
spring整合redis
1.編輯properties文件
#redis集羣配置
redis.nodes=192.168.21.129:7000,192.168.21.129:7001,192.168.21.129:7002,192.168.21.129:7003,192.168.21.129:7004,192.168.21.129:7005
@Configuration // 標識配置類 @PropertySource("classpath:/properties/redis.properties") public class RedisConfig { @Value("${redis.nodes}") private String redisNodes; //node,node,node //將Set集合交給容器管理 @Bean("redisSet") public Set<HostAndPort> redisSet(){ Set<HostAndPort> redisSet = new HashSet<HostAndPort>(); String[] arrayNodes = redisNodes.split(","); for (String node : arrayNodes) { //ip:port String host = node.split(":")[0]; int port = Integer.parseInt(node.split(":")[1]); HostAndPort hostAndPort = new HostAndPort(host, port); redisSet.add(hostAndPort); } return redisSet; } @Bean @Scope("prototype") public JedisCluster jedisCluster(@Qualifier("redisSet")Set<HostAndPort> redisSet) { return new JedisCluster(redisSet); } }
3.編輯切面
@Component //將類交給容器管理 @Aspect //標識切面 public class CacheAspect { @Autowired private JedisCluster jedis;
//若是是環繞通知,則參數必須寫ProceedingJoinPoint,必須位於第一位 @Around("@annotation(cacheFind)")
............