持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
一、集群
1、必要性
1、单个redis存在不稳定性。当redis服务宕机了,就没有可用的服务了
2、单个redis的读写能力是有限的。
总结:redis集群是为了强化redis的读写能力。
2、说明
1、redis集群中,每一个redis称之为一个节点。
2、redis集群中,有两种类型的节点:主节点(master)、从节点(slave)。
3、redis集群,是基于redis主从复制实现。
3、主从复制
主从复制模型中,有多个redis节点。 其中,有且仅有一个为主节点Master。从节点Slave可以有多个。
只要网络连接正常,Master会一直将自己的数据更新同步给Slaves,保持主从同步。
1)、特点
1、主节点Master可读、可写.
2、从节点Slave只读。(read-only)
主从模型可以提高读的能力,在一定程度上缓解了写的能力。因为能写仍然只有Master节点一个,可以将读的操作全部移交到从节点上,变相提高了写能力。
2)、配置
主节点不需要修改, 从节点修改slaveof,后面改为主节点的ip和端口
3)、缺点
当主节点宕机了,整个集群就没有可写的节点了
4)、实现方式
1、slaveof命令,如:slaveof xxxx:6379,表示将xxxx:6379设置成当前实例的主节点
slaveof no one命令表示当前服务取消当从节点
不需要重启,但是不便于管理
2、配置
slaveof ip port
slave-read-only yes
统一配置,需要重启
查看偏移量:info replication命令
如果主节点master_repl_offset和从节点的offset相差太多,表示复制可以存在问题
5)、全量同步
- slave内部首先会发送一个psync的命令给master 这个命令第一个参数是runId,第二个参数是偏移量,而由于是第一次复制,slave不知道master的runId,也不知道自己偏移量,这时候会传一个问号和-1,告诉master节点是第一次同步。
- 当master接受到psync ? -1 时,就知道slave是要全量复制,就会将自己的runID和offset告知slave
- slave会将master信息保存
- master这时会做一个RDB的生成(bgsave)
- 将RDB发送给slave
- 将复制缓冲区记录的操作也发送给slave
- slave清空自己的所有老数据
- slave这时就会加载RDB文件以及复制缓冲区数据,完成同步。
全量复制开销
1.bgsave的开销,每次bgsave需要fork子进程,对内存和CPU的开销很大
2.RDB文件网络传输的时间(网络带宽)
3.从节点清空数据的时间
4.从节点加载RDB的时间
5.可能的AOF重写时间(如果我们的从节点开启了AOF,则加载完RDB后会对AOF进行一个重写,保证AOF是最新的)
6)、部分复制
部分复制是 Redis 2.8 以后出现的,之所以要加入部分复制,是因为全量复制会产生很多问题,比如像上面的时间开销大、无法隔离等问题, Redis 希望能够在 master 出现抖动(相当于断开连接)的时候,可以有一些机制将复制的损失降低到最低
1、如果网络抖动(连接断开 connection lost) 2、主机master 还是会写 replbackbuffer(复制缓冲区) 3、从机slave 会继续尝试连接主机 4、从机slave 会把自己当前 runid 和偏移量传输给主机 master,并且执行 pysnc 命令同步 5、如果 master 发现你的偏移量是在缓冲区的范围内,就会返回 continue 命令 同步了 offset 的部分数据,所以部分复制的基础就是偏移量 offset。
注意: 正常情况下redis是如何决定是全量复制还是部分复制? 从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定能否执行部分复制: 1.如果offset偏移量之后的数据,仍然都在复制积压缓冲区里,则执行部分复制; 2.如果offset偏移量之后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制。
7)、主从复制常见问题
1、读写分离:读流量分摊到从节点
可能遇到的问题:复制数据延迟、读到过期数据、从节点故障
2、主从配置不一致
如maxmemory不一致:丢失数据
如数据结构优化参数(hash-max-ziplist-entries):内存不一致
3、规避全量复制
第一次全量复制不可避免;小主节点;低峰如:夜间访问量低时
节点运行ID不匹配:如一主一从配置,主节点重启(运行id变化);故障转移如:哨兵和集群
复制积压缓冲区不足,网络中断,部分复制无法满足;解决:增大复制缓冲区配置rel_backlog_size,网络增强
4、规避复制风暴
单主节点复制风暴:主节点重启,多从节点复制;解决:更换复制拓扑
单机器复制风暴:机器宕机重启,多主节点造成大量全量复制;解决:主节点分散多机器
4、Sentine哨兵模式
在主节点宕机的情况下,能够将从节点变成一个主节点
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
监控(Monitoring) : Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification) : 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知
自动故障迁移(Automatic failover) : 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会进行选举,将其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
1)、监控
Sentinel可以监控任意多个Master和该Master下的Slaves。(即多个主从模式)
同一个哨兵下的、不同主从模型,彼此之间相互独立。
Sentinel会不断检查Master和Slaves是否正常。
2)、自动故障切换(Automatic failover)
监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监视服务器的信息
疑问:为什么要使用sentinel网络呢?
答:当只有一个sentinel的时候,如果这个sentinel挂掉了,那么就无法实现自动故障切换了。
故障切换的过程
1、投票 (半数原则) :当任何一个Sentinel发现被监控的Master下线时,会通知其它的Sentinel开会,投票确定该Master是否下线(半数以上,所以sentinel通常配奇数个)。
2、选举 :当Sentinel确定Master下线后,会在所有的Slaves中,选举一个新的节点,升级成Master节点。其它Slaves节点,转为该节点的从节点。
3、原Master重新上线 :当原Master节点重新上线后,自动转为当前Master节点的从节点
3)、部署
前提:已经存在一个正在运行的主从模式。
另外,配置三个Sentinel实例,监控同一个Master节点
没搭建过。。。。跳过
5、Cluster模式
官方提供的分布式解决方案
是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能
Redis的数据是根据一定规则分配到cluster的不同机器,当数据量过大时,可以新增机器进行扩容。
每个集群中至少需要三个主数据库才能正常运行,所以redis集群至少需要一个备份节点,才能更好的保证集群的高可用
1)、分区和槽slot
redis cluster中有一个16384(2^4 * 2^10)长度的槽的概念。通过哈希算法再加上取模运算可以将一个值固定地映射到某个区间,区间由连续的slot组成。
redis cluster采用虚拟槽分区,所有的键根据哈希函数(CRC16[key]&16383)映射到0-16383槽内,共16384个槽位,每个节点维护部分槽及槽所映射的键值数据
哈希函数: Hash()=CRC16[key]&16383 按位与
redis用虚拟槽分区原因:解耦数据与节点关系,节点自身维护槽映射关系,分布式存储
2)、特点
多个redis节点网络互联,数据共享
所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用
不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上, 并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
支持在线增加、删除节点
客户端可以连接任何一个主节点进行读写
二、搭建redis集群Cluster(window)
1、解压安装包并赋值6份
2、修改各个redis的配置文件redis.windows.conf
bind 10.9.14.82 //服务器ip地址
port 6381 //端口6381--6386
cluster-enabled yes //打开集群
cluster-config-file nodes-6381.conf //nodes-6381.conf---condes-6386.conf
cluster-node-timeout 15000 //请求超时
3、安装Ruby运行环境
下载dl.bintray.com/oneclick/ru… (rubyinstaller-2.3.3-x64.exe)
运行安装三个选择框都打勾
注意:系统变量里面 path 需要配置 ruby的安装目录bin
PATHEXT 需要配置 .RB;.RBW
4、安装Redis的Ruby驱动redis-xxxx.gem
下载rubygems.org/pages/downl… (rubygems-update-3.1.4.gem)
切换到安装目录执行命令:gem install redis
5、安装集群脚本redis-trib (redis-trib.rb)
下载连接不可用,网上找资源
保存到某个redis目录下
6、创建集群
注意:
1、创建集群前删除dump.rdb和nodes-xxx.conf文件
2、每个redis节点都不能有数据
3、密码和集群密码都不能设置,创建集群后可以改配置文件设置密码和集群密码
4、flushall清除数据库数据
// 创建命令
ruby redis-trib.rb create --replicas 1 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005
--replicas 1 表示每个主数据库拥有从数据库个数为1。master节点不能少于3个,所以我们用了6个redis
三、搭建redis集群Cluster(Linux)
1、安装redis
先编译安装一个redis,然后复制bin文件夹和配置文件
// 创建集群文件夹
mkdir /usr/local/redis-cluster
// 复制
cd /usr/local/redis
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis80
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis81
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis82
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis83
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis84
cp -r /usr/local/redis/bin /usr/local/redis-cluster/redis85
修改所有节点的配置文件
cd /usr/local/redis-cluster/redis80
vi redis.conf
#bind 127.0.0.1 远程访问注释掉 如果跨服务器则不能注释,填服务器ip
设置protected-mode 为 no
设置daemonize 为yes // 后台运行
#requirepass xxx 密码先注释掉,集群搭建成功再设置
#masterauth xxx 集群密码先注释掉,集群搭建成功再设置
设置cluster-enabled 为yes
cluster-config-file 放开注释
2、设置一键启动所有节点
cd /usr/local/redis-cluster
// 创建脚本文件
vi start-all.sh
cd redis80
./bin/redis-server redis.conf
cd ..
cd redis81
./bin/redis-server redis.conf
cd ..
cd redis82
./bin/redis-server redis.conf
cd ..
cd redis83
./bin/redis-server redis.conf
cd ..
cd redis84
./bin/redis-server redis.conf
cd ..
cd redis85
./bin/redis-server redis.conf
cd ..
// 修改脚本文件权限
chmod +x start-all.sh
// 一键启动
cd /usr/local/redis-cluster
./start-all.sh
3、安装ruby
注意:不要在线安装,在线安装的版本太低,推荐离线安装,去官网下载安装包
// 上传安装包ruby-2.3.8.tar.gz解压
cd /usr/local/redis-cluster/ruby-2.3.8
// 编译安装-prefix是将ruby安装到指定目录,也可以自定义 (过程几分钟)
./configure –-prefix=/usr/local/redis-cluster/ruby
make && make install
// 验证是否安装成功
./ruby -v
// 设置环境变量
vi /etc/profile
export PATH=/usr/local/redis-cluster/ruby/bin:$PATH
// 保存退出执行
source /etc/profile
4、安装ruby驱动
cd /usr/local/redis-cluster
// 上传文件rubygems-update-3.1.4.gem
// 运行
gem install rubygems-update-3.1.4.gem
5、创建集群
在redis的安装文件src里的redis-cli文件复制到集群目录
cd /redis-5.0.4/src
cp redis-cli /usr/local/redis-cluster
cd /usr/local/redis-cluster
./redis-cli --cluster create --cluster-replicas 1 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005
// 连接某个节点
./redis-cli -p 9000 -c
// 查看集群信息
cluster info
// 查看集群连接信息
cluster nodes
// 修改密码,所有节点都修改
cd /usr/local/redis-cluster/redisxx
vi redis.conf
requirepass xxx
masterauth xxx
// 全部修改完,关闭当前集群所有节点
pa aux | grep redis
kill -9 进程号
// 一键启动所有节点
cd /usr/local/redis-cluster/
./start-all.sh