NoSQL——redis集群——Cluster群集
前言
一、Cluster群集
redis的哨兵模式基本已经可以实现高可用、读写分离,但是在这种模式每台redis服务器都存储相同的数据,很浪费内存资源,所以在redis3.0上加入了Cluster群集模式,实现了redis的分布式存储,也京是说每台redis节点存储着不同的内容根据官方推荐,集群部署至少要3台以上的master节点,最好使用3主3从六个节点的模式。
-
Cluster群集由多个redis服务器组成的分布式网络服务群集,群集之中有多个master主节点,每一个主节点都可读可写,节点之间会相互通信,两两相连,redis群集无中心节点
-
在redis-Cluster群集中,可以给每个一个主节点添加从节点,主节点和从节点直接尊循主从模型的特性,当用户需要处理更多读请求的时候,添加从节点可以扩展系统的读性能
-
redis-cluster的故障转移:redis群集的主机节点内置了类似redissentinel的节点故障检测和自动故障转移功能,当群集中的某个主节点下线时,群集中的其他在线主节点会注意到这一点,并且对已经下线的主节点进行故障转移集群进行故障转移的方法和redis sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以群集不必另外使用redis sentinel
主节点负责读写请求和集群信息的维护,从节点只进行主节点数据和状态信息的复制
1. 数据分区
数据分区(或称数据分片)是集群最核心的功能:
- 集群将数据分散到多个节点,一方面突破了 Redis 单机内存大小的限制,存储容量大大增加,另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力
- Redis 单机内存大小受限问题,在介绍持久化和主从复制时都有提及
- 例如,如果单机内存太大,bgsave 和 bgrewriteaof 的 fork 操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出
2. 高可用
- 集群支持主从复制和主节点的自动故障转移(与哨兵类似),当任意节点发送故障时,集群仍然可以对外提供服务
3. 数据分片
Redis 集群引入了哈希槽的概念,有== 16384 个哈希槽(编号 0~16383)==
集群的每个节点负责一部分哈希槽,每个 Key 通过 CRC16 校验后对 16384 取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
以 3 个节点组成的集群为例:
- 节点 A 包含 0~5469 号的哈希槽
- 节点 B 包含 5461~10922 号的哈希槽
- 节点 C 包含 10923~16383 号的哈希槽
二、搭建Cluster集群
redis的集群一般需要6个节点,3主3从。这里使用的为虚拟机,个人性能不太够用。所以方便起见,这里所有节点在同一台服务器上模拟:
以端口号进行区分:3个主节点端口号:6001/6002/6003, 对应的从节点端口号:6004/ 6005/ 6006。
#回车,直到出现以下选项,手动修改为“/usr/local/redis/bin/redis-server”
Please select the redis executable path [/usr/local/bin/redis-server] /usr/local/redis/bin/redis-server
ln -s /usr/local/redis/bin/* /usr/local/bin/
#创建redis 6个端口的工作目录
cd /etc/redis/
mkdir -p redis-cluster/redis600{1..6}
vim /opt/redis.sh
#!/bin/bash
for i in {1..6}
do
cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i
cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis600$i
done
sh -x /opt/redis.sh
cd /etc/redis/redis-cluster/redis 6001
vim redis.conf
bind 127.0.0.1
#69行,注释掉bind项或不修改,默认监听所有网卡
protected-mode no
#88行,修改,关闭保护模式
port 6001
#92行,修改,redis监听端口,
daemonize yes
#136行,开启守护进程,以独立进程启动
cluster-enabled yes
#832行,取消注释,开启群集功能
cluster-config-file nodes-6001.conf
#840行,取消注释,群集名称文件设置
cluster-node-timeout 15000
#846行,取消注释群集超时时间设置
appendonly yes
#700行,修改,开启AOF持久化
其他5个配置文件除端口号外改动相同
cp redis.conf ../redis6002/
--->yes
#启动服务
cd /etc/redis/redis-cluster/redis6001
redis-server redis.conf
#根据对应配置文件启动redis
vim /opt/redis_start.sh
#!/bin/bash
for d in {1..6}
do
cd /etc/redis/redis-cluster/redis600$d
redis-server redis.conf
done
ps -ef | grep redis
sh -x /opt/redis_start.sh
加入集群
redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1
#六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点
#下面交互的时候需要输入 yes 才可以创建
#-replicas 1 表示每个主节点有一个从节点
测试群集
redis-cli -p 6001 -c #加-c参数,节点之,间就可以互相跳转
127.0.0.1:6001> cluster slots #查看节点的哈希槽编号范围
1) 1) (integer) 5461
2) (integer) 10922 #哈希槽编号范围
3) 1) "127.0.0.1"
2) (integer) 6003 #主节点IP和端口号
3) " fdca661922216dd69a63a7c9d3c4540cd6baef44"
4) 1) "127.0.0.1"
2) (integer) 6004 #从节点IP和端口号
3) " a2c0c32aff0f38980accd2b63d6d952812e44740"
2) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 6001
3) "0e5873747a2e26bdc935bc76c2bafb19d0a54b11"
4) 1) "127.0.0.1"
2) (integer) 6006
3) "8842ef5584a85005e135fd0ee59e5a0d67b0cf8e"
3) 1) (integer) 10923
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 6002
3) "81 6ddaa3d1469540b2ffbcaaf9aa867646846b30"
4) 1) "127.0.0.1"
2) (integer) 6005
3) " f847077bfe6722466e96178ae8cbb09dc8b4d5eb"
127.0.0.1:6001> set name zhangsan
-> Redi rected to slot [5798] located at 127.0.0.1:6003
OK
127.0.0.1:6001> cluster keyslot name #查看name键的槽编号
127.0.0.1:6001> cluster slots
1) 1) (integer) 10923
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 6003
3) "f466e92c2487cea57aeca1ac74065e976f23bf0e"
4) 1) "127.0.0.1"
2) (integer) 6004
3) "451dda82fd262ad6f3eaca5d39a4847b7c2b635c"
2) 1) (integer) 5461
2) (integer) 10922
3) 1) "127.0.0.1"
2) (integer) 6002
3) "1cbb5bdda47f98adb4193da8cc7b801ef76ac08e"
4) 1) "127.0.0.1"
2) (integer) 6006
3) "fb71c49ba37aa0e2495160b6979d8c79b56f123f"
3) 1) (integer) 0
2) (integer) 5460
3) 1) "127.0.0.1"
2) (integer) 6001
3) "7696a844322b9a2c8d23125228afd25097885546"
4) 1) "127.0.0.1"
2) (integer) 6005
3) "87412db1a80e4f8064205efdb581d34e0af80c2e"
127.0.0.1:6001> set name lisi
-> Redirected to slot [5798] located at 127.0.0.1:6002
OK
127.0.0.1:6002> cluster keyslot name
(integer) 5798