一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的,原因如下:
1、从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大; (容错性)
2、从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内容容量为256G,也不能将所有内容用作Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G。
高可用
“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。
高并发
高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求。
Redis主从复制
1、简介
一个Redis服务可以有多个该服务的复制品,这个Redis服务称为Master,其它复制称为Slaves
如图中所示,我们将一台Redis服务器作主库(Matser),其他三台作为从库(Slave),主库只负责写数据,每次有数据更新都将更新的数据同步到它所有的从库,而从库只负责读数据。
在Redis主从模式中,一台主库可以拥有多个从库,但是一个从库只能隶属于一个主库
2、使用场景
电子商务网站上的商品,一般都是一次上传,无数次浏览的,也就是”多读少写
”。
3、优缺点
优点:
这样一来,就有了两个好处:
1. 读写分离,不仅可以提高服务器的负载能力,并且可以根据读请求的规模自由增加或者减少从库的数量。
2. 数据被复制成了了好几份,就算有一台机器出现故障,也可以使用其他机器的数据快速恢复。
3. 写到master数据,当同步到slave时,非阻塞。
缺点:
数据复制的延迟;
读到过期的数据;
当master宕机,那这个主从复制就不能使用了;
针对master宕机之后的解决方案,那就是 Sentinel 哨兵模式
,一会儿介绍,现在配置好一主多从主从复制。
4、配置
在Redis中,要实现主从复制架构非常简单,Redis支持主从复制,
配置主从,有两种方式,一个是使用命令SLAVEOF 另一个是在redis配置文件配置 SLAVEOF,我这里使用的是执行命令的方式:(下面使用docker配置)使用redis版本是3.2
a.
运行三个Redis容器 ,名称分别为 redis-master、redis-slave1、redis-slave2
docker run -p 6380:6379 --name="redis-master" -v $PWD/data:/data -d redis:3.2 redis-server --appendonly yes
docker run -p 6381:6379 --name="redis-slave1" -v $PWD/data:/data -d redis:3.2 redis-server --appendonly yes
docker run -p 6382:6379 --name="redis-slave2" -v $PWD/data:/data -d redis:3.2 redis-server --appendonly yes
b.
使用SLAVEOF命令配置
1、查看redis-master ip (内部分配的ip)
很多方法如:
a、docker inspect 容器名称或id ip:172.17.0.7
# docker inspect redis-master
//多余省略
"Networks": {
"bridge": {
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.7"
}
}
b、exec进入容器查看 ip 172.17.0.7
]#docker exec -it redis-master bash
进入容器执行]#cat /etc/hosts
172.17.0.7 11f26b309931
2、配置从redis(使用slaveof命令)
]# docker exec -it redis-slave1 redis-cli
直接执行redis命令
127.0.0.1:6379> SLAVEOF 172.17.0.7 6379
redis-slave1就配置成redis-master的从服务了
redis-slave2同理.
3、测试
分别连接这三个redis服务中
#docker exec -it redis-master redis-cli
#docker exec -it redis-slave1 redis-cli
#docker exec -it redis-slave2 redis-cli
在redis-master中执行命令
redis-master:6379>set sunday 66666
分别在redis-slave1、redis-slave2中执行
redis-slave:6379>get sunday //就行获取到“66666”说明我们已经配置好了最基础的主从复制,实现了redis的高可用。
如果在redis-slave1、redis-slave2执行set命令是不允许的,默认情况从只能执行读操作。
一主多从的哨兵模式
针对主节点故障之后,我们使用哨兵模式(Sentinel)来监测节点,哨兵顾名思义,就是不断的在监测这些节点,如果故障,就需要他来做一些事情,将故障自动溢出,使redis正常使用。
1、简介
Redis Sentinel是Redis官方的高可用性解决方案。尽可能的可以一直用
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器,
并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
当故障的原主节点修好之后,我们将他指定到新主服务器,使他成为新主服务器的节点。
2、场景
一般
3、配置
我们在上面已经搭建好了一主多从,并且主节点是IP是172.17.0.7,我们就在上面的基础上搭建哨兵模式(sentinel),搭建Sentinel集群,搭建Sentinel不需要重新下载任何东西,Sentinel是在redis启动的另一种模式,我们直接sentinel.cnf 启动就可以了。
- 创建文件夹 mkdir redis-sentinel
- 创建三个sentinel配置文件分别为
sentinel-26380.conf sentinel-26381.conf sentinel-26382.conf
sentinel-26380.conf
port 26380
dir /tmp
#当前Sentinel节点监控 172.17.0.7:6379 这个主节点
#2代表判断主节点失败至少需要2个Sentinel节点节点同意
#mymaster是主节点的别名
sentinel monitor mymaster 172.17.0.7 6379 2
#每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达,
#原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为1
sentinel down-after-milliseconds mymaster 30000
//当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
sentinel parallel-syncs mymaster 1
//故障转移超时时间为180000毫秒
sentinel failover-timeout mymaster 180000
sentinel-26381.conf
port 26381
dir /tmp
sentinel monitor mymaster 172.17.0.7 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel-26382.conf
port 26382
dir /tmp
sentinel monitor mymaster 172.17.0.7 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
- 启动
docker run -p 26380:26380 -v /root/redis-sentinel/:/data --name sentinel-0 -d redis:3.2 redis-sentinel sentinel-26380.conf
docker run -p 26381:26381 -v /root/redis-sentinel/:/data --name sentinel-1 -d redis:3.2 redis-sentinel sentinel-26381.conf
docker run -p 26382:26382 -v /root/redis-sentinel/:/data --name sentinel-2 -d redis:3.2 redis-sentinel sentinel-26382.conf
redis-sentinel 为启动的模式。sentinel模式,
4. 检测验证
docker exec -it sentinel-0 redis-cli -p 26380
我们可以看到sentinel在见此主节点,并且状态ok ,有三个sentinels
此时我们关闭主节点容器,
docker stop redis-master
过一段时间之后我们查看主节点状态,主节点的地址换位了172.17.0.8
重启redis-master之后,redis-master成为了redis-slave1
节点。功能都正常使用。
docker start redis-master
现在我们完成了redis的高可用性。当主节点出现问题时,我们可以用哨兵模式,来使redis正常使用。然而,在高并发的情况下,还是会出现数据复制的延迟,读到过期的数据的问题。如何解决这个问题????
Redis Cluster集群
1、简介
从redis 3.0之后版本支持redis-cluster集群,至少需要3(Master)+3(Slave)才能建立集群 (相当于6台机器或运行6个服务)
。Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。其redis-cluster架构图:
2、使用场景
3、特点
- 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽
节点的fail
是通过集群中超过半数
的节点检测失效时才生效,所以有很高的可用性。- 客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
- redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护
- Redis集群预分好16384个哈希槽,当需要在 Redis 集群中放置一个 key-value 时, redis 先对key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节
4、配置
这次使用的比较新的 redis版本5.0.4
a、 wget http://download.redis.io/releases/redis-5.0.7.tar.gz
b、tar xzf redis-5.0.7.tar.gz
c、创建配置文件,因为最少需要6个节点所以创建有个文件夹,以端口号命名
mkdir 7031 7032 7033 7034 7034 7035 7036
将reids.conf放入这几个文件中
并分别编辑redis.conf文件
1、如果外部访问:redis.conf中设置保护模式为 protected-mode no
2、port 7031 # 绑定端口,
3、bind 192.168.0.179 # 绑定服务端IP
4、dir /usr/local/redis-cluster/7031 指定数据存放路径,以端口号来区分
5、cluster-enabled yes # 启动集群模式,
6、cluster-config-file nodes-7031.conf # 指定集群节点配置文件,以端口号来区分
7、daemonize yes # 后台启动,
8、cluster-node-timeout 5000 # 指定集群节点超时时间
9、appendonly yes #启动AOF增量持久化策略
10、pidfile # var/run/redis-7031.pid #修改进程文件名,以端口号来区分
d、配置好,启动节点
在这里我们下载的redis 是源码需要编译,首先需要安装gcc
yum install gcc
安装后进入redis 根目录,运行make,之后在src文件看见redis-server
redis-server ../../7031/redis.conf
redis-server ../../7032/redis.conf
redis-server ../../7033/redis.conf
redis-server ../../7034/redis.conf
redis-server ../../7035/redis.conf
redis-server ../../7036/redis.conf
查看是否运行 ps -ef|grep redis
e、安装ruby
# yum -y install ruby ruby-devel rubygems rpm-build
# gem install redis
f、创建集群
[root@linux src]# sudo ./redis-cli --cluster create 192.168.0.179:7031 192.168.0.179:7032 192.168.0.179:7033 192.168.0.179:7034 192.168.0.179:7035 192.168.0.179:7036 --cluster-replicas 1
--replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。(--cluster-replicas 1 命令的意思: 一主一从配置,六个节点就是 三主三从)
这个就是Redis集群预分好16384个哈希槽。
5、测试验证
连接集群
redis-cli -h 127.0.0.1 -c -p 7031
加参数 -C 可连接到集群,因为上面 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略。
[root@ecs-t6-large-2-linux-20191024085655 redis-5.0.4]# redis-cli -h 192.168.0.179 -c -p 7031
查看下面图:
- 每个Redis的节点都有一个ID值,此ID将被此特定redis实例永久使用,以便实例在集群上下文中具有唯一的名称。 每个节点都会记住使用此ID的每个其他节点,而不是通过IP或端口。IP地址和端口可能会发生变化,但唯一的节点标识符在节点的整个生命周期内都不会改变。 我们简单地称这个标识符为节点ID。
鸣谢
- https://www.jianshu.com/p/ab9aaae8b7e8
- https://blog.csdn.net/weixin_43184769/article/details/89083713
- https://blog.csdn.net/weixin_43184769/article/details/90580474
- https://www.bilibili.com/video/av49517046?from=search&seid=10799782498192513173
等等 找不到来链接了~~~~~