目前在做Python项目用到同步和异步的方法使用Redis单机,现在要增加兼容Redis集群。也就说当前项目用到中以下4种Python使用Redis的方法都用到了。
并且由于Redis单机版用的是redis-py
这个官方模块,所以集群也需要使用同样的模块。
早期的redis-py
不支持集群的连接,网上能查到集群的连接是用另一个模块redis-py-cluster
。其实redis-py
后面整合了redis-py-cluster
集群相关的连接,所以也能支持集群连接。
可以参见包的介绍:https://pypi.org/project/redis/
本文介绍以上4种连接方法。本地环境
:
Python:3.8
Redis:4.3.4
|
redis到目前已经更新到redis7.0.2,本文使用redis5.0.4,同时使用较为简单的docker来部署。首先下载docker镜像 redis 5.0.4
docker pull redis:5.0.4
docker pull redis:5.0.4 5.0.4: Pulling from library/redis 29b80961214d: Pull complete 4c417db3b6fe: Pull complete 262a0c65662c: Pull complete 36db11a6661e: Pull complete d5d8b9326480: Pull complete 4e9148e44a67: Pull complete Digest: sha256:2dfa6432744659268d001d16c39f7be52ee73ef7e1001ff80643f0f7bdee117e Status: Downloaded newer image for redis:5.0.4 docker.io/library/redis:5.0.4
ljk@192 ~ % docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis 5.0.4 b61ab367aee1 3 years ago 90MB
|
docker run -itd --name=redis0 redis:5.0.4
(ymir) ➜ docker run -itd --name=redis0 redis:5.0.4 75ec79bd233c917fb681e224559c67a5e90c55089ffd01b1df8d939795b70746 (ymir) ➜ nacos git:(dev) docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4e7ab577003c redis:5.0.4 "docker-entrypoint.s…" 53 seconds ago Up 52 seconds 6379/tcp redis0
查看docker的ip地址
docker inspect redis0
可以得到redis0的ip地址是 172.17.0.8
|
导入 StrictRedis
模块,连接redis。这里留意一下:
Redis 提供两个类 Redis 和 StrictRedis, StrictRedis 用于实现大部分官方的命令,Redis 是 StrictRedis 的子类,用于向后兼用旧版本。所以优先使用StrictRedis。
import asyncio def sync_singal(): from redis import StrictRedis ip = "172.17.0.8" redis_conn = StrictRedis( host=ip, port=6379, encoding="utf8", decode_responses=True, db=, ) redis_conn.set("name", "sync singal") res = redis_conn.get("name") print(res) sync_singal()
结果:
(ymir) ➜ Desktop python redis_learn.py sync singal
|
异步编程用官方模块asyncio
实现,注意导入的库是redis.asyncio
。需要在连接、设置、获取等使用redis的地方可等待。
import asyncio async def async_singal(): from redis.asyncio import StrictRedis ip = "172.17.0.8" redis_conn = await StrictRedis( host=ip, port=6379, encoding="utf8", decode_responses=True, db=, ) await redis_conn.set("name", "async singal") res = await redis_conn.get("name") print(res) asyncio.run(async_singal())
结果:
(ymir) ➜ Desktop python redis_learn.py async singal
|
redis的集群有三种,这里以cluster集群为例,使用docker快速搭建一个cluster集群。
cluster集群要求至少三个节点组建成3个master节点,下面使用6个节点,组成三主三从经典集群。
1.启动docker
docker run -itd --name redis-nodes1 redis:5.0.4 --cluster-enabled yes docker run -itd --name redis-nodes2 redis:5.0.4 --cluster-enabled yes docker run -itd --name redis-nodes3 redis:5.0.4 --cluster-enabled yes docker run -itd --name redis-nodes4 redis:5.0.4 --cluster-enabled yes docker run -itd --name redis-nodes5 redis:5.0.4 --cluster-enabled yes docker run -itd --name redis-nodes6 redis:5.0.4 --cluster-enabled yes
2.查询所有docker的ip
查询出所有docker的ip,用于组建集群
docker inspect redis-nodes1
得到所有节点的ip
- 创建集群
登录到其中一个redis,执行集群创建命令
redis-cli --cluster create 172.17.0.2:6379 172.17.0.3:6379 172.17.0.4:6379 172.17.0.5:6379 172.17.0.6:6379 172.17.0.7:6379 --cluster-replicas 1
--cluster-replicas 1 表示主从节点比例是1:1。如果是0则表示没有从节点
4.检查集群是否创建成功
如上就表示cluster集群创建成功
|
从redis.cluster
导入RedisCluster
,将所有节点信息打包成一个列表
import asyncio def sync_cluster(): from redis.cluster import ClusterNode from redis.cluster import RedisCluster cluster_nodes = [ ClusterNode("172.17.0.2", 6379), ClusterNode("172.17.0.3", 6379), ClusterNode("172.17.0.4", 6379), ClusterNode("172.17.0.5", 6379), ClusterNode("172.17.0.6", 6379), ClusterNode("172.17.0.7", 6379), ] redis_conn = RedisCluster( startup_nodes=cluster_nodes, password=None, encoding="utf8", decode_responses=True, ) redis_conn.set("name", "sync cluster") res = redis_conn.get("name") print(res) sync_cluster()
(ymir) ➜ Desktop python redis_learn.py async singal
|
从redis.asyncio.cluster
中导入ClusterNode
和RedisCluster
,注意不能用同步模块的ClusterNode,两者名称一致但是方法不同。
async def async_cluster(): from redis.asyncio.cluster import ClusterNode from redis.asyncio.cluster import RedisCluster cluster_nodes = [ ClusterNode("172.17.0.2", 6379), ClusterNode("172.17.0.3", 6379), ClusterNode("172.17.0.4", 6379), ClusterNode("172.17.0.5", 6379), ClusterNode("172.17.0.6", 6379), ClusterNode("172.17.0.7", 6379), ] redis_conn = await RedisCluster( startup_nodes=cluster_nodes, password=None, encoding="utf8", decode_responses=True, ) await redis_conn.set("name", "async cluster") res = await redis_conn.get("name") print(res) asyncio.run(async_cluster())
结果:
(ymir) ➜ Desktop python redis_learn.py async cluster
异步集群需要注意的是,如果集群有密码,需要在ClusterNode
中设置密码,如下:
cluster_nodes = [ ClusterNode("172.17.0.2", 6379, password="xxx"), ClusterNode("172.17.0.3", 6379, password="xxx"), ClusterNode("172.17.0.4", 6379, password="xxx"), ClusterNode("172.17.0.5", 6379, password="xxx"), ClusterNode("172.17.0.6", 6379, password="xxx"), ClusterNode("172.17.0.7", 6379, password="xxx"), ]
看起来比较奇怪,从redis-py的源码和实际使用中看确实如此。