Redis 高可用集羣搭建

一、Redis 集羣方案比較

1. 哨兵模式
在這裏插入圖片描述
在redis3.0以前的版本要實現集羣一般是藉助哨兵sentinel工具來監控master節點的狀態,如果master節點異常,則會做主從切換,將某一臺slave作爲master,哨兵的配置略微複雜,並且性能和高可用性等各方面表現一般,特別是在主從切換的瞬間存在訪問瞬斷的情況,而且哨兵模式只有一個主節點對外提供服務,沒法支持很高的併發,且單個主節點內存也不宜設置得過大,否則會導致持久化文件過大,影響數據恢復或主從同步的效率。

2. 高可用集羣模式
在這裏插入圖片描述
redis集羣是一個由多個主從節點羣組成的分佈式服務器羣,它具有複製、高可用和分片特性。Redis集羣不需要 sentinel哨兵也能完成節點移除和故障轉移的功能。需要將每個節點設置成集羣模式,這種集羣模式沒有中心節點,可 水平擴展,據官方文檔稱可以線性擴展到上萬個節點(官方推薦不超過1000個節點)。redis集羣的性能和高可用性均優於之前版本的哨兵模式,且集羣配置非常簡單 。

二、搭建步驟

由於時間和機器的緣故,本文演示的是三主三從的集羣架構,且只有三臺主機,每臺主機上模擬出一主一從。本人使用的Windows操作系統,使用VMWare來虛擬出三臺主機,Centos 7 操作系統,在安裝好第一臺主機後,第二臺和第三臺可以直接克隆第一臺。三臺機器 ip 分別爲:192.168.2.101、192.168.2.102、192.168.2.103。

1.redis 安裝

# 安裝gcc 
yum install gcc

# 本人安裝在 /usr/local/ 目錄下,redis 最新版是6.0.5
cd /usr/local/
wget http://download.redis.io/releases/redis‐5.0.8.tar.gz 
tar xzf redis‐5.0.8.tar.gz 
cd redis‐5.0.8
make

# 啓動並指定配置文件 
 src/redis‐server redis.conf(使用後臺啓動,修改redis.conf裏的daemonize改爲yes)

# 驗證啓動是否成功
ps -ef | grep redis

# 進入redis客戶端 
src/redis-cli -p 6379  (默認6379端口)

# 退出客戶端
quit

2.集羣搭建


 第一步:在第一臺機器的/usr/local下創建文件夾redis‐cluster,然後在其下面分別創建2個文件夾如下 
1)mkdir ‐p /usr/local/redis‐cluster 
2)cd /usr/local/redis‐cluster
3)mkdir 8001 8004

第二步:把redis‐5.0.8/redis.conf 配置文件copy到8001下,修改如下內容: 
1)daemonize yes 
2)port 8001(分別對每個機器的端口號進行設置) 
3)pidfile /var/run/redis_8001.pid
4)logfile "8001.log"
5)dir /usr/local/redis‐cluster/8001/(指定數據文件存放位置,必須要指定不同的目錄位置,不然會丟失數據) 
6)cluster‐enabled yes(啓動集羣模式) 
7)cluster‐config‐file nodes‐8001.conf(集羣節點信息文件,這裏800x好和port對應上) 
8)cluster‐node‐timeout 5000 
9# bind 127.0.0.1(去掉bind綁定訪問ip信息) 
10 protected‐mode no (關閉保護模式) 
11 appendonly yes 

 如果要設置密碼需要增加如下配置: 
12 requirepass 123456 (設置redis訪問密碼) 
13 masterauth 123456 (設置集羣節點間訪問密碼,跟上面一致)

第三步:把修改後的配置文件,copy到8004,修改第235項裏的端口號,可以用批量替換:
:%s/源字符串/目的字符串/g

第四步:另外兩臺機器也需要做上面幾步操作,第二臺機器用80028005,第三臺機器用80038006

第五步:分別啓動6個redis實例,然後檢查是否啓動成功 
1/usr/local/redis-5.0.8/src/redis-server /usr/local/redis-cluster/800*/redis.conf 
2)ps ‐ef | grep redis 查看是否啓動成功

第六步:用redis‐cli創建整個redis集羣(redis5以前的版本集羣是依靠ruby腳本redis‐trib.rb實現) 
# 下面命令裏的1代表爲每個創建的主服務器節點創建一個從服務器節點 
# 執行這條命令需要確認三臺機器之間的redis實例要能相互訪問,可以先簡單把所有機器防火牆關掉,如果不關閉防火牆 則需要打開redis服務端口和集羣節點gossip通信端口 
# 關閉防火牆 
# systemctl stop firewalld      # 臨時關閉防火牆 
# systemctl disable firewalld   # 禁止開機啓動 
1/usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.2.101:8001 192.168.2.102:8002 192.168.2.103:8003 192.168.2.101:8004 192.168.2.102:8005 192.168.2.103:8006

第七步:驗證集羣: 
1)連接任意一個客戶端即可:./redis-cli -c -h -p (‐a訪問服務端密碼,‐c表示集羣模式,指定ip地址和端口號) 
 如:/usr/local/redis-5.0.8/src/redis-cli -a 123456 -h 192.168.2.101 -p 8001 -c (-c 代表以集羣模式連接,可省略)
2)進行驗證: cluster info(查看集羣信息)、cluster nodes(查看節點列表) 
3)進行數據操作驗證 
4)關閉集羣則需要逐個進行關閉,使用命令: 
 /usr/local/redis-5.0.8/src/redis-cli -a 123456 -c -h 192.168.2.102 -p 8002 shutdown
 

創建集羣成功後可看到看到如下信息:
在這裏插入圖片描述
連接客戶端: /usr/local/redis-5.0.8/src/redis-cli -a 123456 -h 192.168.2.101 -p 8001
執行 cluster info 可看到如下信息:
在這裏插入圖片描述
執行 cluster nodes 可看到如下信息:
在這裏插入圖片描述
最前面一串類似uuid的爲節點id,slave節點中間也有這麼一串,代表的是他的master節點id。

三、Spring Boot 項目整合 Redis

  1. 創建 Spring Boot 項目,引入核心依賴:
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
    <dependency>
    	<groupId>org.apache.commons</groupId>
    	<artifactId>commons-pool2</artifactId>
    </dependency>
    
  2. 修改 application.properties 配置:
    spring.redis.timeout=3000
    spring.redis.password=123456
    spring.redis.lettuce.pool.max-active=1000
    spring.redis.lettuce.pool.min-idle=10
    spring.redis.lettuce.pool.max-idle=50
    spring.redis.lettuce.pool.max-wait=1000
    # springboot2.3 以後加上下面配置可自動刷新拓撲,某節點掛掉後,會有新的主從關係,如果不配置,調用接口時程序會報錯
    spring.redis.lettuce.cluster.refresh.adaptive=true
    spring.redis.lettuce.cluster.refresh.period=5000
    # spring.redis.sentinel.master=mymaster
    # spring.redis.sentinel.nodes=192.168.2.101:26379,192.168.2.101:26380,192.168.2.101:26381
    spring.redis.cluster.nodes=192.168.2.101:8001,192.168.2.102:8002,192.168.2.103:8003,192.168.2.101:8004,192.168.2.102:8005,192.168.2.103:8006
    
    
  3. 創建 Controller ,如下:
    /**
     * @author: francis
     * @description:
     * @date: 2020/6/21 21:24
     */
    @RestController
    public class IndexController {
        private final StringRedisTemplate stringRedisTemplate;
    
        public IndexController(StringRedisTemplate stringRedisTemplate) {
            this.stringRedisTemplate = stringRedisTemplate;
        }
    
        @RequestMapping("/test")
        public String test(@RequestParam("key") String key, @RequestParam("value") String value) {
            stringRedisTemplate.opsForValue().set(key, value);
            return stringRedisTemplate.opsForValue().get(key);
        }
    }
    
  4. 運行程序,訪問接口
    在這裏插入圖片描述
  5. 連接 redis 客戶端: /usr/local/redis-5.0.8/src/redis-cli -a 123456 -h 192.168.2.103 -p 8006 ,查看剛剛設置的key-value
    在這裏插入圖片描述

Redis Cluster 將所有數據劃分爲 16384 個 slots(槽位),每個節點負責其中一部分槽位。槽位的信息存儲於每個節點中。

當 Redis Cluster 的客戶端來連接集羣時,它也會得到一份集羣的槽位配置信息並將其緩存在客戶端本地。這樣當客戶端要查找某個 key 時,可以直接定位到目標節點。同時因爲槽位的信息可能會存在客戶端與服務器不一致的情況,還需要糾正機制來實現槽位信息的校驗調整。

槽位定位算法
Cluster 默認會對 key 值使用 crc16 算法進行 hash 得到一個整數值,然後用這個整數值對 16384 進行取模來得到具體槽位。
HASH_SLOT = CRC16(key) mod 16384

四、Redis 集羣相關命令

  1. 幫助命令

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster help
    

    在這裏插入圖片描述

  2. 命令含義

    1.create:創建集羣 host1:port1 ... hostN:portN 
    2.call:可以執行redis命令 
    3.add-node:將一個節點添加到集羣裏,第一個參數爲新節點的ip:port,第二個參數爲集羣中任意一個已經存在的節點的ip:port  
    4.del-node:移除節點 
    5.reshard:重新分片 
    6.check:檢查集羣狀態
    

五、Redis 集羣水平擴展

  1. 查看redis集羣信息,結果如下:
    在這裏插入圖片描述
    目前是三主三從,現在再增加一主一從,在101機器上新增8007和8008節點。

  2. mkdir /usr/local/redis-cluster/8007 mkdir /usr/local/redis-cluster/8008

  3. 分別拷貝 8001 節點目錄下的 redis.conf 至 8007 和 8008 節點目錄下

  4. 修改redis.conf,和前面搭建步驟一樣,批量替換端口號::%s/源字符串/目的字符串/g 來替換端口號

  5. 啓動新增節點: /usr/local/redis-5.0.8/src/redis-server /usr/local/redis-cluster/800*/redis.conf

  6. 查看是否啓動成功: ps -ef | grep redis

  7. 添加8007節點,默認爲主節點:

    # 前面的ip:port爲新增節點,後面的ip:port爲已知存在節點
    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster add-node 192.168.2.101:8007 192.168.2.101:8001
    
    

    在這裏插入圖片描述

  8. 再次查看集羣信息,發現新增master節點8007,但是沒有分配任何的slot(hash槽),
    在這裏插入圖片描述

  9. 爲8007節點分配hash槽

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster reshard 192.168.2.101:8007
    # 執行完這條命令會提示需要輸入幾個參數,具體如下圖
    

    在這裏插入圖片描述

  10. 再次查看節點信息,8007節點分配槽位成功
    在這裏插入圖片描述

  11. 將 8008 添加進集羣

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster add-node 192.168.2.101:8008 192.168.2.101:8001
    
    
  12. 查看集羣信息
    在這裏插入圖片描述

  13. 將 8008 節點配置爲 8007 節點的從節點

    1.  /usr/local/redis-5.0.8/src/redis-cli -a 123456 -h 192.168.2.101 -p 8008
    
    2.  cluster replicate 44a88ac96d18be2db5b962fcca1602af0043ddcf
    

    在這裏插入圖片描述

六、Redis 集羣節點移除

基於第五章節,移除8007和8008節點。

  1. 移除8008節點(移除此節點會將該節點shutdown)

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster del-node 192.168.2.101:8008 6d29ebf9db5e9e5bb0faaacb4bc27bc0732340a7
    
    
  2. 查看集羣信息
    在這裏插入圖片描述

  3. 移除8007節點,8007節點是master節點,需要將數據遷移,所以需要重新分配槽位,否則數據將丟失。示例是將8007節點遷移至8001節點

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster reshard 192.168.2.101:8007
    
    

    在這裏插入圖片描述

  4. 爲確保遷移成功,再次查看集羣信息
    在這裏插入圖片描述

  5. 移除8007節點

    /usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster del-node 192.168.2.101:8007 44a88ac96d18be2db5b962fcca1602af0043ddcf
    
    

    在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章