博文大纲:
1、Redis群集相关概念
2、部署Redis群集node
- 一、部署环境
- 二、配置Redis实例
- 三、配置node06主机的多Redis实例
- 四、主机node01安装配置ruby的运行环境,便于管理Redis群集
- 五、配置群集中的各个节点
- 六、使用ruby安装的命令管理Redis群集
- 七、将node06的6380实例添加节点到Redis群集中
- 八、为新加入的master分配从节点
- 九、删除主节点操做
Redis是从3.0版本开始支持cluter的,采用的是hash槽方式,能够将多个Redis实例整合在一块儿,造成一个群集,也就是将数据分散存储到群集中的多个节点上。redis
Redis的cluster是一个无中心的结构,在群集中,每一个master的身份是平等的,每一个节点都保存数据和整个群集的状态,而且知道其余节点所负责的槽,也会定时发送心跳信息,可以及时感知群集中异常的节点,而且采起投票的方式来决定该节点是否为不可用,若票数为群集中节点的半数以上,则认为该节点不可用,也正是由于此特色,因此要部署Redis群集,节点数量最少要三个及以上。shell
群集角色有master和slave,master之间分配slots(槽),槽点编号是0-16383(共16384个)。数据库
默认状况下,每一个群集节点有两个TCP端口在监听,一个是6379(用于监听客户端的访问链接),另外一个是16379(用于群集之间的节点通讯)。注意,防火墙须要放行这两个端口的流量。vim
Redis的全部数据都是保存在内存中,而后不按期的经过异步方式保存到磁盘上(这称为“半持久化模式”);也能够把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。 centos
Redis提供的这两种方式进行持久化,一种是RDB持久化(原理是将Redis在内存中的数据库定时记录dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Redis的操做日志以追加的方式写入文件)安全
RDB的优势与缺点ruby
RDB半持久化的优势:服务器
- 只包含一个文件,有利于文件备份;
- 灾难恢复比aof持久化要快;
- 性能最大化。对于Redis的服务进程而言,在开始持久化时,它惟一须要作的只是fork出子进程,以后再由子进程完成这些持久化的工做,这样就能够极大的避免服务进程执行IO操做了。
- 相比较AOF机制,若是数据集过大,RDB的启动效率会更高。
RDB半持久化的缺点:- 因为RDB是经过fork子进程来协助完成数据持久化工做的,所以,若是当数据集比较大时,可能会致使整个服务中止几百毫秒,甚至是1秒钟。
AOF的优势与缺点app
AOF全持久化的优势:
- 能够保证数据的高可用性;
- 写入过程当中及时出现宕机现象,也不会破坏日志文件中已经存在的内容,若是在写入过程当中宕机,重启Redis后能够经过redis-check-aof工具来解决;
- 若是日志过大,Redis能够自动启用rewrite机制,生成新的文件存储aof日志;
- 该机制能够带来更高的数据安全性,及数据持久性。Redis中提供了三种同步策略,即每秒同步、每修改同步和不一样步。
AOF全持久化的缺点:- 对于相同数量的数据集而言,AOF文件一般要大于RDB文件。RDB在恢复大数据集时的速度比AOF的恢复速度要快;
- 根据同步策略的不一样,AOF在运行效率上每每会慢于RDM,总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB同样高效。
若是RDB和AOF同时存在,则优先选择AOF方式。
上面共六台centos服务器,实现三台master分别对应一台slave(也能够在一台服务器上配置多个Redis实例,但不要master-slave在同一台物理服务器,可使用交叉master-slave的方式进行主从复制,所谓交叉就是master在node01,但对应的slave在node02,node02上master对应的slave在node03,而node03对应的slave在node01,这样作的好处是避免由于物理服务器的宕机而形成整个群集崩溃,这里只是稍微提示如下,自行研究便可)。
这里为了展现同一台主机上配置多个Redis实例,因此将在node06上配置多个Redis实例,其他节点各负责一个Redis实例便可。
在进行接下来的配置前,请先下载我提供的源码包(其实,这里部署的版本是Redis4.0的,版本还低了些,有些方便的配置没法进行,能够参考下我那篇部署Redis 5.0的博文)。
这里以node01的配置进行示例,其余节点照搬进行配置便可。
[root@node01 ~]# ls | grep redis #在xshell使用rz命令上传我提供的包,以下: redis-4.0.14.tar.gz [root@node01 ~]# tar zxf redis-4.0.14.tar.gz -C /usr/local/ #解包 [root@node01 ~]# cd /usr/local/ #切换至指定路径 [root@node01 local]# mv redis-4.0.14 redis #更改目录名称 [root@node01 local]# cd redis/ #切换至解压后的目录 [root@node01 redis]# make && make install #无需配置,直接编译安装便可 [root@node01 redis]# ./utils/install_server.sh #对Redis进行初始化 #初始化的全部选项保持默认,一路回车确认便可 #是在确认监听端口、配置文件、日志文件、pid存放路径等信息 .............#省略部份内容 Successfully added to chkconfig! Successfully added to runlevels 345! Starting Redis server... Installation successful! #出现上述内容,则表示初始化成功 #接下来进行一些优化,以下: [root@node01 redis]# echo "512" > /proc/sys/net/core/somaxconn [root@node01 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@node01 redis]# sysctl -p vm.overcommit_memory = 1 [root@node01 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled [root@node01 redis]# vim /etc/redis/6379.conf #编辑配置文件,修改以下 bind 0.0.0.0 #找到没有被注释的这一行,修改成0.0.0.0 daemonize yes #如有注释符号,须要删除注释符号,以便生效 cluster-enabled yes cluster-node-timeout 5000 appendonly yes #修改完成后,保存退出便可。 [root@node01 redis]# /etc/init.d/redis_6379 restart #重启Redis服务 [root@node01 redis]# netstat -anpt | grep redis #肯定端口6379及16379处于监听状态
在其余节点服务器上将上述配置依次进行以便,主机node06除外,由于稍后将在node06上展现单台主机多Redis实例的配置。
node06这个节点上,我将配置其运行多个Redis数据库实例,因此与前面五个节点的配置并非彻底同样,请谨慎配置。
[root@node06 ~]# tar zxf redis-4.0.14.tar.gz -C /usr/local/ [root@node06 ~]# cd /usr/local/ [root@node06 local]# mv redis-4.0.14 redis [root@node06 local]# cd redis/ [root@node06 redis]# make && make install #编译安装后,无需进行初始化 [root@node06 redis]# redis-server #启动查看须要优化的项 #在前面几个节点的优化配置就是今后命令执行后的提示信息得到的 #接下里就优化这些提示的配置咯! [root@node06 redis]# echo "512" > /proc/sys/net/core/somaxconn [root@node06 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf [root@node06 redis]# sysctl -p vm.overcommit_memory = 1 [root@node06 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled [root@node06 redis]# vim redis.conf #编辑当前目录下的模板配置文件如下几项 bind 0.0.0.0 port 6379 daemonize yes #开启后台守护进程,以便后台运行 cluster-enabled yes #开启群集 cluster-node-timeout 5000 #群集节点间的超时时间,单位是毫秒 appendonly yes #是否开启同步到磁盘 appendfilename "appendonly-6379.aof" #aof日志的名字 #编辑完成后,保存退出便可 [root@node06 redis]# mkdir -p /usr/local/redis-cluster/{6379..6382} #以上是打算运行几个Redis实例,就建立几个目录便可,这里我以实例的端口号给目录命名(暂时打算运行4个Redis实例) #如下是将修改后的配置文件复制到指定的目录下一份 [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6379/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6380/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6381/ [root@node06 redis]# cp redis.conf /usr/local/redis-cluster/6382/ #而后下面将复制过去的各个配置文件中改成与Redis实例对应的端口号 [root@node06 redis]# cd /usr/local/redis-cluster/ [root@node06 redis-cluster]# sed -i s/6379/6380/g 6380/redis.conf [root@node06 redis-cluster]# sed -i s/6379/6381/g 6381/redis.conf [root@node06 redis-cluster]# sed -i s/6379/6382/g 6382/redis.conf [root@node06 redis-cluster]# cd 6379 #切换到6379目录 [root@node06 6379]# redis-server redis.conf #启动该目录下的配置文件 101582:C 04 Nov 23:37:04.988 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 101582:C 04 Nov 23:37:04.988 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=101582, just started 101582:C 04 Nov 23:37:04.988 # Configuration loaded #接下来就是依次启动各个实例 [root@node06 6379]# cd ../6380 [root@node06 6380]# redis-server redis.conf [root@node06 6380]# cd ../6381 [root@node06 6381]# redis-server redis.conf [root@node06 6381]# cd ../6382 [root@node06 6382]# redis-server redis.conf [root@node06 6382]# netstat -anpt | grep redis #查看Redis相关端口的监听状况
上述查看Redis端口监听状况的返回信息以下:
[root@node01 ~]# yum -y install rpm-build openssl openssl-devel #安装依赖 [root@node01 ~]# ls | egrep "gem|ruby" #将下面的两个包上传至主机node01 redis-3.3.0.gem ruby-2.3.1.tar.gz [root@node01 ~]# tar zxf ruby-2.3.1.tar.gz -C /usr/src #解包 [root@node01 ~]# cd /usr/src/ruby-2.3.1/ #进入解压后的目录 [root@node01 ruby-2.3.1]# ./configure --prefix=/usr/local/ruby && make && make install #编译安装,时间较长 #下面是对生成的命令作软链接 [root@node01 ruby-2.3.1]# ln -sf /usr/local/ruby/bin/* /usr/local/bin/ [root@node01 ruby-2.3.1]# ln -sf /usr/local/redis/src/redis-trib.rb /usr/local/bin/ [root@node01 ruby-2.3.1]# cd #回到 .gem文件所在目录 [root@node01 ~]# gem install redis-3.3.0.gem #执行此命令 Successfully installed redis-3.3.0 Parsing documentation for redis-3.3.0 Installing ri documentation for redis-3.3.0 Done installing documentation for redis after 0 seconds 1 gem installed #返回上述信息则表示成功
[root@node01 ~]# redis-cli -p 6379 #登陆到本地Redis实例 #如下是将参与群集的各个节点添加到群集中 127.0.0.1:6379> CLUSTER MEET 192.168.20.3 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.4 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.5 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.6 6379 OK 127.0.0.1:6379> CLUSTER MEET 192.168.20.7 6379 OK 127.0.0.1:6379> set a b #虽然节点添加完成,可是因为没有分配hash槽,因此没法添加数据 (error) CLUSTERDOWN Hash slot not served 127.0.0.1:6379> CLUSTER INFO #查看群集的状态 cluster_state:fail #是失败的 192.168.20.3:6379> exit #接下来为群集中的节点分配槽点 #必须当心分配,一旦分配错误,很麻烦 #虽然能够将命令中的“add”换为“del”,可是我没有成功 #必定要将0至16383彻底分配出去,最好是等份分配 #只需给做为master的节点分配便可,我这里node01至node03为master [root@node01 ~]# redis-cli -h 192.168.20.2 -p 6379 cluster addslots {0..5461} OK [root@node01 ~]# redis-cli -h 192.168.20.3 -p 6379 cluster addslots {5462..10922} OK [root@node01 ~]# redis-cli -h 192.168.20.4 -p 6379 cluster addslots {10923..16383} OK [root@node01 ~]# redis-cli -p 6379 -c #进入群集,须要加“-c”选项 127.0.0.1:6379> CLUSTER NODES #查看群集中的节点信息 #接下来是将各个slave从节点与master进行绑定 #node04做为node01的从节点,node05做为node02的从节点,node06的6379实例做为node03的从节点 #须要配置哪一个从节点,就须要登陆到哪一个实例 127.0.0.1:6379> CLUSTER NODES #能够先执行此命令,查看相应节点的ID,以便接下来指定 [root@node01 ~]# redis-cli -h 192.168.20.5 -p 6379 #登陆到node04 192.168.20.5:6379> CLUSTER REPLICATE 5cd3d0eec161a7bcc785202397fd8363074ae9c2 #上面指定的是node01节点的ID OK 192.168.20.5:6379> exit #退出实例 [root@node01 ~]# redis-cli -h 192.168.20.6 -p 6379 #登陆到node05 192.168.20.6:6379> CLUSTER REPLICATE e2de936c380eb2239f0a349dcbfba5daa74fa1d7 #上述指定的是node02的节点ID OK 192.168.20.6:6379> exit #退出实例 [root@node01 ~]# redis-cli -h 192.168.20.7 -p 6379 #登陆到node06的6379实例 192.168.20.7:6379> CLUSTER REPLICATE dd03b02213df3a91608d1f4ae8080c37f4790d7c #上述是指定node03的节点ID OK 192.168.20.7:6379> exit
配置至此,可再次查看群集的节点信息,会发现主从之间都对应上了,以下:
至此,群集便可正常读写数据了,以下:
[root@node01 ~]# redis-cli -h 192.168.20.2 -p 6379 -c #登陆到群集 192.168.20.2:6379> set b c OK
[root@node01 ~]# redis-trib.rb check 127.0.0.1:6379 #检查群集的状态
上述命令返回的信息以下:
[root@node01 ~]# redis-trib.rb add-node 192.168.20.7:6380 192.168.20.2:6379 #在添加节点时,不添加其余配置,默认加入群集后,角色是master
返回的提示信息以下则表示成功:
因为一个群集若要正常运行,必须将全部的槽点分配出去,因此当有新的节点加入后,须要从新给新加入的节点分配槽点,以下:
[root@node01 ~]# redis-trib.rb check 127.0.0.1:6379 #执行此命令进行确认新加入的节点时master [root@node01 ~]# redis-trib.rb reshard 192.168.20.2:6379 #指定群集地址及端口 How many slots do you want to move (from 1 to 16384)? 4096 #如果四个master,那么平均值为4096,因此这里输入4096 What is the receiving node ID? 010752fb2527317a938fcb5b4e73822db805b3a1 #指定接收的节点,也就是新加入的node06主机上6380的那个实例的ID Source node #1:all #指定从哪一个节点的槽点分配,这里输入“all”选择全部节点 Do you want to proceed with the proposed reshard plan (yes/no)? yes #输入“yes”进行确认
至此,新的节点就添加完成了,而且分配了相应的槽点,可是...尚未从节点,因此接下来为新加入的master分配一个从节点。
分配从节点的方式有两种,一种是不指定为哪一个master的从节点,自动绑定到没有从节点的master上,一种是直接指定绑定到哪一个master上,这里将这两种方式都写下来。
#方式一: [root@node01 ~]# redis-trib.rb add-node --slave 192.168.20.7:6381 192.168.20.7:6380 #将node06上的6381实例以slave的身份加入到群集 #注意,返回的信息不可有红色字样,那就说明有错误 [root@node01 ~]# redis-trib.rb check 192.168.20.2:6379 #查看确认新加入的slave是否与node06的6380master实例绑定 #方式二: [root@node01 ~]# redis-trib.rb add-node --slave --master-id 010752fb2527317a938fcb5b4e73822db805b3a1 192.168.20.7:6382 192.168.20.2:6380 #上述命令指定的ID就是6380实例的master的ID,直接指定为6380的slave节点 [root@node01 ~]# redis-trib.rb check 192.168.20.2:6379 #查看群集状态,能够看到master6380有两个slave了,都是上面新加入的slave
删除主节点的操做其实就是把添加主节点的操做反了过了,须要先将要删除的主节点上的槽点分配给其余master,而后才能够执行删除操做,而且删除主节点后,该master对应的slave也将会随着slots槽进行转移到新的master上。
这里以移除node06上的6380实例为例。
#移除6380实例上的槽点 [root@node01 ~]# redis-trib.rb reshard 192.168.20.2:6379 #指定群集监听地址 How many slots do you want to move (from 1 to 16384)? 4096 #输入要删除多少槽 What is the receiving node ID? 5cd3d0eec161a7bcc785202397fd8363074ae9c2 #这里指定的是删除主节点后,主节点上的槽分配给谁?这里写了node02的6379实例的ID Source node #1:010752fb2527317a938fcb5b4e73822db805b3a1 #这里指定的是要删除哪一个主节点?指定的ID是node06上6380实例的ID Source node #2:done #输入done表示结束 Do you want to proceed with the proposed reshard plan (yes/no)? yes #输入“yes”表示确认 #移除槽点后,接下来将6380实例从群集中移除,以下: [root@node01 ~]# redis-trib.rb del-node 192.168.20.2:6379 010752fb2527317a938fcb5b4e73822db805b3a1 #上面指定的是6380实例的ID
至此,6380实例就被完全移除群集了,而且本来与之对应的slave也随着槽点转移到node02也一块儿成为了node02的slave。如今查看群集信息,node02的master应该是对应了三个slave。
———————— 本文至此结束,感谢阅读 ————————