实现Redis Cluster并实现Python链接集群
目录
一、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集群提供了以下两个好处:
- 将数据自动切分(split)到多个节点的能力。
- 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。
三、环境准备
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权限:
- sysctl vm.overcommit_memory=1
- echo 'vm.overcommit_memory=1' >>/etc/sysctl.conf && sysctl -p
- 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]# /application/redis/bin/redis-cli set name oldboy ok [root@cache06 redis]# /application/redis/bin/redis-cli get name "oldboy" #删除数据 [root@cache06 redis]# /application/redis/bin/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上的所有数据都复制一份。
具体步骤如下:
- 从服务器连接主服务器,发送sync命令;
- 主服务器接收到sync命令后,开始执行bgsave命令生成rdb文件,并使用缓冲区记录此后执行的所有写命令;
- 主服务器bgsave执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
- 从服务器收到快照文件后丢弃旧的数据,载入新的快照;
- 主服务器快照发送完毕后,开始向从服务器发送缓冲区中的写命令;
- 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;
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方式:
redis-py提供两个类redis和strictredis用于实现redis的命令。strictredis用于实现大部分官方的命令,并使用官方的语法和命令(比如:set命令对应与strictredis.set方法)。(推荐)
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
推荐阅读
-
Redis Cluster集群动态扩容的实现
-
Redis的Cluster集群搭建的实现步骤
-
实现Redis Cluster并实现Python链接集群
-
k8s部署redis cluster集群的实现
-
Redis3.0集群crc16算法php客户端实现方法(php获得redis3.0集群中redis数据所在的redis分区插槽,并根据分区插槽取得分区所在redis服务器地址)
-
Redis3.0集群crc16算法php客户端实现方法(php获得redis3.0集群中redis数据所在的redis分区插槽,并根据分区插槽取得分区所在redis服务器地址)
-
docker redis5.0 cluster集群搭建的实现
-
redis cluster集群实现高可用
-
实现Redis Cluster并实现Python链接集群
-
Redis的Cluster集群搭建的实现步骤