Redis 的四種模式

主從模式

redis主從模式,顧名思義。就是一主一從或一主多從。配置很簡單,只需要在從的配置文件中寫一個參數即可。

slaveof <masterip> <masterport>
# 例如
# slaveof 192.168.1.197 6379

優點:

    配置簡單,使用靈活,數據安全性較高。

缺點:

    無法實現故障切換,當master down後,slave無法自動切換爲主接替後續任務。

哨兵模式

 哨兵模式部署步驟也很簡單,redis.conf的配置文件就不在闡述,跟普通redis配置文件一樣,cp一份就行。

// vim sentinel.conf

# 後臺運行
protected-mode yes  
# 綁定的服務器ip,如果不寫ip默認爲127.0.0.1,只能本地連接
bind 10.10.10.137
# 後臺運行
daemonize yes
# 開啓端口,如果主從都在同一臺機器,記得端口要改一下,別衝突
port 26380
# 需要監控的主的ip地址和端口,後面的1表示有一個哨兵發現master down後,就切換slave爲 master
sentinel monitor mymaster 127.0.0.1 6379 1
# sentinel會向master發送心跳PING來確認master是否存活,如果master在“一定時間範圍”內不迴應PING 或者是回覆了一個錯誤消息,
# 那麼這個sentinel會主觀地(單方面地)認爲這個master已經不可用了(subjectively down, 也簡稱爲SDOWN)。
# 而這個down-after-milliseconds就是用來指定這個“一定時間範圍”的,單位是毫秒。
sentinel down-after-milliseconds mymaster 3000
# failover過期時間。當failover開始後,在此時間內仍然沒有觸發任何failover操作,當前sentinel將會認爲此次failoer失敗。  
sentinel failover-timeout mymaster 1800

分別啓動redis進程和sentinel進程。

./redis-server redis.conf
./redis-server sentinel.conf

高可用集羣分片模式

重要講解redis的官方集羣安裝方式是如何操作的。

需要用到的軟件

redis-4.0.9.tar.gz 下載 (3.0開始支持集羣功能)

ruby-2.5.7.tar.gz 下載 (一般我們選擇2.4或2.5就行,儘量不要用yum安裝,因爲yum安裝的ruby是2.0.0的,gem install redis ruby的版本必須是2.2.2以上)

redis-4.0.0.gem 下載

zlib-1.2.11.tar.gz  自行網上查找

openssl-1.1.1a.tar.gz 自行網上查找

啓動端口:7001 7002 7003 7004 7005 7006

配置文件:/app/redis/redis-cluster

本文當中,我們在一臺Linux上搭建6個節點的Redis集羣(實際生產環境,需要3臺Linux服務器分佈存放3個Master)

使用root用戶安裝,因爲普通用戶沒有創建目錄及編譯權限,需要授權

以下只講述離線安裝步驟

    安裝

第一步:安裝gcc環境

查看gcc版本,如果沒有安裝則需要進行安裝

[root@localhost ~]# gcc -v
使用內建 specs。
目標:x86_64-redhat-linux
配置爲:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
線程模型:posix
gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-23) (GCC)

使用yum命令在線安裝

yum -y install gcc gcc-c++

第二步:解壓redis並編譯安裝

cd /app/redis/
tar -xvf redis-4.0.9.tar.gz
cd redis-4.0.9/
make
/app/redis/redis-4.0.9/src
make install

安裝成功提示

Hint: It’s a good idea to run ‘make test’ ;)
INSTALL install
INSTALL install
INSTALL install
INSTALL install
INSTALL install

redis安裝完之後會在/usr/local/bin目錄下多幾個文件

[root@localhost ~]# ll /usr/local/bin
總用量 35500
-rwxr-xr-x. 1 root root 5600238 5月   6 20:54 redis-benchmark
-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-check-aof
-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-check-rdb
-rwxr-xr-x. 1 root root 5739834 5月   6 20:54 redis-cli
lrwxrwxrwx. 1 root root      12 5月   6 20:54 redis-sentinel -> redis-server
-rwxr-xr-x. 1 root root 8331277 5月   6 20:54 redis-server

第三步:解壓ruby並編譯安裝

cd /app/redis
tar -xvf ruby-2.5.1.tar.gz
cd ruby-2.5.1/
./configure --prefix=/usr/local/ruby  --prefix是將ruby安裝到指定目錄,也可以自定義
make && make install

安裝成功後可以看到在ruby目錄下多了四個目錄

[root@localhost ~]# ll /usr/local/ruby
總用量 16
drwxr-xr-x. 2 root root 4096 10月 10 11:59 bin
drwxr-xr-x. 3 root root 4096 10月 10 11:59 include
drwxr-xr-x. 4 root root 4096 10月 10 11:59 lib
drwxr-xr-x. 5 root root 4096 10月 10 11:59 share

配置ruby環境變量

vi /etc/profile
export PATH=$PATH:/usr/local/ruby/bin
:wq
source /etc/profile

echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/openssh-7.5p1/bin:/root/bin:/usr/local/ruby/bin

查看ruby版本號

[root@localhost ~]# ruby -v
ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-linux]

第四步:創建redis-cluster集羣目錄並拷貝redis的gem包以及在src下將redis-trib.rb 集羣管理工具拷貝到集羣目錄

cd /app/redis
mkdir redis-cluster
cp redis-4.0.0.gem redis-cluster/
/app/redis/redis-4.0.9/src
cp redis-trib.rb /app/redis/redis-cluster/

第五步:使用gem安裝redis的gem包

cd /app/redis/redis-cluster
gem install redis-4.0.0.gem

如果安裝沒有任何問題會出現以下提示

Successfully installed redis-4.0.0
Parsing documentation for redis-4.0.0
Installing ri documentation for redis-4.0.0
Done installing documentation for redis after 1 seconds
1 gem installed

如在第五步報錯需要zlib或者openssl

    解決zlib報錯問題

cd /app/redis/ruby-2.5.1/ext/zlib
ruby extconf.rb    --成功會出現creating Makefile
creating Makefile    --如果沒有出現creating Makefile,執行下面的命令
ruby extconf.rb --with-zlib-dir=/usr/local/zlib/
vi Makefile
將     zlib.o: $(top_srcdir)/include/ruby.h
修改爲 zlib.o: ../../include/ruby.h
make
# 成功顯示
linking shared-object zlib.so
make install
# 成功顯示
/usr/bin/install -c -m 0755 zlib.so /usr/local/ruby/lib/ruby/site_ruby/2.5.0/x86_64-linux
如果上面再執行make之前不修改Makefile,將會報下面的錯誤
make: * No rule to make target /include/ruby.h', needed byzlib.o’. Stop.

解決openssl報錯問題

首先要安裝openssl,如果系統安裝了,本步驟可以省略

cd /app/redis
tar -zxvf openssl-1.1.1a.tar.gz
./config --prefix=/usr/local/openssl && make && make install

安裝完成後繼續解決openssl報錯問題

cd /app/redis/ruby-2.5.1/ext/openssl
ruby extconf.rb    --成功會出現creating Makefile

如發現沒有出現creating Makefile,請執行下面命令

vi Makefile
將所有的$(top_srcdir)修改爲 ../..$(top_srcdir)  # 注意(top_srcdir)不止有一個,所有的都要改
make
# 成功安裝輸出
linking shared-object openssl.so
make install
# 成功安裝輸出
/usr/bin/install -c -m 0755 openssl.so /usr/local/ruby/lib/ruby/site_ruby/2.5.0/x86_64-linux
installing default openssl libraries
如果上面再執行make之前不修改Makefile,將會報下面的錯誤
make: * No rule to make target /include/ruby.h', needed byossl.o’. Stop.

再次使用gem安裝redis的gem包

# 不出意外可以順利安裝 
cd /app/redis/redis-cluster
gem install redis-4.0.0.gem

四.創建集羣

之前講到是我們需要6個節點的Redis作爲集羣,所以我們需要創建6個文件夾,分別存放6個節點的配置信息,6個節點需要對應6個端口號,比如7001~7006,這個端口號我們可以自行定義。

/app/redis/redis-cluster/
mkdir 700{1,2,3,4,5,6}    --批量創建六個文件夾

將原先redis安裝目錄下的配置文件redis.conf拷貝到新創建的六個文件夾下面

cd /app/redis/redis-4.0.9
cp redis.conf /app/redis/redis-cluster/7001/
cp redis.conf /app/redis/redis-cluster/7002/
cp redis.conf /app/redis/redis-cluster/7003/
cp redis.conf /app/redis/redis-cluster/7004/
cp redis.conf /app/redis/redis-cluster/7005/
cp redis.conf /app/redis/redis-cluster/7006/

將redis安裝之後生成的服務端與客戶端拷貝到新創建的六個文件夾下面

cd /usr/local/bin/
cp redis-server redis-cli /app/redis/redis-cluster/7001/
cp redis-server redis-cli /app/redis/redis-cluster/7002/
cp redis-server redis-cli /app/redis/redis-cluster/7003/
cp redis-server redis-cli /app/redis/redis-cluster/7004/
cp redis-server redis-cli /app/redis/redis-cluster/7005/
cp redis-server redis-cli /app/redis/redis-cluster/7006/

修改新創建的六個文件夾下面的配置文件redis.conf的部分參數

cd /app/redis/redis-cluster/
修改7001-7006中的redis.conf
bind 192.168.5.104    連入主機的ip地址,不修改外部無法連入你的redis緩存服務器中
port 700X    x爲文件夾名稱,你在700幾就填幾
daemonize yes    開啓守護進程模式。在該模式下,redis會在後臺運行,並將進程pid號寫入至redis.conf選項pidfile設置的文件中,此時redis將一直運行,除非手動kill該進程。
pidfile /app/redis/redis-cluster/700x/redis_700x.pid    x爲文件夾名稱,你在700幾就填幾
cluster-enabled yes    開啓集羣模式

cd /app/redis/redis-cluster

寫個批處理 vim start-all.sh,如果vim不支持就用vi

vim start-all.sh

cd 7001
  ./redis-server redis.conf
cd ..
cd 7002
  ./redis-server redis.conf
cd ..
cd 7003
  ./redis-server redis.conf
cd ..
cd 7004
  ./redis-server redis.conf
cd ..
cd 7005
  ./redis-server redis.conf
cd ..
cd 7006
  ./redis-server redis.conf
cd ..
並執行 chmod +x start-all.sh 命令進行授權

啓動實例之前在根路徑下配置多種環境

yum -y install gcc gcc-c++

啓動集羣實例

./start-all.sh
[root@localhost redis]# ps -ef|grep redis
root     14253     1  0 Oct14 ?        00:03:27 ./redis-server 192.168.5.104:7001 [cluster]
root     14262     1  0 Oct14 ?        00:03:38 ./redis-server 192.168.5.104:7006 [cluster]
root     18571 13962  0 15:37 pts/0    00:00:00 grep redis
root     30364     1  0 Oct10 ?        00:15:55 ./redis-server 192.168.5.104:7002 [cluster]
root     30372     1  0 Oct10 ?        00:15:51 ./redis-server 192.168.5.104:7003 [cluster]
root     30374     1  0 Oct10 ?        00:15:31 ./redis-server 192.168.5.104:7004 [cluster]
root     30379     1  0 Oct10 ?        00:15:17 ./redis-server 192.168.5.104:7005 [cluster]

配置集羣

cd /app/redis/redis-cluster
# 創建了三個主節點,三個從節點。其中—replicas1 表示每個主節點下面有1個從節點,從節點可以是任意多個。
./redis-trib.rb create --replicas 1 192.168.4.212:7001 192.168.4.212:7002 192.168.4.212:7003 192.168.4.212:7004 192.168.4.212:7005 192.168.4.212:7006
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.5.104:7001    --主節點
192.168.5.104:7002    --主節點
192.168.5.104:7003    --主節點
Adding replica 192.168.5.104:7005 to 192.168.5.104:7001    -主節點對應的從節點
Adding replica 192.168.5.104:7006 to 192.168.5.104:7002    -主節點對應的從節點
Adding replica 192.168.5.104:7004 to 192.168.5.104:7003    -主節點對應的從節點
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589 192.168.5.104:7001
   slots:0-5460 (5461 slots) master                        --主節點分配的hash槽
M: 3d48e5f1dbb2640d96b4522ece9b8be430bca721 192.168.5.104:7002
   slots:5461-10922 (5462 slots) master                    --主節點分配的hash槽
M: dfa039f4cb9fed60b44e223a7afa462e34f904f7 192.168.5.104:7003
   slots:10923-16383 (5461 slots) master                    --主節點分配的hash槽
S: 4027313648b8615cec31b2b5c51e25bfc02ade59 192.168.5.104:7004
   replicates 3d48e5f1dbb2640d96b4522ece9b8be430bca721      --從節點沒有hash槽
S: 57331ee1000d4ea652c7eda84b472a38bcd2e21d 192.168.5.104:7005
   replicates dfa039f4cb9fed60b44e223a7afa462e34f904f7      --從節點沒有hash槽
S: 8ca8eeba19b0acba4fd6f1e9f7be3c4bdb5ea1e5 192.168.5.104:7006
   replicates ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589      --從節點沒有hash槽
Can I set the above configuration? (type 'yes' to accept): yes   --選擇yes, 意思是服從這種主從分配方式,我們也可以通過配置文件自己指定slave
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join....
>>> Performing Cluster Check (using node 192.168.5.104:7001)        --以下是詳細的主從節點分佈
M: ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589 192.168.5.104:7001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 4027313648b8615cec31b2b5c51e25bfc02ade59 192.168.5.104:7004
   slots: (0 slots) slave
   replicates 3d48e5f1dbb2640d96b4522ece9b8be430bca721
S: 8ca8eeba19b0acba4fd6f1e9f7be3c4bdb5ea1e5 192.168.5.104:7006
   slots: (0 slots) slave
   replicates ee942ff5cf8cd0efddcf25b0ff21b5bc1c259589
M: 3d48e5f1dbb2640d96b4522ece9b8be430bca721 192.168.5.104:7002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
M: dfa039f4cb9fed60b44e223a7afa462e34f904f7 192.168.5.104:7003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 57331ee1000d4ea652c7eda84b472a38bcd2e21d 192.168.5.104:7005
   slots: (0 slots) slave
   replicates dfa039f4cb9fed60b44e223a7afa462e34f904f7
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered

五.集羣測試

    測試主從高可用

    停止7001(master),登錄到7001的從上,查看發現狀態爲master,使用命令 info Replication

cd /app/redis/redis-cluster/7001
./redis-cli -c -h 192.168.5.104 -p 7001
./redis-cli -c -h 192.168.5.104 -p 7001 shutdown //關閉7001節點,如果沒有-h參數,默認連接127.0.0.1,如果沒有-p參數,默認連接6379端口(所有如果用默認的,就沒有-h -p)
說明:-h+host  -p+端口號  -c是要連接集羣,注意坑,不加會報錯的

當主master down後,重新上線後,原先的slave依舊是master,原先的master由原先的master變爲slave了(親測)

    測試集羣的分片性

    通過java代碼對3對redis進行循環寫入,查看3個master上的是否都有數據(親測所有master都有數據)

    下面列出java連接redis的代碼

/*******************集羣模式***********************/
  JedisPoolConfig poolConfig = new JedisPoolConfig();
     // 最大連接數
     poolConfig.setMaxTotal(50);
     // 最大空閒數
     poolConfig.setMaxIdle(10);
     // 最大允許等待時間,如果超過這個時間還未獲取到連接,則會報JedisException異常:
     // Could not get a resource from the pool
     poolConfig.setMaxWaitMillis(1000);
     Set<HostAndPort> nodes = new LinkedHashSet<HostAndPort>();
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7001")));
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7002")));
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7003")));
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7004")));
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7005")));
     nodes.add(new HostAndPort("192.168.5.104",  Integer.parseInt("7006")));
     @SuppressWarnings("resource")
  JedisCluster cluster = new JedisCluster(nodes, poolConfig);
     for(int i=0;i<1000;i++){
   try {
   Thread.sleep(500);
   System.out.println(i+"-------"+cluster.set("wc_"+i, "xinxin"+i));
   }catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    continue;
   }
  }

 

 

 

 

 

發佈了26 篇原創文章 · 獲贊 24 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章