Redis集群

Redis集群通过数据分片解决海量数据存储和并发写压力,采用虚拟槽分区算法,将数据自动分配到不同节点。集群搭建涉及节点间相互感知、分配主从,通过`redis-cli`工具进行操作。Python操作Redis集群可使用`redis-py-cluster`库,简化客户端交互。
摘要由CSDN通过智能技术生成

一 Redis集群介绍

1.1 为什么需要Redis集群?

从最开始的一主N从,到读写分离,再到Sentinel哨兵机制,单实例的Redis缓存足以应对大多数的使用场景,也能实现主从故障迁移。

在这里插入图片描述
但是,在某些场景下,单实例存Redis缓存会存在的几个问题:

1)写并发:

Redis单实例读写分离可以解决读操作的负载均衡,但对于写操作,仍然是全部落在了master节点上面,在海量数据高并发场景,一个节点写数据容易出现瓶颈,造成master节点的压力上升。

(2)海量数据的存储压力:

单实例Redis本质上只有一台Master作为存储,如果面对海量数据的存储,一台Redis的服务器就应付不过来了,而且数据量太大意味着持久化成本高,严重时可能会阻塞服务器,造成服务请求成功率下降,降低服务的稳定性。

1.2 什么是Redis集群?

Redis3.0加入了Redis的集群模式,实现了数据的分布式存储,对数据进行分片,将不同的数据存储在不同的master节点上面,从而解决了海量数据的存储问题。

Redis集群采用去中心化的思想,没有中心节点的说法,对于客户端来说,整个集群可以看成一个整体,可以连接任意一个节点进行操作,就像操作单一Redis实例一样,不需要任何代理中间件,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。

Redis也内置了高可用机制,支持N个master节点,每个master节点都可以挂载多个slave节点,当master节点挂掉时,集群会提升它的某个slave节点作为新的master节点。
在这里插入图片描述

二 数据分布(分布式数据库)

分布式数据库要解决的就是将整块数据,按照规则分配到多个缓存节点,解决的是单个缓存节点处理数量大的问题。

如果要将这些数据进行拆分,并且存放必须有一个算法。例如:哈希算法和哈希一致性算法,这些比较经典的算法。

Redis Cluster 则采用的是虚拟槽分区算法。其中提到了槽(Slot)的概念。这个槽是用来存放缓存信息的单位,在 Redis 中将存储空间分成了 16384 个槽,也就是说 Redis Cluster 槽的范围是 0 -16383(2^4 * 2^10)。

缓存信息通常是用 Key-Value 的方式来存放的,在存储信息的时候,集群会对 Key 进行 CRC16 校验并对 16384 取模(slot = CRC16(key)%16383)

得到的结果就是 Key-Value 所放入的槽,从而实现自动分割数据到不同的节点上。然后再将这些槽分配到不同的缓存节点中保存。

在这里插入图片描述
如图所示,假设有三个缓存节点分别是 1、2、3。Redis Cluster 将存放缓存数据的槽(Slot)分别放入这三个节点中:

缓存节点 1 存放的是(0-5000)Slot 的数据。缓存节点 2 存放的是(5001-10000)Slot 的数据。缓存节点 3 存放的是(10000-16383)Slot 的数据。

此时 Redis Client 需要根据一个 Key 获取对应的 Value 的数据,首先通过 CRC16(key)%16383 计算出 Slot 的值,假设计算的结果是 5002。

将这个数据传送给 Redis Cluster,集群接受到以后会到一个对照表中查找这个 Slot=5002 属于那个缓存节点。

发现属于“缓存节点 2”,于是顺着红线的方向调用缓存节点 2 中存放的 Key-Value 的内容并且返回给 Redis Client。

三 集群搭建

搭建一个6台机器,3个节点的集群

第一步:准备6台机器

# 准备6个配置文件
vim redis-7000.conf
port 7000
daemonize yes
dir "/root/redis/data/"
logfile "7000.log"
dbfilename "dump-7000.rdb"
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-require-full-coverage yes 

# 配置文件解释
cluster-enabled yes  # 开启cluster
cluster-node-timeout 15000 # 故障转移,超时时间 15s
cluster-config-file nodes-${port}.conf  # 给cluster节点增加一个自己的配置文件
cluster-require-full-coverage yes  #只要集群中有一个故障了,整个就不对外提供服务了,这个实际不合理,假设有50个节点,一个节点故障了,所有不提供服务了;,需要设置成no

# 快速生成其他配置5个配置文件
sed 's/7000/7001/g' redis-7000.conf > redis-7001.conf
sed 's/7000/7002/g' redis-7000.conf > redis-7002.conf
sed 's/7000/7003/g' redis-7000.conf > redis-7003.conf
sed 's/7000/7004/g' redis-7000.conf > redis-7004.conf
sed 's/7000/7005/g' redis-7000.conf > redis-7005.conf

# 启动6台机器
redis-server ./redis-7000.conf
redis-server ./redis-7001.conf
redis-server ./redis-7002.conf
redis-server ./redis-7003.conf
redis-server ./redis-7004.conf
redis-server ./redis-7005.conf
ps -ef |grep redis

在这里插入图片描述
第二步:相互感知,分配主从,分配槽

# meet,分配槽,指定主从。 1 的意思是,每个节点都是一主一从 ,自动组建主从

redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

yes

在这里插入图片描述
在这里插入图片描述
第三步:主从关系和集群关系

主:7000   从:7004
主:7001   从:7005
主:7002   从:7003

第四步:3个命令

cluster nodes   # 看节点信息
cluster slots   # 槽的信息
cluster info    # 整体信息

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

redic-cli -c # 集群模式链接,设置获取值,如果不在当前节点,会自动转过去,并完成数据操作

在这里插入图片描述

四 集群扩容(8台机器,4个节点的集群)

# 启动两台机器,加入到集群中(meet),两台机器做主从,各个节点分配槽。

# 第一步启动两台机器
sed 's/7000/7006/g' redis-7000.conf > redis-7006.conf
sed 's/7000/7007/g' redis-7000.conf > redis-7007.conf

# 第二步:启动新增的两台机器
redis-server ./redis-7006.conf
redis-server ./redis-7007.conf

# 第三步:两台机器加入到集群中去
redis-cli --cluster add-node 127.0.0.1:7006 127.0.0.1:7000
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7000

# 第四步:让7007作为7006的从
redis-cli -p 7007 cluster replicate 82b00d882879141a08e916898c0c9ebe300c57a3

第五步:迁移槽:从每台机器均匀的移动一部分槽给新的机器

redis-cli --cluster reshard 127.0.0.1:7000 
# 迁移多少个槽:4096
# 哪个id接收:7006的id 82b00d882879141a08e916898c0c9ebe300c57a3
# 传入source id :all
# yes

在这里插入图片描述

五 集群缩容

# 7006管理的槽,移走,关闭节点,节点下线,先下从库,再下主

# 第一步:下线迁槽
# 把7006的1365个槽迁移到7000上
redis-cli --cluster reshard --cluster-from 82b00d882879141a08e916898c0c9ebe300c57a3 --cluster-to dd220a1ff2157fee22b9ff181f62323faa30d233 --cluster-slots 1365 127.0.0.1:7000
yes

# 把7006的1366个槽迁移到7001上
redis-cli --cluster reshard --cluster-from 82b00d882879141a08e916898c0c9ebe300c57a3 --cluster-to ec5cccb1e241a63564c2bc74efcdbae08695bcf0 --cluster-slots 1366 127.0.0.1:7000
yes

# 把7006的1366个槽迁移到7002上
redis-cli --cluster reshard --cluster-from 82b00d882879141a08e916898c0c9ebe300c57a3 --cluster-to e4a9d3b83c9c230d12ca3af10116c9519d1e48e2 --cluster-slots 1366 127.0.0.1:7000

在这里插入图片描述

# 第二步:下线节点 忘记节点,关闭节点
redis-cli --cluster del-node 127.0.0.1:7000 479e89b3a4de41cee6461cdc51a071770e0280c7

# 先下从,再下主,因为先下主会触发故障转移
redis-cli --cluster del-node 127.0.0.1:7000 82b00d882879141a08e916898c0c9ebe300c57a3

# 第三步:关掉其中一个主,另一个从立马变成主顶上, 重启停止的主,发现变成了从

在这里插入图片描述

六 python操作集群

pip3 install redis-py-cluster
from rediscluster import RedisCluster
startup_nodes = [{"host":"127.0.0.1", "port": "7000"},{"host":"127.0.0.1", "port": "7001"},{"host":"127.0.0.1", "port": "7002"}]
# rc = RedisCluster(startup_nodes=startup_nodes,decode_responses=True)
rc = RedisCluster(startup_nodes=startup_nodes)
rc.set("xx", "xx")
rc.set("yy", "yy")
print(rc.get("xx"))
print(rc.get("yy"))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值