一、应用场景介绍
本文主要是介绍Redis集群在Linux环境下的安装讲解,联网环境安装较为简单,这里只说脱机的Linux环境下是如何安装的。因为大多数时候,公司的生产环境是在内网环境下,无外网,服务器处于脱机状态。
二、安装环境及工具
系统:CentOS7
工具:XShell5及Xftp5
安装包:
Ruby-2.4.2
Rubygems-2.6.14
Redis-4.0.2(3.x版本才开始支持集群功能)
openssl-1.1.0f
三、安装步骤
要搭建一个最简单的Redis集群,我们至少需要6个节点:3个Master和3个Slave。那为什么需要3个Master呢?其实就是一个“铁三角”的关系,当1个Master下线的时候,其他2个Master和对应的Salve立马就能顶替上去,确保集群能够正常使用,如果你之前了解Mongodb/Hadoop/Strom这些的话,你就很容易目标一般分布式的最低要求基数个数节点,这样便于选举(少数服从多数的原则)。本文当中,我们就偷下懒,在一台Linux虚拟机上搭建6个节点的Redis集群(实际真正生产环境,需要3台Linux服务器分布存放3个Master)
实际上,Redis集群的操作在后文你可以看到是通过Ruby脚本来完成的,因此我们需要安装Ruby相关的RPM包,以及Redis和Ruby的接口包。
1、Ruby离线安装
一、Ruby简介
Ruby是一种纯粹的面向对象编程语言。它由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)创建于1993年。
您可以在 www.ruby-lang.org 的 Ruby 邮件列表上找到松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)的名字。在 Ruby 社区,松本也被称为马茨(Matz)。Ruby 是"程序员的最佳朋友"。
Ruby 的特性与 Smalltalk、Perl 和 Python 类似。Perl、Python 和 Smalltalk 是脚本语言。Smalltalk 是一个真正的面向对象语言。Ruby,与 Smalltalk 一样,是一个完美的面向对象语言。使用 Ruby 的语法比使用 Smalltalk 的语法要容易得多。
二、Ruby离线安装
去官网下载:http://www.ruby-lang.org/en/downloads/ 最新的版本为2.4.2
在安装之前,请确保你Root权限,将下载的Ruby安装包上传到服务器当中,使用Xftp可以很方便的将文件传入到linux服务器上。
使用命令# tar -zxvf ruby-2.4.2.tar.gz解压当前文件包,使用# cd ruby-2.4.2转到当前目录,
使用命令# ./configure --prefix=/usr/local/ruby --prefix是将ruby安装到指定目录,也可以自定义。出现如下界面代表已经配置完成了。
然后使用# make && make install 打包编译,时间较长,稍等片刻,打包完成后输入 #ruby –v如果出现ruby的版本号则代表安装成功。如果出现如下的情况,则先跳过执行第三步。
三、配置Ruby环境变量
使用命令# which ruby
如果出现上图所示则代表没有配置环境变量。输入命令# vim /etc/profile,然后按下I键进入编辑模式,在文件最后加上 export PATH=/usr/local/ruby/bin:$PATH
如果已存在PATH则在最后加入 :/usr/local/ruby/bin 。
保存退出就可以了(按ESC键,然后输入:wq保存退出) 最后需要执行命令# source /etc/profile 才能立即生效,此时再使用# which ruby则会出现对应的信息。安装成功!
2、离线安装RubyGems
一、RubyGems简介
RubyGems 是 Ruby 的一个包管理器,它提供一个分发 Ruby 程序和库的标准格式,还提供一个管理程序包安装的工具。
RubyGems 旨在方便地管理 gem 安装的工具,以及用于分发 gem 的服务器。这类似于 Ubuntu 下的apt-get, Centos 的 yum,Python 的 pip。
RubyGems大约创建于2003年11月,从Ruby 1.9版起成为Ruby标准库的一部分。
二、RubyGems离线安装
首先下载安装包:https://rubygems.org/pages/download。使用Xftp将对应压缩包放入到/usr/local/src
解压# tar -zxvf rubygems-2.6.14.tgz
进入对应目录# cd rubygems-2.6.14
然后使用命令# ruby setup.rb 当出现Rubygems-2.6.14 installed时,表示已经成功安装,
使用命令# gem update –system更新 RubyGems。
三、RubyGems环境变量配置
使用命令# which gem 查看环境变量是否存在。
如不存在则需配置环境变量,存在则不需要配置。
输入命令# vim /etc/profile 如上面所说的配置Ruby的环境变量的操作一样,将路径写入PATH中,保存即可。最后需要执行命令:source /etc/profile 才能立即生效。
3、安装Redis
一、Redis简介
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端,使用很方便。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis的官网地址,非常好记,是redis.io。(特意查了一下,域名后缀io属于国家域名,是british Indian Ocean territory,即英属印度洋领地)
目前,Vmware在资助着redis项目的开发和维护。
二、Redis离线安装
1、到官网(https://redis.io/download)下载Redis,现在最新的版本为:4.0.2 ,将下载好的压缩包使用Xftp上传到服务器当中。
如图所示,我是新建了一个Redis临时目录存放,偷懒我就用xftp5手动创建一个目录存放(也可以写命令创建文件夹 $ makdir redis)
使用#cd /usr/local/src/redis命令转到压缩包所在路径,使用解压命令# tar -zxvf redis-4.0.2.tar.gz。
进入解压后的redis的目录,
使用make命令进行安装 #make && make install //make 这里如果不指定PREFIX,默认将安装在/usr/local/bin下,保持默认就好。出现如下界面表示已经安装成功了。
安装完成后 在redis的解压目录中使用命令# redis-server redis.conf 即可启动redis,因为我们需要配置集群版本的redis ,这里我们先使用Ctrl + C 退出redis。
三、配置Redis集群
刚刚上面讲到如果只是想运行单机版的Redis(个人研究Redis可以安装单机版),上面的讲解已经够了,不过现实当中,我们往往是需要使用到集群功能的,进行容错。
之前讲到是我们需要6个节点的Redis作为集群,所以我们需要创建6个文件夹,分别存放6个节点的配置信息,6个节点需要对应6个端口号,比如7001~7006,这个端口号我们自行定义,我们通过xftp5可视化创建一下。也可以通过命令创建更加快捷,使用命令# mkdir redis700{1,2,3,4,5,6} 即可在当前目录批量创建6个文件夹。
因为需要6个节点,所有我们需要配置各自的redis.conf配置文件。到我们Redis的安装目录usr/local/bin,将redis-cli、redis-server、redis.conf(没有conf文件,可以从压缩包里拷个出来,或者自己直接新建一个空的conf文件,后面再配置相关信息),分别复制到刚刚创建的6个文件夹当中。可以使用Xftp进行复制。
也可以使用命令 # echo /usr/local/src/redis/redis700{1,2,3,4,5,6} | xargs -n 1 cp redis-cli redis-server 将server和client复制到对应的6个文件夹中, 然后再使用命令 # echo /usr/local/src/redis/redis700{1,2,3,4,5,6} | xargs -n 1 cp ../src/redis/redis-4.0.2/redis.conf 。
将conf文件复制到这6个文件夹中。
接下来,我们需要配置redis.conf文件,如果你是从压缩包拷贝出来,你会发现特别多的备注,这些是都是官网的备注讲解,你可以全部删除,只配置你想配置的信息就行。我们主要配置相对应的端口信息和集群配置信息。
主要配置信息如下:
port 7001
#启用守护进程
appendonly yes
#启用集群
cluster-enabled yes
#关联集群的配置文件
cluster-config-file "nodes.conf"
#超时时间
cluster-node-timeout 5000
#只要有结点宕机导致16384个槽没全被覆盖,整个集群就全部停止服务,所以一定要改为no
cluster-require-full-coverage no
#后台启动
daemonize yes
logfile ""
bind 0.0.0.0
注意6个文件夹的端口号需要一一对应,6个文件都修改完成后,在每个对应文件夹中使用命令# redis-server redis.conf分别将这6个redis服务启动起来。也可以使用脚本的形式批量进行操作。
这里我们可以新建一个脚本用于批量执行启动任务,在redis目录下使用命令# vim startall.sh 。输入I进入编辑模式,输入如下命令:
按下Esc然后:wq保存,执行./startall.sh 提示permission denied说明权限不足,执行命令# chmod 777 startall.sh修改权限获取root用户执行脚本。在使用命令# sh startall.sh 即可正常执行脚本,脚本执行情况如下:
通过命令netstat -tnulp | grep redis和ps aux | grep redis查看redis运行情况,可以看到端口7001、7002、7003、7004、7005、7006的redis都起来了。
四、安装redis与ruby的接口包
现在还缺少redis和ruby的接口,使用gem 安装,我们这个时候其实还需要安装对应的Redis的Rbuy接口包。我们需要下载对应Redis的gem包安装才行。Rubygems的官网其实提供了Redis的gem包,我们可以直接去下载https://rubygems.org/gems/redis/ 下载后上传到服务器当中
因为需要zlib工具依赖,我们需要再安装zlib才行,下载zlib,上传解压,安装zlib官方网站:http://www.zlib.net ,最新版1.2.11,安装我们就一笔带过。
到Xftp上传后的目录
命令:# tar -xvzf zlib-1.2.11.tar.gz 进入解压后的目录#cd zlib-1.2.11
配置编译安装:
命令# ./configure --prefix=/usr/local/zlib
命令:# make && make install
完成后我们需要进入ruby解压后的目录,再使用命令 # cd ./ext/zlib进入ruby的zlib目录,再使用命令# ruby extconf.rb --with-zlib-include=/usr/local/zlib/include/ --with-zlib-lib=/usr/local/zlib/lib //会生成一个Makefile文件。这个时候不要直接安装,先需要将Makefile文件中的错误路径修改一下。使用命令# vim Makefile 打开该文件,将文件中的
修改完成,然后保存:wq接着我们再 使用命令# make && make install ,
安装完成。
最新版本接口包为redis-4.0.1.gem,使用Xftp上传至服务器后使用命令# gem install redis-4.0.1.gem ,
如出现如下错误:
则先跳过该部分,先安装OpenSSL。
安装OpenSSL
因为Redis集群交互是需要OpenSSL ,所以需要先安装OpenSSL,官网地址:https://www.openssl.org/source/ 上次压缩包到服务器,解压。如果之前已经安装了则跳过该步骤。
命令# tar -xzvf openssl-1.1.0f.tar.gz
# cd openssl-1.1.0f
# ./config -fPIC --prefix=/usr/local/openssl enable-shared
# ./config -t
# make && make install
安装完成。
安装完成后回到Ruby的解压目录进入# cd /usr/local/src/ruby-2.4.2/ext/openssl/目录,像安装zlib一样安装openssl。
命令 # ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/
--with-openssl-lib=/usr/local/openssl/lib //会生成一个Makefile文件
注意:/usr/local/openssl是我的openssl安装目录
同样需要将Makefile中的$(top_srcdir)全部改成../.. (可以在Xftp中对该文件使用Notepad++进行打开,然后统一替换)
修改后保存,再执行# make && make install 这样就可以成功了。
这时候再回到存放redis-4.0.1.gem的目录,执行命令# gem install redis-4.0.1.gem 此时redis集群的配置就完成了。
五、启动Redis集群
我们使用redis的集群是通过Ruby脚本完成的,在redis的解压包下的src目录下找到文件 redis-trib.rb
使用Xftp或者复制命令# cp redis-trib.rb ../../将文件放到放有6个节点的文件夹的同一级 ,使用命令# ./redis-trib.rb create --replicas 1 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 127.0.0.1:7006 我们可以使用其默认配置
我们选择yes,意思是服从这种主从分配方式,我们也可以通过配置文件自己指定slave。
到此可以看到redis集群已经启动成功了。
六、Redis集群测试
进入7001端口的目录,使用命令 # redis-cli -p 7001 –c
说明:-h+host –p+端口号 –c 是要连接集群,注意坑,不加会报错
我们在7001的redis中存入一个值 set name tiger ,
这时我们发现他自动把个值转存到7002的redis了。
然后使用 Ctrl + C退出客户端,进入7003的目录使用命令 # redis-cli -p 7003 –c 链接7003的redis,获取值name,我们会发现redis会自动跳转到存入该key的集群redis节点7002中。
七、redis-trib.rb脚本的使用
redis-trib.rb是redis官方推出的管理redis集群的工具,集成在redis的源码src目录下,是基于redis提供的集群命令封装成简单、便捷、实用的操作工具。redis-trib.rb是redis作者用ruby完成的。ruby是门非常灵活的语言,redis-trib.rb只用了1600行左右的代码,就实现了强大的集群操作。
我们可以使用命令# ruby redis-trib.rb help 对redis-trib.rb进行了解
可以看到redis-trib.rb具有以下功能:
1、create:创建集群
2、check:检查集群
3、info:查看集群信息
4、fix:修复集群
5、reshard:在线迁移slot
6、rebalance:平衡集群节点slot数量
7、add-node:将新节点加入集群
8、del-node:从集群中删除节点
9、set-timeout:设置集群节点间心跳连接的超时时间
10、call:在集群全部节点上执行命令
11、import:将外部redis数据导入集群
1、create创建集群
create命令可选replicas参数,replicas表示需要有几个slave。最简单命令使用如下:
# ruby redis-trib.rb create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
有一个slave的创建命令如下:
# ruby redis-trib.rb create --replicas 1 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 127.0.0.1:7006
2、check检查集群
检查集群状态的命令,没有其他参数,只需要选择一个集群中的一个节点即可。执行命令以及结果如下:
# ruby redis-trib.rb check 127.0.0.1:7001
3、info查看集群信息
info命令用来查看集群的信息。info命令也是先执行load_cluster_info_from_node获取完整的集群信息。然后显示ClusterNode的info_string结果,示例如下:
# ruby redis-trib.rb info 127.0.0.1:7001
4、fix修复集群
fix命令的流程跟check的流程很像,显示加载集群信息,然后在check_cluster方法内传入fix为true的变量,会在集群检查出现异常的时候执行修复流程。目前fix命令能修复两种异常,一种是集群有处于迁移中的slot的节点,一种是slot未完全分配的异常。
fix_open_slot方法是修复集群有处于迁移中的slot的节点异常。fix_slots_coverage方法能修复slot未完全分配的异常。
命令:# ruby redis-trib.rb fix 127.0.0.1:7001
5、reshard在线迁移slot
reshard命令可以在线把集群的一些slot从集群原来slot负责节点迁移到新的节点,利用reshard可以完成集群的在线横向扩容和缩容。
reshard的参数很多,下面来一一解释一番:
reshard host:port
--from
--to
--slots
--yes
--timeout
--pipeline
host:port:这个是必传参数,用来从一个节点获取整个集群信息,相当于获取集群信息的入口。
--from
--to
--slots
--yes:设置该参数,可以在打印执行reshard计划的时候,提示用户输入yes确认后再执行reshard。
--timeout
--pipeline
命令:# ruby redis-trib.rb reshard --from all --to
80b661ecca260c89e3d8ea9b98f77edaeef43dcd --slots 11 127.0.0.1:7001
6、rebalance平衡集群节点slot数量
rebalance命令可以根据用户传入的参数平衡集群节点的slot数量,rebalance功能非常强大,可以传入的参数很多,以下是rebalance的参数列表和命令示例。
rebalance host:port
--weight
--auto-weights
--threshold
--use-empty-masters
--timeout
--simulate
--pipeline
命令# ruby redis-trib.rb rebalance --threshold 1 --weight b31e3a2e=5 --weight 60b8e3a1=5 --use-empty-masters --simulate 127.0.0.1:7001
下面也先一一解释下每个参数的用法:
host:port:这个是必传参数,用来从一个节点获取整个集群信息,相当于获取集群信息的入口。
--weight
--auto-weights:这个参数在rebalance流程中并未用到。
--threshold
--use-empty-masters:rebalance是否考虑没有节点的master,默认没有分配slot节点的master是不参与rebalance的,设置--use-empty-masters可以让没有分配slot的节点参与rebalance。
--timeout
--simulate:设置该参数,可以模拟rebalance操作,提示用户会迁移哪些slots,而不会真正执行迁移操作。
--pipeline
7、add-node将新节点加入集群
add-node命令可以将新节点加入集群,节点可以为master,也可以为某个master节点的slave。
add-node new_host:new_port existing_host:existing_port
--slave
--master-id
add-node有两个可选参数:
--slave:设置该参数,则新节点以slave的角色加入集群
--master-id:这个参数需要设置了--slave才能生效,--master-id用来指定新节点的master节点。如果不设置该参数,则会随机为节点选择master节点。
可以看下add-node命令的执行示例:
命令#ruby redis-trib.rb add-node 127.0.0.1:7009 127.0.0.1:7001
8、del-node从集群中删除节点
del-node可以把某个节点从集群中删除。del-node只能删除没有分配slot的节点。删除命令传递两个参数:
host:port:从该节点获取集群信息。
node_id:需要删除的节点id。
del-node执行结果示例如下:
命令# ruby redis-trib.rb del-node 127.0.0.1:7001
d5f6d1d17426bd564a6e309f32d0f5b96962fe53
9、set-timeout设置集群节点间心跳连接的超时时间
set-timeout用来设置集群节点间心跳连接的超时时间,单位是毫秒,不得小于100毫秒,因为100毫秒对于心跳时间来说太短了。该命令修改是节点配置参数cluster-node-timeout,默认是15000毫秒。通过该命令,可以给每个节点设置超时时间,设置的方式使用config set命令动态设置,然后执行config rewrite命令将配置持久化保存到硬盘。以下是示例:
命令# ruby redis-trib.rb set-timeout 127.0.0.1:7001 30000
10、call在集群全部节点上执行命令
call命令可以用来在集群的全部节点执行相同的命令。call命令也是需要通过集群的一个节点地址,连上整个集群,然后在集群的每个节点执行该命令。
命令# ruby redis-trib.rb call 127.0.0.1:7001 get key
11、import将外部redis数据导入集群
import命令可以把外部的redis节点数据导入集群。导入的流程如下:
1、通过load_cluster_info_from_node方法转载集群信息,check_cluster方法检查集群是否健康。
2、连接外部redis节点,如果外部节点开启了cluster_enabled,则提示错误。
3、通过scan命令遍历外部节点,一次获取1000条数据。
4、遍历这些key,计算出key对应的slot。
5、执行migrate命令,源节点是外部节点,目的节点是集群slot对应的节点,如果设置了--copy参数,则传递copy参数,如果设置了--replace,则传递replace参数。
6、不停执行scan命令,直到遍历完全部的key。
7、至此完成整个迁移流程
这中间如果出现异常,程序就会停止。没使用--copy模式,则可以重新执行import命令,使用--copy的话,最好清空新的集群再导入一次。
import命令更适合离线的把外部redis数据导入,在线导入的话最好使用更专业的导入工具,以slave的方式连接redis节点去同步节点数据应该是更好的方式。
下面是一个例子
命令# ./redis-trib.rb import --from 10.0.10.1:6379 127.0.0.1:7001
上面的命令是把 10.0.10.1:6379上的数据导入到 127.0.0.1:7001这个节点所在的集群