實現Redis Cluster並實現Python鏈接集群

来源:https://www.cnblogs.com/theboy/archive/2019/04/14/10690838.html
-Advertisement-
Play Games

[TOC] 一、Redis Cluster簡單介紹 搭建的方式有多種,例如使用Redis主從複製+Sentinel高可用集群、zookeeper等,但從 之後版本支持Redis cluster集群, "Redis Cluster" 採用無中心結構,每個節點保存數據和整個集群狀態,每個節點都和其他所有 ...


目錄

一、Redis Cluster簡單介紹

Redis集群搭建的方式有多種,例如使用Redis主從複製+Sentinel高可用集群、zookeeper等,但從Redis 3.0之後版本支持Redis-cluster集群,Redis-Cluster採用無中心結構,每個節點保存數據和整個集群狀態,每個節點都和其他所有節點連接。

其Redis-cluster結構圖如下:

Redis Cluster集群的運行機制:

  • 所有的Redis節點彼此互聯(PING-PONG機制),內部使用二進位協議優化傳輸速度和帶寬。
  • 節點的Failover是通過集群中超過半數的節點檢測失效時才生效。
  • 客戶端與Redis節點直連,不需要中間Proxy層。客戶端不需要連接集群所有節點,連接集群中任何一個可用節點即可(預設slave從節點只提供備份)。
  • Redis-cluster把所有的物理節點映射到[0-16383]Slot上(不一定是平均分配),Cluster 負責維護node<->slot<->value。
  • Redis集群預分好16384個桶,當需要在 Redis 集群中放置一個 key-value 時,根據 CRC16(key) mod 16384的值,決定將一個key放到哪個槽中。

二、背景

為了保證Redis集群的高可用性,即使使用Sentinel哨兵實現Failover自動切換,Redis每個實例也是全量存儲,每個Redis存儲的內容都是完整的數據,比較浪費記憶體。為了最大化利用記憶體,可以採用數據分片的形式,保存到不同的Redis實例上,這就是分散式存儲。即每台redis存儲不同的內容,Redis Cluster集群架構正是滿足這種分散式存儲要求的一種體現。

Redis Cluster集群提供了以下兩個好處:

  1. 將數據自動切分(split)到多個節點的能力。
  2. 當集群中的一部分節點失效或者無法進行通訊時, 仍然可以繼續處理命令請求的能力。

三、環境準備

3.1 主機環境

[root@cache06 ~]# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
[root@cache06 ~]# uname -m
x86_64

3.2 主機規劃

每台主機安裝兩個Redis實例,一主、一從。

其緩存架構圖如下:

四、部署Redis

4.1 安裝Redis軟體

#下載redis
[root@cache06 server]# cd /server/tools && wget http://download.redis.io/releases/redis-3.2.12.tar.gz
#解壓併進入src目錄
[root@cache06 server]# tar xf redis-3.2.12.tar.gz && cd redis-3.2.12
#編譯軟體,參數MALLOC=jemalloc,2.4.4以上版本預設的記憶體分配器(可省略)
[root@cache06 redis-3.2.12]# make
#將軟體安裝到指定目錄下
[root@cache06 redis-3.2.12]# make PREFIX=/application/redis-3.2.12 install
#創建軟鏈接
[root@cache06 redis-3.2.12]# ln -s /application/redis-3.2.12 /application/redis
#修改PATH環境變數並使其生效
[root@cache06 redis]# echo 'PATH=/application/redis/bin:$PATH'>>/etc/profile && source /etc/profile
#檢查安裝結果
[root@cache06 redis]# ll bin
-rwxr-xr-x 1 root root 2432992 Apr 10 13:34 redis-benchmark
-rwxr-xr-x 1 root root   25176 Apr 10 13:34 redis-check-aof
-rwxr-xr-x 1 root root 5192440 Apr 10 13:34 redis-check-rdb
-rwxr-xr-x 1 root root 2586080 Apr 10 13:34 redis-cli
lrwxrwxrwx 1 root root      12 Apr 10 13:34 redis-sentinel -> redis-server
-rwxr-xr-x 1 root root 5192440 Apr 10 13:34 redis-server 

命令解釋:

  • redis-server:Redis 服務端的啟動程式 。
  • redis-cli:Redis客戶端程式,也可以用 telnet 根據其純文本協議來操作Redis緩存。
  • redis-benchmark:Redis 性能測試工具,測試 Redis 在當前系統下的讀寫性能。
  • redis-check-aof:數據修複。
  • redis-check-dump:檢查導出工具。

4.2 編輯Redis配置文件

[root@cache06 redis]# mkdir /application/redis/conf
[root@cache06 redis]# cp /server/tools/redis-3.2.12/redis.conf ./conf/
[root@cache06 redis]# cd conf 
[root@cache06 redis]# vim redis.conf
#是否後臺運行
daemonize yes
#預設埠
port 6379
#日誌文件位置
logfile /var/log/redis.log
#持久化文件存儲位置
dir /data/6379
#RDB持久化數據文件
dbfilename dump.rdb

4.3 啟動Redis服務

4.3.1 啟動前優化記憶體分配策略

有三種方法進行修改,但是需要root許可權:

  1. sysctl vm.overcommit_memory=1
  2. echo 'vm.overcommit_memory=1' >>/etc/sysctl.conf && sysctl -p
  3. echo 1 >/proc/sys/vm/overcommit_memory

Overcommit_Memory參數可選值含義:

  • 0 表示內核將檢查是否有足夠的可用記憶體供應用進程使用;如果有足夠的可用記憶體,記憶體申請允許;否則,記憶體申請失敗,並把錯誤返回給應用進程。
  • 1 表示內核允許分配所有的物理記憶體,而不管當前的記憶體狀態如何。
  • 2 表示內核允許分配超過所有物理記憶體和交換空間總和的記憶體。

4.3.2 啟動redis-server

#啟動服務
[root@cache06 redis]# redis-server /application/redis/conf/redis.conf &
#追加啟動命令到/etc/rc.local文件中
echo -e '#start redis-server\nredis-server /application/redis/conf/redis.conf &' >>/etc/rc.local
#添加執行許可權
[root@cache06 ~]# chmod +x /etc/rc.d/rc.local

4.3.3 檢查服務

#預設埠6379
[root@cache06 redis]# lsof -i :6379
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 10835 root    4u  IPv4  26242      0t0  TCP localhost:6379 (LISTEN)

4.3.4 客戶端連接測試

#互動式簡單存取數據
[root@cache06 redis]# redis-cli
127.0.0.1:6379> set name oldboy
OK
127.0.0.1:6379> get name
"oldboy"
#非互動式簡單存取數據:類似mysql -e參數
[root@cache06 redis]# redis-cli set name oldboy
OK
[root@cache06 redis]# redis-cli get name
"oldboy"
#刪除數據
[root@cache06 redis]# redis-cli del name

註:也可以通過telnet命令實現redis互動式存取數據,類似操作memcached緩存。

五、構建Redis Cluster集群

Redis Cluster集群正常工作至少需要3個主節點,同時為了保證數據的高可用性,加入了主從模式。因此至少創建6個節點,一個主節點對應一個或多個從節點,主節點提供數據存取,從節點預設情況下只負責從Master拉取數據進行備份。當這個主節點掛掉後,集群就會通過下線檢測的方式,由從節點中選舉一個節點來充當主節點,實現故障轉移,從而保證集群正常運行。

5.1 Redis主從複製原理

Redis-Cluster集群的複製特性重用了 SLAVEOF 命令的代碼,所以集群節點的複製行為和 SLAVEOF 命令的複製行為完全相同。
Redis全量複製一般在Slave初始化階段執行,通過SLAVEOF命令開啟主從複製,此時Slave需要將Master上的所有數據都複製一份。
具體步驟如下:

  1. 從伺服器連接主伺服器,發送SYNC命令;
  2. 主伺服器接收到SYNC命令後,開始執行BGSAVE命令生成RDB文件,並使用緩衝區記錄此後執行的所有寫命令;
  3. 主伺服器BGSAVE執行完後,向所有從伺服器發送快照文件,併在發送期間繼續記錄被執行的寫命令;
  4. 從伺服器收到快照文件後丟棄舊的數據,載入新的快照;
  5. 主伺服器快照發送完畢後,開始向從伺服器發送緩衝區中的寫命令;
  6. 從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;

複製時序圖

5.2 創建Redis多實例

規劃三台虛擬主機,每台虛擬主機分別搭建一臺master主節點和一臺slave從節點。並將一個分片的兩個節點,分到不同的主機上,防止主機宕機造成整個分片數據丟失。
其主機規劃如下:

  • 172.16.1.54
    主節點:172.16.1.54:6378
    從節點:172.16.1.54:6379
  • 172.16.1.57
    主節點:172.16.1.57:6378
    從節點:172.16.1.57:6379
  • 172.16.1.56
    主節點:172.16.1.56:6378
    從節點:172.16.1.56:6379

5.2.1 創建存放多個實例的目錄

#以單台主機為例,創建存放多個實例的目錄
[root@cache06 ~]# mkdir -p /data/{6378,6379}

5.2.2 配置redis.conf文件

#配置6378實例
[root@cache06 ~]# cd /data/6378
#編輯redis實例配置文件
[root@cache06 6378]# vim redis.conf
port 6378
daemonize yes
pidfile /data/6378/redis.pid
logfile /data/6378/redis.log
loglevel notice
dir /data/6378
dbfilename dump.rdb
#禁用保護模式(避免影響主從複製)
protected-mode no
#開啟cluster模式
cluster-enabled yes
#記錄集群信息,cluster集群自動維護,不用手動更新、創建
cluster-config-file nodes.conf
#節點超時時間,目標節點超過指定時間沒響應,就標記為FAIL或PFAIL(可能宕機)
cluster-node-timeout 5000
appendonly yes

#配置6379實例
[root@cache06 6378]# cd /data/6379
#拷貝redis.conf配置文件
[root@cache06 6379]# cp /data/{6378,6379}/redis.conf
#埠替換
[root@cache06 6379]# sed -i 's#6378#6379#g' redis.conf
#檢查替換是否成功
[root@cache06 6379]# grep '6379' redis.conf 
port 6379
pidfile /data/6379/redis.pid
logfile /data/6379/redis.log
dir /data/6379

5.2.3 啟動實例

#啟動Redis實例
[root@cache06 data]# redis-server /data/6378/redis.conf 
[root@cache06 data]# redis-server /data/6379/redis.conf 
#查看進程是否存在
[root@cache06 data]# ps -ef|grep [r]edis
root       2350      1  0 11:07 ?        00:00:01 redis-server *:6378 [cluster]
root       2399      1  0 11:21 ?        00:00:00 redis-server *:6379 [cluster]

之後根據主機規劃,按照以上步驟創建其他Redis實例。

5.3 創建Redis Cluster集群

5.3.1 安裝redis-trib.rb需要的依賴環境

#安裝Epel源
[root@cache06 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
#安裝Ruby環境
[root@cache06 ~]# yum install ruby rubygems -y
#使用國內源
[root@cache06 ~]# gem sources --add http://mirrors.aliyun.com/rubygems/ --remove https://rubygems.org/
#檢查源
[root@cache06 ~]# gem sources -l
*** CURRENT SOURCES ***

http://mirrors.aliyun.com/rubygems/
#安裝依賴軟體
[root@cache06 ~]# gem install redis -v 3.3.3

5.3.2 創建集群

1)創建一個包含三個主節點和三個從節點的集群

#複製redis-trib.rb到/application/redis/bin目錄
[root@cache06 ~]# cp /server/tools/redis-3.2.12/src/redis-trib.rb /application/redis/bin
#創建集群
[root@cache06 ~]# redis-trib.rb create --replicas 1 172.16.1.54:6378 172.16.1.54:6379 172.16.1.57:6378 \
172.16.1.57:6379 172.16.1.56:6378 172.16.1.56:6379

命令參數的含義:

  • 選項 create 表示希望創建一個新的集群。
  • 選項 --replicas 1 表示希望集群中的每個主節點創建一個從節點。
  • 之後跟著的多個host:port參數,則是實例的地址列表,希望程式使用這些地址所指示的實例來創建新集群。

ERROR錯誤提示:如果集群節點少於6個,使用redis-trib.rb創建集群會提示如下信息

>>> Creating cluster
ERROR: Invalid configuration for cluster creation.
Redis Cluster requires at least 3 master nodes.
This is not possible with 4 nodes and 1 replicas per node.
At least 6 nodes are required.

2)redis-trib 會列印出一份預想中的配置,如果沒問題就可以輸入 yes ,redis-trib 就會將這份配置應用到集群當中

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.16.1.54:6378
172.16.1.57:6378
172.16.1.56:6378
Adding replica 172.16.1.57:6379 to 172.16.1.54:6378
Adding replica 172.16.1.54:6379 to 172.16.1.57:6378
Adding replica 172.16.1.56:6379 to 172.16.1.56:6378
M: a560974d9721882574aaf7fa4cf7218f590e97e0 172.16.1.54:6378
   slots:0-5460 (5461 slots) master
S: 4b462992200244a66c63f085ffd7ef4983a9655b 172.16.1.54:6379
   replicates f2d4d17676e6166bcdc2d05d81fc891327d03319
M: f2d4d17676e6166bcdc2d05d81fc891327d03319 172.16.1.57:6378
   slots:5461-10922 (5462 slots) master
S: 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.57:6379
   replicates a560974d9721882574aaf7fa4cf7218f590e97e0
M: ca2a21eb3b5679c61b186ca4ca661f93e11ec304 172.16.1.56:6378
   slots:10923-16383 (5461 slots) master
S: 78e4b73c8f5f57d55303db52e9774ba69a306bb2 172.16.1.56:6379
   replicates ca2a21eb3b5679c61b186ca4ca661f93e11ec304
Can I set the above configuration? (type 'yes' to accept):

3)輸入yes並回車確認之後,集群將會配置應用到各個節點, 並連接各個節點,讓節點之間開始互相通訊

Can I set the above configuration? (type 'yes' to accept): yes
>>> 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 172.16.1.54:6378)
M: a560974d9721882574aaf7fa4cf7218f590e97e0 172.16.1.54:6378
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: f2d4d17676e6166bcdc2d05d81fc891327d03319 172.16.1.57:6378
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.57:6379
   slots: (0 slots) slave
   replicates a560974d9721882574aaf7fa4cf7218f590e97e0
S: 4b462992200244a66c63f085ffd7ef4983a9655b 172.16.1.54:6379
   slots: (0 slots) slave
   replicates f2d4d17676e6166bcdc2d05d81fc891327d03319
S: 78e4b73c8f5f57d55303db52e9774ba69a306bb2 172.16.1.56:6379
   slots: (0 slots) slave
   replicates ca2a21eb3b5679c61b186ca4ca661f93e11ec304
M: ca2a21eb3b5679c61b186ca4ca661f93e11ec304 172.16.1.56:6378
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)

4)創建成功則輸出如下信息

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

5.3.3 測試集群

#連接任一節點進行數據管理
[root@cache06 ~]# redis-cli -c -p 6378
172.16.1.56:6378> set msg 'oldboy'
-> Redirected to slot [6257] located at 172.16.1.57:6378
OK
172.16.1.57:6378> get msg
"oldboy"

模擬測試:實現熱點數據緩存

1)創建學生表,並插入數據

#登錄資料庫
[root@db01 ~]# mysql -uroot -p123456

#創建stu學生表
mysql> create table stu(
 -> sid smallint(8) unsigned zerofill not null auto_increment comment 'sid',
 -> sname varchar(20) not null default '' comment 'sname',
 -> address varchar(20) not null default '' comment 'address',
 -> primary key(sid)
 -> )character set utf8 engine innodb;
 
#插入數據
mysql> use test;
mysql> insert into stu values(null,'張三豐','湖南長沙'),(null,'張無忌','河南洛陽'),(null,'段譽','北京市'),(null,' 喬峰','廣州市'),(null,'沈浪','上海市');

#查詢數據
mysql> select * from stu;
+----------+-------+----------+
|    sid   | sname | address  |
+----------+-------+----------+
| 00000001 | 張三豐 | 湖南長沙  |
| 00000002 | 張無忌 | 河南洛陽  |
| 00000003 | 段譽   | 北京市   |
| 00000004 | 喬峰   | 廣州市   |
| 00000005 | 沈浪   | 上海市   |
+----------+---- ---+---------+

2)將stu表中數據導入到redis資料庫中

[root@cache06 scripts]# vim hmset_data.sh
#!/bin/bash
IP=172.16.1.51
script='/server/scripts'
if [ ! -d $script ];then
    mkdir -p $script
fi

#從資料庫獲取學生表信息,編輯成redis-cli命令
#redis-cli -c -p 6378 hmset stu_00000001 sid 00000001 sname 張三豐 address 湖南長沙
cd $script && \
/usr/bin/ssh $IP "mysql -uroot -p123456 -e 'select concat(\"hmset stu_\",sid,\" sid \",sid,\" sname \",sname,\" address \",address) from test.stu;'"|grep -v '^concat'|awk '{print "redis-cli -c -p 6378",$0}' >db.cmd

#判斷上一條命令執行是否成功
if [ $? -ne 0 ];then
    echo 'USAGE: Please check the Data or IP.'
    exit 1
fi

#執行命令,並將結果寫入到緩存中
cat db.cmd|while read line
do
    $line
done

3)檢查緩存結果

#查看集群信息
[root@cache06 scripts]# redis-trib.rb info 127.0.0.1:6378
127.0.0.1:6378 (ca2a21eb...) -> 2 keys | 5461 slots | 1 slaves.
172.16.1.57:6378 (f2d4d176...) -> 4 keys | 5462 slots | 1 slaves.
172.16.1.54:6378 (a560974d...) -> 4 keys | 5461 slots | 1 slaves.
[OK] 10 keys in 3 masters.
0.00 keys per slot on average.

#獲取鍵值信息,在redis中存儲中文,讀取數據時會遇到字元集的問題
[root@cache06 scripts]# redis-cli -c -p 6378 hget stu_00000009 sname
"\xe6\xb1\xaa\xe6\xb6\xb5"

#在redis-cli後面加--raw參數,顯示中文
[root@cache06 scripts]# redis-cli -c --raw -p 6378 hmget stu_00000009 sid sname
00000009
汪涵

5.4 集群管理

5.4.1 故障轉移

1)查詢172.16.1.54主機上的主節點(6378埠實例)數據

[root@cache06 ~]# redis-cli -c -h 172.16.1.54 -p 6378
172.16.1.54:6378> keys *
1) "stu_00000005"
2) "stu_00000001"
3) "stu_00000008"
4) "stu_00000004"

#查詢學生stu_00000005的姓名
[root@cache06 ~]# redis-cli -c --raw -p 6378 hget stu_00000005 sname
沈浪

2)停止服務

#停止172.16.1.54主機上的主節點(6378實例)服務
[root@cache06 ~]# redis-cli -c -h 172.16.1.54 -p 6378 shutdown

#查看進程是否存在
[root@cache04 ~]# ps -ef|grep [r]edis
root       2631      1  0 15:47 ?        00:00:29 redis-server *:6379 [cluster]

3)檢查集群節點狀態

[root@cache06 ~]# redis-cli -c -p 6378 cluster nodes
ca2a21eb3b5679c61b186ca4ca661f93e11ec304 172.16.1.56:6378 master - 0 1555066929017 5 connected 10923-16383
90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.57:6379 master - 0 1555066928312 7 connected 0-5460
f2d4d17676e6166bcdc2d05d81fc891327d03319 172.16.1.57:6378 master - 0 1555066927808 3 connected 5461-10922
78e4b73c8f5f57d55303db52e9774ba69a306bb2 172.16.1.56:6379 myself,slave ca2a21eb3b5679c61b186ca4ca661f93e11ec304 0 0 6 connected
4b462992200244a66c63f085ffd7ef4983a9655b 172.16.1.54:6379 slave f2d4d17676e6166bcdc2d05d81fc891327d03319 0 1555066928008 3 connected
a560974d9721882574aaf7fa4cf7218f590e97e0 172.16.1.54:6378 master,fail - 1555066721816 1555066719602 1 disconnected

可以看到172.16.1.54的主節點顯示fail狀態,原來的172.16.1.57的從節點(6379實例),自動提升為master。

4)再次檢索stu_00000005學生信息,可以正常查詢

[root@cache06 ~]# redis-cli -c --raw -p 6378
127.0.0.1:6378> hgetall stu_00000005
-> Redirected to slot [5220] located at 172.16.1.57:6379
sid
00000005
sname
沈浪
address
上海市

5.4.2 添加節點

語法:redis-trib.rb add-node new_host:new_port existing_host:existing_port --slave --master-id <arg>

參數:

  • --slave:以從節點身份加入集群。
  • --master-id:主節點號。
  • new_host:new_port:新增節點的地址。
  • existing_host:existing_port:集群中任意一個節點的地址。

1)添加節點

#刪除實例下的文件,只保留redis.conf配置文件
[root@cache04 data]# rm -f 6378/{appendonly.aof,dump.rdb,nodes.conf,redis.log}
#啟動實例
[root@cache04 data]# redis-server /data/6378/redis.conf 
#檢查進程
[root@cache04 data]# ps -ef|grep [r]edis
root       2631      1  0 07:04 ?        00:00:59 redis-server *:6379 [cluster]
root       3607      1  0 12:35 ?        00:00:00 redis-server *:6378 [cluster]
#查看節點數據,當前節點數據為空
[root@cache04 data]# redis-cli -c -p 6378
127.0.0.1:6378> keys *
(empty list or set)

2)以slave身份加入到集群

[root@cache04 data]# redis-trib.rb add-node --slave --master-id 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.54:6378 172.16.1.57:6379
>>> Adding node 172.16.1.54:6378 to cluster 172.16.1.57:6379
>>> Performing Cluster Check (using node 172.16.1.57:6379)
M: 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.57:6379
   slots:0-5460 (5461 slots) master
   0 additional replica(s)
S: ca2a21eb3b5679c61b186ca4ca661f93e11ec304 172.16.1.56:6378
   slots: (0 slots) slave
   replicates 78e4b73c8f5f57d55303db52e9774ba69a306bb2
S: 4b462992200244a66c63f085ffd7ef4983a9655b 172.16.1.54:6379
   slots: (0 slots) slave
   replicates f2d4d17676e6166bcdc2d05d81fc891327d03319
M: 78e4b73c8f5f57d55303db52e9774ba69a306bb2 172.16.1.56:6379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
M: f2d4d17676e6166bcdc2d05d81fc891327d03319 172.16.1.57:6378
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 172.16.1.54:6378 to make it join the cluster.
Waiting for the cluster to join.
>>> Configure node as replica of 172.16.1.57:6379.
[OK] New node added correctly.

3)檢查集群節點狀態

[root@cache06 ~]# redis-cli -c -p 6378 cluster nodes
78e4b73c8f5f57d55303db52e9774ba69a306bb2 172.16.1.56:6379 master - 0 1555130226500 8 connected 10923-16383
4b462992200244a66c63f085ffd7ef4983a9655b 172.16.1.54:6379 slave f2d4d17676e6166bcdc2d05d81fc891327d03319 0 1555130225999 3 connected
f2d4d17676e6166bcdc2d05d81fc891327d03319 172.16.1.57:6378 master - 0 1555130227043 3 connected 5461-10922
90fc1e298bdfb55e35a9dae7137684c6217dc6ff 172.16.1.57:6379 master - 0 1555130227547 7 connected 0-5460
69f66290fd63721965c83a71b5f673a3907d38da 172.16.1.54:6378 slave 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 0 1555130227547 7 connected
ca2a21eb3b5679c61b186ca4ca661f93e11ec304 172.16.1.56:6378 myself,slave 78e4b73c8f5f57d55303db52e9774ba69a306bb2 0 0 5 connected
a560974d9721882574aaf7fa4cf7218f590e97e0 :0 slave,fail,noaddr 90fc1e298bdfb55e35a9dae7137684c6217dc6ff 1555129672056 1555129671656 7 disconnected

可以看到172.16.1.54:6378實例以從節點身份加入集群,並且指向的主節點是172.16.1.57:6379實例。

4)檢查節點數據

#查看節點數據是否存在,預設加入集群之後,會從主節點進行全量複製
[root@cache04 data]# redis-cli -c -p 6378
127.0.0.1:6378> keys *
1) "stu_00000001"
2) "stu_00000005"
3) "stu_00000004"
4) "stu_00000008"

#獲取數據
[root@cache04 data]# redis-cli -c --raw -p 6378
127.0.0.1:6378> hgetall stu_00000005
-> Redirected to slot [5220] located at 172.16.1.57:6379
sid
00000005
sname
沈浪
address
上海市

遇到的問題小結:

ERROR1:new_host:new_port:待添加的節點,必須確保數據為空或者不在集群中,否則,會提示一下錯誤。

#使用redis-trib.rb添加新節點,在節點加入集群之前,會對新節點的狀態進行檢查
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
[ERR] Node 172.16.1.54:6378 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

ERROR2:--slave和--master-id必須跟在add-node後面,同樣的參數,如果是以下這種寫法,會提示錯誤。

[root@cache06 ~]# redis-trib.rb add-node 172.16.1.54:6378 172.16.1.57:6379 --slave --master-id 90fc1e298bdfb55e35a9dae7137684c6217dc6ff
[ERR] Wrong number of arguments for specified sub command

六、實現Python鏈接Redis Cluster集群

實現Python鏈接及操作Redis Cluster,需要以下環境支持:

1.搭建Python開發環境,Python2.7.2以上版本才支持Redis Cluster,這裡選擇的是3.5。

  • Python2 使用2.7以後的版本
  • Python3 使用3.4以後的版本(新項目推薦)

2.安裝驅動程式,官方提供多種Python連接redis的API方式,這裡推薦使用redis-py。

3.Redis-py並沒有提供Redis-cluster的支持,需要下載redis-py-cluster。

6.1 搭建python開發環境

##安裝之前,檢查python版本
[root@cache04 tools]# python --version
Python 2.7.5

#下載python3.x
[root@cache04 tools]# wget https://www.python.org/ftp/python/3.5.5/Python-3.5.5.tgz

#源碼安裝
[root@cache04 tools]# tar xf Python-3.5.5.tgz 
[root@cache04 tools]# cd Python-3.5.5/
[root@cache04 Python-3.5.5]# ./configure
[root@cache04 Python-3.5.5]# make && make install

#檢查安裝環境,這裡使用python3命令,而不是python命令
[root@cache04 Python-3.5.5]# python3
Python 3.5.5 (default, Apr 14 2019, 11:13:51) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()

6.2 安裝Redis-py驅動程式

Redis-py提供的,Python 連接及操作Redis方式:

  1. Redis-py提供兩個類Redis和StrictRedis用於實現Redis的命令。StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令(比如:SET命令對應與StrictRedis.set方法)。(推薦)

  2. Redis是StrictRedis的子類,用於向後相容舊版本的redis-py。

#下載源碼包
[root@cache04 tools]# wget https://github.com/andymccurdy/redis-py/archive/2.10.6.tar.gz
#解壓
[root@cache04 tools]# tar xf 2.10.6.tar.gz 
#切換到包目錄下
[root@cache04 tools]# cd redis-py-2.10.6/
#使用python3安裝驅動
[root@cache04 redis-py-2.10.6]# python3 setup.py install
#導入redis包,沒有報錯,驅動安裝成功
[root@cache04 redis-py-cluster-1.3.6]# python3
Python 3.5.5 (default, Apr 14 2019, 11:13:51) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import redis
>>>

6.3 安裝Redis-py-cluster驅動程式

Redis-py並沒有提供Redis-cluster的支持,需要下載redis-py-cluster包,管理集群。

註意:redis-py3.0.x版本和redis-py-cluster版本存在不相容的問題(目前redis-py-cluster最新版本為1.3.6),實際使用過程中,建議降低redis-py版本為2.10.6,這也是redis-py-cluster作者建議的。

#使用redis-py-3.0.1版本遇到的問題,在導入類文件的時候,出現報錯
[root@cache04 redis-py-cluster-1.3.6]# python3
>>> from rediscluster import StrictRedisCluster 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/server/tools/redis-py-cluster-1.3.6/rediscluster/__init__.py", line 7, in <module>
    from .client import StrictRedisCluster, RedisCluster
  File "/server/tools/redis-py-cluster-1.3.6/rediscluster/client.py", line 10, in <module>
    from .connection import (
  File "/server/tools/redis-py-cluster-1.3.6/rediscluster/connection.py", line 11, in <module>
    from .nodemanager import NodeManager
  File "/server/tools/redis-py-cluster-1.3.6/rediscluster/nodemanager.py", line 12, in <module>
    from redis._compat import b, unicode, bytes, long, basestring
ImportError: cannot import name 'b'

安裝Redis-py-cluster程式。

#下載源碼包
[root@cache04 tools]# https://github.com/Grokzen/redis-py-cluster/archive/1.3.6.tar.gz
#解壓
[root@cache04 tools]# tar xf 1.3.6.tar.gz 
#切換到包目錄下
[root@cache04 tools]# cd redis-py-cluster-1.3.6
#使用python3安裝驅動
[root@cache04 redis-py-cluster-1.3.6]# python3 setup.py install

6.4 測試API讀寫功能

#寫入數據
[root@cache04 tools]# python3
Python 3.5.5 (default, Apr 14 2019, 11:13:51) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from rediscluster import StrictRedisCluster
>>> startup_nodes = [{"host": "127.0.0.1", "port": "6379"}]         
>>> conn = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
>>> conn.set("msg","Nice to meet you")
True

#讀取數據,檢查是否寫入成功
[root@cache06 ~]# redis-cli -c -p 6378 get msg
"Nice to meet you"

遇到的問題小結:
ERROR1:使用python交互模式,在命令開頭不能有任何空格,否則,會出現報錯。

>>>  from rediscluster import StrictRedisCluster    #命令開頭不能有空格或tab
  File "<stdin>", line 1
    from rediscluster import StrictRedisCluster 
    ^
IndentationError: unexpected indent

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 閑聊 步入前端切圖仔行列的我曾多次糾結過「到底使用哪種編輯器寫前端好用?」這樣的問題,前前後後嘗試過 Dreamweaver 、HBuilder 、Sublime Text 、Atom 和現在主要使用的 VSCode 。現在回過頭來看,我發現這個問題有了答案,那就是「愛用啥用啥」。(笑…… 今天的主 ...
  • request、out對象使用 一、實驗目的 1、掌握代碼片段中的註釋的應用; 2、掌握JSP腳本標示 Java代碼片段的應用。 二、實驗內容 1、設計教師與學生不同登陸界面,如下圖; 2、驗證碼隨機生成; 3、提交後分別轉向教師頁面和學生頁面進行判斷用戶名和密碼正確性; 4、如果正確,3秒後,轉向 ...
  • 渲染機制 渲染機制主要分為兩部分: 首次渲染和更新渲染。 首次渲染 首先通過一個小例子,來講解首次渲染過程。 程式運行到 時,其中的 babel React.createElement(ClickCounter, null) element`如下: 接下來執行 函數,生成 節點。首先瞭解下 的部分數 ...
  • 原文首發: "行為型模式:解釋器模式" 十一大行為型模式之十:解釋器模式。 簡介 姓名 :解釋器模式 英文名 :Interpreter Pattern 價值觀 :不懂解釋到你懂​ 個人介紹 : Given a language, define a representation for its gra ...
  • 面向對象的詳細解讀 一、基本概念 1. 面向過程 (1) 概念:以過程為中心的編程思想,就是分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,使用的時候一個一個依次調用就可以了。 (2) 優點:極大的降低了寫程式的複雜度,只需要順著要執行的步驟,堆疊代碼即可。因為程式的流程很清楚,按著模 ...
  • 抽象工廠模式概述 定義:提供一個創建一系列相關或相互依賴對象的介面,而無需指定他們具體的類 抽象工廠抽象工廠,顧名思義,就是比工廠模式更抽象的工廠模式。在工廠模式中,一個具體工廠只負責生產一個具體產品。而在抽象工廠模式中,一個具體工廠可以生產一組相關的產品,這些產品稱為產品族,產品族中的每一個產品部 ...
  • 前言: 現在我們生活中已經離不開微信,QQ等交流軟體,這對於我們來說不僅是交流,更有在朋友圈中或空間中進行分享自己的生活,同時也可以通過這個渠道知道別人的生活。我們在看朋友圈的時候其實我們扮演的就是一個觀察者,朋友圈或空間里的動態可以看作是主體對象。接下來我們就介紹一下觀察者模式 一、定義 定義了對 ...
  • 前段時間看到一份代碼,小規模、低難度的一個應用,MVC用到極致,業務邏輯卻混成一團麻,應該是中了培訓班的毒。現在的程式員,大多是沒仔細讀過《現代操作系統》,沒看過編譯原理,不知道堆與棧,沒怎麼用過C、C++,上手就Java、C#,程式一開就記憶體狂飆,資料庫連接隨手就建,但這種人算是相當多了,見多了也 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...