Redis集群搭建的几种方式
Posted 斐波那切
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis集群搭建的几种方式相关的知识,希望对你有一定的参考价值。
前面使用了哨兵集群搭建单个分片高可用的结构,实现了主从复制和故障转移,但是没有实现分布式。接下来使用Redis集群搭建,实现哨兵集群没有实现的分布式高可用。
redis-cluster搭建需求
下面准备6个redis节点,搭建如图所示的三主三从分布式redis集群,实现两两互联,以master8001为例,它可以连接另外两个主节点,以及三个从节点。搭建过程可以使用原生redis cluster命令(使用方便),也可以使用ruby自带的脚本(需要先安装ruby,还有安装redis和ruby的接口,比较麻烦)。
ruby脚本辅助搭建
使用ruby脚本辅助安装,即使用redis根目录/src/redis-trib.rb脚本来完成,需要先安装ruby。
-rwxrwxr-x. 1 root root 60852 Sep 21 2017 redis-trib.rb
(1)安装ruby,这里解压了压缩包,进行编译和安装。但是安装完只是最基本的一步,后面还有坑,比较麻烦。
# 解压 [root@node01 /home/software]# tar -zxvf ruby-2.3.1.tar.gz # 检查 [root@node01 /home/software/ruby-2.3.1]# . /configure # 编译,安装 [root@node01 /home/software/ruby-2.3.1]# make && make install # 省略具体安装日志,安装完成后使用ruby -v如果能查看到版本号,就安装ok [root@node01 /home/software/ruby-2.3.1]# ruby -v ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_4-linux]
(2)先准备一个redis-cluster.conf启动加载文件,基本配置参考前面博文https://www.cnblogs.com/youngchaolin/p/11983705.html#_label0 ,主要是bind设置不绑定ip、protected mode设置为no、daemonize设置为yes、其他还有pid、logfile、rdb等,保持原设置不变。
(3)配置appendonly为yes,启动aof持久化方式,这是除了rdb外redis提供的第二种持久化方式。
589 # AOF and RDB persistence can be enabled at the same time without problems. 590 # If the AOF is enabled on startup Redis will load the AOF, that is the file 591 # with the better durability guarantees. 592 # 593 # Please check http://redis.io/topics/persistence for more information. 594 # 配置第二种持久化方式aof 595 appendonly yes 596 597 # The name of the append only file (default: "appendonly.aof") 598 # 标识aof持久化文件名,以端口号区分 599 appendfilename "appendonly6379.aof"
其中rdb和aof两种持久化的主要区别为:
a.rdb保存的是具体的key-value数据,如name-messi,aof保存的是操作记录,如set name messi。
b.因为aof保存的数据更全,redis启动默认加载的是aof,rdb启动可以单独开启。
c.rdb持久化频率是按照持久化策略来的,容易造成数据丢失,而aof是每秒保存一次数据,数据不容易丢失。
d.如果对数据的可靠性要求高,使用aof持久化,如果需要一定的数据恢复能力,但是又不需要很高的可靠性,就选择rdb。
(4)开启集群模式,如果不开启无法计算槽道号。
719 # Normal Redis instances can\'t be part of a Redis Cluster; only nodes that are 720 # started as cluster nodes can. In order to start a Redis instance as a 721 # cluster node enable the cluster support uncommenting the following: 722 # 需设置yes,否则无法计算槽道号,无法创建集群 723 cluster-enabled yes
(5)需要开启集群节点状态记录文件,这个文件会自动更新,每个redis节点都需要一个这样的文件。
725 # Every cluster node has a cluster configuration file. This file is not 726 # intended to be edited by hand. It is created and updated by Redis nodes. 727 # Every Redis Cluster node requires a different cluster configuration file. 728 # Make sure that instances running in the same system do not have 729 # overlapping cluster configuration file names. 730 # 开启集群节点状态记录文件 731 cluster-config-file nodes-6379.conf
(6)将上面的配置文件保存,接下来复制到6个不同的文件夹下,其中文件夹的名字就是redis节点的端口号,根据上图准备8000、8001、8002、8003、8004和8005六个文件夹。复制完成后,修改对应端口号,如8000文件夹的配置文件,将里面全是6379的部分替换为8000,其他类似修改即可。
# 创建目录 [root@node01 /home/software/redis-3.2.11]# mkdir 8000 8001 8002 8003 8004 8005 # 复制文件 [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8000/ [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8001/ [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8002/ [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8003/ [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8004/ [root@node01 /home/software/redis-3.2.11]# cp redis.conf 8005/ # 递归查看是否copy成功 [root@node01 /home/software/redis-3.2.11]# ls -R 800* 8000: redis.conf 8001: redis.conf 8002: redis.conf 8003: redis.conf 8004: redis.conf 8005: redis.conf
# 修改端口略
(7)启动各个节点,发现均是cluster的方式启动,这是创建集群的基础,另外查看集群状态为fail,是因为槽道还没分配的原因,且每个节点cluster nodes查看集群节点信息都只能找到自己一个节点,目前两两互联还没有建立。
# 加载修改后的配置文件启动各个节点 [root@node01 /home/software/redis-3.2.11]# redis-server 8000/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8001/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8002/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8003/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8004/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8005/redis.conf # 查看是否以cluster方式启动,ok [root@node01 /home/software/redis-3.2.11]# ps -ef|grep redis root 16028 1 0 15:43 ? 00:00:00 redis-server *:8000 [cluster] root 16033 1 0 15:43 ? 00:00:00 redis-server *:8001 [cluster] root 16037 1 0 15:43 ? 00:00:00 redis-server *:8002 [cluster] root 16041 1 0 15:43 ? 00:00:00 redis-server *:8003 [cluster] root 16045 1 0 15:43 ? 00:00:00 redis-server *:8004 [cluster] root 16049 1 0 15:43 ? 00:00:00 redis-server *:8005 [cluster] root 16053 1409 0 15:43 pts/0 00:00:00 grep redis # 登录一个节点,查看集群信息 [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8000 127.0.0.1:8000> cluster info cluster_state:fail # 只要有一个槽道没分配,就是fail cluster_slots_assigned:0 cluster_slots_ok:0 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:1 # 只能发现自己一个节点,两两互联暂未建立 cluster_size:0 cluster_current_epoch:0 # 集群的纪元 cluster_my_epoch:0 cluster_stats_messages_sent:0 # 两两互联发送数据量 cluster_stats_messages_received:0 # 两两互联接受数据量 # 查看集群节点,发现只有自己一个 127.0.0.1:8000> cluster nodes dc0e2e16888426089de31466ff398679eec81b86 :8000 myself,master - 0 0 0 connected
(8)启动src/redis-trib.rb命令后想查看帮助信息发现报错。这是正常的,这意味着踏入了一个大坑,接下来的需要填坑了,参考文末博文,完成了报错解决。
# 报错 /usr/local/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require\': cannot load such file -- redis (LoadError) from /usr/local/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require\' from src/redis-trib.rb:25:in `<main>\'
(9)上面报错是需要redis的gem包来安装ruby和redis的接口,先安装gem包,网址https://rubygems.org/gems/redis/,选择对应的版本下载,我这里是选择3.2.1版本,下载好后上传到了redis根目录/src目录下了,具体位置放哪不清楚,放src下是可以验证通过的,另外查看博文放根目录也是可以的。
-rw-r--r--. 1 root root 73728 Dec 12 16:51 redis-3.2.1.gem
(10)准备使用gem install redis命令安装接口,发现报错,提示需要安装zlib,网址http://www.zlib.net,本次选择了1.2.11版本。
ERROR: Loading command: install (LoadError) cannot load such file -- zlib ERROR: While executing gem ... (NoMethodError) undefined method `invoke_with_build_args\' for nil:NilClass
(11)tar -zxvf解压zlib压缩包后,进入解压目录,先指定安装目录,后编译安装zlib。
# --prefix指定安装目录/usr/local/zlib [root@node01 /home/software/zlib-1.2.11]# ./configure --prefix=/usr/local/zlib Checking for gcc... Checking for shared library support... Building shared library libz.so.1.2.11 with gcc. Checking for size_t... Yes. Checking for off64_t... Yes. Checking for fseeko... Yes. Checking for strerror... Yes. Checking for unistd.h... Yes. Checking for stdarg.h... Yes. Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). Checking for vsnprintf() in stdio.h... Yes. Checking for return value of vsnprintf()... Yes. Checking for attribute(visibility) support... Yes. You have new mail in /var/spool/mail/root # 编译后安装 [root@node01 /home/software/zlib-1.2.11]# make && make install ...省略 安装成功 chmod 644 /usr/local/zlib/include/zlib.h /usr/local/zlib/include/zconf.h
(12)还需要进入ruby根目录/ext/zlib,先使用ruby extconf.rb命令,执行完后会在当前目录下生成Makefile文件。
[root@node01 /home/software/ruby-2.3.1/ext/zlib]# ll total 892 -rw-r--r--. 1 root root 146 Apr 16 2013 depend -rw-r--r--. 1 root root 1447 Dec 16 2015 extconf.rb
# 使用ruby extconf.rb命令后会生成一个Makefile文件 -rw-r--r--. 1 root root 7656 Dec 12 17:14 Makefile -rw-r--r--. 1 root root 7090 Dec 12 17:14 mkmf.log -rw-r--r--. 1 root root 124168 Dec 19 2015 zlib.c -rw-r--r--. 1 root root 418576 Dec 12 17:18 zlib.o -rwxr-xr-x. 1 root root 336032 Dec 12 17:18 zlib.so
# 安装时需添加配置信息,指定zlib目录下的include和lib,zlib目录就是前面编译指定安装的目录 [root@node01 /home/software/ruby-2.3.1/ext/zlib]# ruby extconf.rb --with-zlib-include=/usr/local/zlib/include/ --with-zlib-lib=/usr/local/zlib/lib
# 省略,编译安装
[root@node01 /home/software/ruby-2.3.1/ext/zlib]# make && make install
接下来编译,本次编译顺利通过了,如果没有通过可能会出现如下报错,还需要修改Makefile内容。
make: *** No rule to make target `/include/ruby.h\', needed by `zlib.o\'. Stop
修改Makefile内容,将$(top_srcdir)整个换成绝对路径,我这里没有报错,因此没有修改。
zlib.o: $(top_srcdir)/include/ruby.h
修改成:zlib.o: ../../include/ruby.h
最后编译通过会提示如下内容。
[root@node01 /home/software/ruby-2.3.1/ext/zlib]# make && make install compiling zlib.c linking shared-object zlib.so /usr/bin/install -c -m 0755 zlib.so /usr/local/lib/ruby/site_ruby/2.4.0/x86_64-linux
(13)继续安装openssl,如果不安装切换到redis目录使用gem install redis会报\'\'unable to require openssl...\'\'的报错,因此需要继续像安装zlib一样安装openssl。
网址https://www.openssl.org/source/,解压后进入安装目录,执行以下命令,编译安装执行时间比较长。
[root@node01 /home/software/openssl-1.0.2t]# ./config -fPIC --prefix=/usr/local/openssl enable-shared [root@node01 /home/software/openssl-1.0.2t]# ./config -t # 这里会编译很久 [root@node01 /home/software/openssl-1.0.2t]# make && make install
(14)还需进入ruby根目录/ext/openssl下,执行ruby extconf.rb命令,也会在当前目录下生成Makefile文件,执行后光荣的报错了。
[root@node01 /home/software/ruby-2.3.1/ext/openssl]# ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/ --with-openssl-lib=/usr/local/openssl/lib [root@node01 /home/software/ruby-2.3.1/ext/openssl]# make && make install
(15)类似上面安装zlib,也将Makefile文件的\\$(top_srcdir)全部改成"../..",这里在使用了":%s/\\${top_srcdir}/..\\/../g"进行了全局替换。再次编译安装就通过了。
(16)到这里,就差不多可以了,切换目录到redis根目录,然后执行gem install redis,再次报错。没辙了,网上找了一种土办法,先让安装成功。
[root@node01 /home/software/redis-3.2.11]# gem install redis ERROR: Could not find a valid gem \'redis\' (>= 0), here is why: Unable to download data from https://rubygems.org/ - SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
临时办法,大概意思让https连接改成http连接。
[root@node01 /home/software/redis-3.2.11]# gem sources -r https://rubygems.org source https://rubygems.org not present in cache [root@node01 /home/software/redis-3.2.11]# gem sources -a http://rubygems.org https://rubygems.org is recommended for security over http://rubygems.org Do you want to add this insecure source? [yn] y http://rubygems.org added to sources You have new mail in /var/spool/mail/root
继续执行命令,终于ok了,可谓一波三折,这个方法只能作为参考,换一个redis或ruby又不知道会发生什么报错。
# 继续 [root@node01 /home/software/redis-3.2.11/src]# gem install redis Successfully installed redis-3.2.1 Parsing documentation for redis-3.2.1 Installing ri documentation for redis-3.2.1 Done installing documentation for redis after 0 seconds #成功了 WARNING: Unable to pull data from \'https://rubygems.org/\': SSL_connect returned=1 errno=0 state=error: certificate verify failed (https://api.rubygems.org/specs.4.8.gz) 1 gem installed You have new mail in /var/spool/mail/root # 试运行redis-trib.rb脚本,终于ok了 [root@node01 /home/software/redis-3.2.11]# src/redis-trib.rb Usage: redis-trib <command> <options> <arguments ...> create host1:port1 ... hostN:portN --replicas <arg> check host:port info host:port fix host:port --timeout <arg> reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg> rebalance host:port --weight <arg> --auto-weights --use-empty-masters --timeout <arg> ...省略
(17)前面准备好了后,就可以使用ruby脚本来开始构建集群了。上面启动后的redis节点都是各自为政互不联系,接下来先将8000、8001、8002作为主节点连起来,并分配槽道号,本次使用默认分配。
# 使用create [root@node01 /home/software/redis-3.2.11]# src/redis-trib.rb create 192.168.200.140:8000 192.168.200.140:8001 192.168.200.140:8002 >>> Creating cluster >>> Performing hash slots allocation on 3 nodes... Using 3 masters: 192.168.200.140:8000 192.168.200.140:8001 192.168.200.140:8002 M: dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8000 slots:0-5460 (5461 slots) master M: aa79ace502e5369236b62ed61c0eb43733ddcbde 192.168.200.140:8001 slots:5461-10922 (5462 slots) master M: 719d1dd412faf6b4e1eb348c65c329a262e393e1 192.168.200.140:8002 slots:10923-16383 (5461 slots) master Can I set the above configuration? (type \'yes\' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join >>> Performing Cluster Check (using node 192.168.200.140:8000) M: dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8000 slots:0-5460 (5461 slots) master 0 additional replica(s) M: aa79ace502e5369236b62ed61c0eb43733ddcbde 192.168.200.140:8001 slots:5461-10922 (5462 slots) master 0 additional replica(s) M: 719d1dd412faf6b4e1eb348c65c329a262e393e1 192.168.200.140:8002 slots:10923-16383 (5461 slots) master 0 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. You have new mail in /var/spool/mail/root [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8000 # 查看发现集群状态已变成ok,说明槽道没有一个没分配 127.0.0.1:8000> cluster into (error) ERR Wrong CLUSTER subcommand or number of arguments 127.0.0.1:8000> cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:3 cluster_current_epoch:3 cluster_my_epoch:1 cluster_stats_messages_sent:68 cluster_stats_messages_received:68 # 三个主节点都分配了槽道 127.0.0.1:8000> cluster nodes
# 节点信息
# 第一个为节点id,用40位的十六进制表示
# 第二个为节点ip+端口
# 第三个为角色
# 第四个为主节点id,没有主节点就用\'-\'表示
# 第五个是与操作相关的时间戳
# 第六个代表序号
# 第七个代表连接状态
# 第八个代表槽道号区间 aa79ace502e5369236b62ed61c0eb43733ddcbde 192.168.200.140:8001 master - 0 1576145625541 2 connected 5461-10922 719d1dd412faf6b4e1eb348c65c329a262e393e1 192.168.200.140:8002 master - 0 1576145623522 3 connected 10923-16383 dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8000 myself,master - 0 0 1 connected 0-5460
(18)将8003挂接到8000,8004挂接到8001,8005挂接到8002成为从节点,使用add node命令,这里需要用到两个选项,一个是--salve,代表新加的节点是从,一个是--master-id,指定需要添加的主是谁,最后依次添加slaveHost:slavePort existHost:existPort,后面的节点可以是集群中任意一个集群的已知节点。
# 以添加8003为例 ,注意主节点可以是任意一个主节点,不一定是当前从的主节点
[root@node01 /home/software/redis-3.2.11]# src/redis-trib.rb add-node --slave --master-id dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8003 192.168.200.140:8000 >>> Adding node 192.168.200.140:8003 to cluster 192.168.200.140:8000 >>> Performing Cluster Check (using node 192.168.200.140:8000) M: dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8000 slots:0-5460 (5461 slots) master 0 additional replica(s) M: aa79ace502e5369236b62ed61c0eb43733ddcbde 192.168.200.140:8001 slots:5461-10922 (5462 slots) master 0 additional replica(s) M: 719d1dd412faf6b4e1eb348c65c329a262e393e1 192.168.200.140:8002 slots:10923-16383 (5461 slots) master 0 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
# 底层还是调用redis原生命令cluster meet >>> Send CLUSTER MEET to node 192.168.200.140:8003 to make it join the cluster. Waiting for the cluster to join. >>> Configure node as replica of 192.168.200.140:8000. [OK] New node added correctly. You have new mail in /var/spool/mail/root
登录集群客户端查看集群信息,发现搭建成功,实现了三主三从redis集群的搭建。
127.0.0.1:8000> cluster nodes aa79ace502e5369236b62ed61c0eb43733ddcbde 192.168.200.140:8001 master - 0 1576152242486 2 connected 5461-10922 dc0e2e16888426089de31466ff398679eec81b86 192.168.200.140:8000 myself,master - 0 0 1 connected 0-5460 824a999176c12eb6ebd944b75944fd97c65b579d 192.168.200.140:8005 slave 719d1dd412faf6b4e1eb348c65c329a262e393e1 0 1576152244002 3 connected 312accb9be27c48c107a19ab501a75a8c5d321c6 192.168.200.140:8004 slave aa79ace502e5369236b62ed61c0eb43733ddcbde 0 1576152239461 2 connected ada1903bcb5744900916151dd385936ceb6ce049 192.168.200.140:8003 slave dc0e2e16888426089de31466ff398679eec81b86 0 1576152243496 1 connected 719d1dd412faf6b4e1eb348c65c329a262e393e1 192.168.200.140:8002 master - 0 1576152244507 3 connected 10923-16383
ruby脚本简化搭建
可以看出,这个搭建比较繁琐, 如果解决了ruby的报错问题,只需要一个命令就可以完成三主三从redis集群的搭建,下面记录一下。
(1)停止redis所有进程。
[root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8000 shutdown [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8001 shutdown [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8002 shutdown [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8003 shutdown [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8004 shutdown [root@node01 /home/software/redis-3.2.11]# redis-cli -c -p 8005 shutdown [root@node01 /home/software/redis-3.2.11]# ps -ef|grep redis root 3657 18054 0 20:13 pts/2 00:00:00 grep redis
(2)删除rdb和aof持久化文件,删除集群节点状态记录文件。
[root@node01 /home/software/redis-3.2.11]# rm -rf appendonly800* [root@node01 /home/software/redis-3.2.11]# rm -rf dump800* [root@node01 /home/software/redis-3.2.11]# rm -rf nodes-800*
(3)再次启动6个redis节点。
# 启动 [root@node01 /home/software/redis-3.2.11]# redis-server 8000/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8001/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8002/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8003/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8004/redis.conf [root@node01 /home/software/redis-3.2.11]# redis-server 8005/redis.conf [root@node01 /home/software/redis-3.以上是关于Redis集群搭建的几种方式的主要内容,如果未能解决你的问题,请参考以下文章