redis集群
最近在学习redis的集群的相关内容,对它的概念理解不是很深刻,还是得亲手搭建一个集群才行。下面是自己从0开始搭建的一个6节点的最简单集群, 最后还用python客户端来连接集群,实现一些简单的操作的一个学习记录。
0. 简介
Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时,可以采用Cluster架构方案达到负载均衡的目的。
1、创建目录
[root@localhost ~]# mkdir redis_cluster
[root@localhost ~]# cd redis_cluster
2、下载源码并解压编译安装
# 下载最新的5.0.7版本的redis到当前路径
wget http://download.redis.io/releases/redis-5.0.7.tar.gz
# 解压缩
tar xzf redis-5.0.7.tar.gz
# 进入
cd redis-5.0.7
# 编译, 编译之前可能需要安装gcc --> yum install gcc-c++
make
# 安装到/usr/local/redis文件夹
make install PREFIX=/usr/local/redis
# 这里还需要将默认的配置文件拷贝到对应的运行目录
cp ~/redis_cluster/redis-5.0.7/redis.conf /usr/local/redis/bin
3、搭建集群目录
1 在usr/local目录下创建redis-cluster目录, 用于存放集群节点
mkdir /usr/local/redis-cluster
cd /usr/local
# 将redis的安装目录copy到存放集群节点的地方
cp -r redis/bin/ redis-cluster/redis01
4、修改配置文件
# 修改配置文件
vim /usr/local/redis-cluster/redis01/redis.conf
# 基础的配置项可能有下面所示这几项
# 把绑定本地的配置注释掉
# bind 127.0.0.1
# 开启后台运行模式
daemonize yes
# 修改端口为7000
port 7000
# 开启集群模式
cluster-enabled yes
# 集群内配置文件, 这里先不进行配置
# cluster-config-file nodes.conf
# 集群超时时间
# cluster-node-timeout 15000
5、搭建其他节点
重复上述流程,依次搭建剩余的一些节点7001-7005, 先将redis01的文件copy过去
cd /usr/local/redis-cluster/
cp -r redis01/ redis02
cp -r redis01/ redis03
cp -r redis01/ redis04
cp -r redis01/ redis05
cp -r redis01/ redis06
然后修改每个redis
暴露的端口 7001-7005
vim redis02/redis.conf
vim redis03/redis.conf
vim redis04/redis.conf
vim redis05/redis.conf
vim redis06/redis.conf
最后的结果如下所示
[root@localhost redis-cluster]# ll
总用量 24
drwxr-xr-x. 2 root root 4096 12月 9 00:27 redis01
drwxr-xr-x. 2 root root 4096 12月 9 00:36 redis02
drwxr-xr-x. 2 root root 4096 12月 9 00:36 redis03
drwxr-xr-x. 2 root root 4096 12月 9 00:36 redis04
drwxr-xr-x. 2 root root 4096 12月 9 00:34 redis05
drwxr-xr-x. 2 root root 4096 12月 9 00:34 redis06
6、启动所有redis服务
简单封装成一个小脚本start-server.sh
来快速启动所有节点。
vim start-server.sh # 在集群目录下创建这个sh文件
cd /usr/local/redis-cluster/redis01/
./redis-server redis.conf
cd /usr/local/redis-cluster/redis02/
./redis-server redis.conf
cd /usr/local/redis-cluster/redis03/
./redis-server redis.conf
cd /usr/local/redis-cluster/redis04/
./redis-server redis.conf
cd /usr/local/redis-cluster/redis05/
./redis-server redis.conf
cd /usr/local/redis-cluster/redis06/
./redis-server redis.conf
执行该脚本, 启动所有节点
bash start-server.sh
# 查看节点启动情况
ps aux | grep redis
7、创建集群
由于我使用的是redis5版本, 所以不需要下载ruby脚本来创建集群, 直接使用自带的客户端命令来进行执行就可以了。
./redis-cli --cluster create 192.168.12.78:7000 192.168.12.78:7001 192.168.12.78:7002 192.168.12.78:7003 192.168.12.78:7004 192.168.12.78:7005 --cluster-replicas 1
中途有个地方需要手动输入yes
如果上面出现如下异常
[root@localhost redis01]# ./redis-cli --cluster create 192.168.12.78:7000 192.168.12.78:7001 192.168.12.78:7002 192.168.12.78:7003 192.168.12.78:7004 192.168.12.78:7005 --cluster-replicas 1
[ERR] Node 127.0.0.1:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
# 这里的解决方案就是删除旧的集群的持久化文件,再重新创建
至此, redis
集群就已经搭建完毕了。从最后的打印信息可以看到7000,7001,7002是主节点, 并显示了每个节点所分配的slots
(哈希槽),3个主节点分别映射了0-5460、5461-10922、10933-16383solts
。
下面是使用客户端连接的测试。
# 随意挑选一个客户端进行连接, 一定要加`-c`参数,节点之间就可以互相跳转
./redis-cli -c -p 7000
127.0.0.1:7000> set foo bar
-> Redirected to slot [12182] located at 127.0.0.1:7002
OK
127.0.0.1:7002> set a 0
OK
127.0.0.1:7002> set b 1
-> Redirected to slot [3300] located at 127.0.0.1:7000
OK
127.0.0.1:7000> set c 2
-> Redirected to slot [7365] located at 127.0.0.1:7001
OK
8、python操作redis集群
集群操作不能使用redis
模块,要专门使用redis-py-cluster
这个模块来进行操作.
pip install redis-py-cluster
# 报错信息
"""
redis.exceptions.ResponseError: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
"""
出现以上信息的原因是redis
处于保护模式,外部ip
无法连接,要关闭保护模式,需要在每个redis
的配置文件中配置protected-mode no
。然后重启集群即可。
重启之后,就是正常的操作,使用这个模块还是比较简单的,和正常的redis模块没有太多区别。
from rediscluster import RedisCluster
# Requires at least one node for cluster discovery. Multiple nodes is recommended.
startup_nodes = [
# 填写虚拟机的地址
{"host": "192.168.12.78", "port": "7000"},
{"host": "192.168.12.78", "port": "7001"},
{"host": "192.168.12.78", "port": "7002"},
{"host": "192.168.12.78", "port": "7003"},
{"host": "192.168.12.78", "port": "7004"},
{"host": "192.168.12.78", "port": "7005"},
]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)
rc.set('test2', 'test2...')
print(rc.get('test1'))
print(rc.get('test2'))
上面这个模块的详细信息可以继续参考官方文档,redis集群操作和单机操作一些方法上还是有一些限制的,需要开发人员提前了解,在使用时做好规避。限制如下:
1)key批量操作支持有限。如mset、mget,目前只支持具有相同slot值的
key执行批量操作。对于映射为不同slot值的key由于执行mget、mget等操作可
能存在于多个节点上因此不被支持。
2)key事务操作支持有限。同理只支持多key在同一节点上的事务操
作,当多个key分布在不同的节点上时无法使用事务功能。
3)key作为数据分区的最小粒度,因此不能将一个大的键值对象如
hash、list等映射到不同的节点。
4)不支持多数据库空间。单机下的Redis可以支持16个数据库,集群模
式下只能使用一个数据库空间,即db0。
5)复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复
制结构。