实验环境:
Redis版本:4.0.9
OS:redhat 6.4三台
IP:10.10.1.129 Hostname:wjq1 Port:[7001/7002/7003]
IP:10.10.1.130 Hostname:wjq2 Port:[7004/7005/7006]
IP:10.10.1.131 Hostname:wjq3 Port:[7007/7008/7009]
一、安装redis
下载、解压、编译、安装redis4.0.9
关于Redis实例安装详细可参考:Redis介绍及CentOS 7安装redis 4.0详细步骤
详细的安装过程可参考:
[root@wjq1 wjq-software]# tar -zxvf redis-4.0.9.tar.gz [root@wjq1 redis-4.0.9]# make cd src && make all make[1]: Entering directory `/usr/local/redis/redis-4.0.9/src' CC adlist.o In file included from adlist.c:34: zmalloc.h:50:31: error: jemalloc/jemalloc.h: No such file or directory zmalloc.h:55:2: error: #error "Newer version of jemalloc required" make[1]: *** [adlist.o] Error 1 make[1]: Leaving directory `/usr/local/redis/redis-4.0.9/src' make: *** [all] Error 2
在README.md中有这有一段话:
Redis在安装的时候关于内存分配器allocator, 如果有MALLOC 这个 环境变量, 会有用这个环境变量的 去建立Redis。如果没有,那么就是用默认的分配器;redis2.4版本之后,默认使用jemalloc来做内存管理,因为jemalloc被证明解决fragmentation problem(内存碎片化问题)比libc更好,而且libc 并不是默认的 分配器, 但是如果你又没有jemalloc 而只有 libc 当然 make 出错。 所以加这么一个参数。
解决方法:
[root@wjq1 src]# make MALLOC=libc
如果想用jemalloc的话,安装jemalloc即可;如果使用yum安装的话需要配置EPEL源
[root@wjq1 src]# make MALLOC=libc [root@wjq1 redis-4.0.9]# make PREFIX=/usr/local/redis install [root@wjq1 redis]# ll total 8 drwxr-xr-x 2 root root 4096 Jun 5 11:32 bin drwxr-xr-x 6 root root 4096 Jun 5 11:24 redis-4.0.9
[root@wjq1 redis-4.0.9]# cp redis.conf /etc/redis/
二、创建redis节点
1、首先在10.10.1.129主机上创建目录/etc/redis/redis_cluster
[root@wjq1 ~]# mkdir /etc/redis/redis_cluster
2、在redis_cluster目录下,创建名为7000、7001、7002的目录,并将 redis.conf拷贝到这三个目录中
[root@wjq1 ~]# mkdir /etc/redis/redis_cluster/{7001,7002,7003} [root@wjq1 ~]# cp /etc/redis/redis.conf /etc/redis/redis_cluster/7001 [root@wjq1 ~]# cp /etc/redis/redis.conf /etc/redis/redis_cluster/7002 [root@wjq1 ~]# cp /etc/redis/redis.conf /etc/redis/redis_cluster/7003
3、分别修改这三个配置文件,修改的内容如下所示:
[root@wjq1 ~]# cat /etc/redis/redis_cluster/7001/redis.conf |grep -v ^# |grep -v ^$ //默认ip为127.0.0.1,需要改为其他节点机器可访问的ip,否则创建集群时无法访问对应的端口,无法创建集群 bind 10.10.1.129 //端口7000,7002,7003 port 7001 //redis后台运行 daemonize yes //pidfile文件对应7000,7001,7002 pidfile /var/run/redis/redis_7001.pid //logfile文件对应7000,7001,7002 logfile /var/log/redis/redis_7001.log //rdb文件对应7000,7001,7002 dbfilename dump7001.rdb //开启集群,把注释#去掉 cluster-enabled yes //集群的配置,配置文件首次启动自动生成 7000,7001,7002 cluster-config-file nodes-7001.conf //请求超时,默认15秒,可自行设置 cluster-node-timeout 15000
接着在另外两台机器上(10.10.1.130、10.10.1.131)重复以上三步,只是把目录改为7003、7004、7005、7006、7007、7008对应的配置文件也按照这个规则修改即可
三、启动各个节点的redis
节点一:
[root@wjq1 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7001/redis.conf [root@wjq1 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7002/redis.conf [root@wjq1 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7003/redis.conf
查看相应的进程以及端口信息
[root@wjq1 ~]# ps -ef | grep redis root 40414 1 0 12:36 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.129:7001 [cluster] root 40419 1 0 12:36 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.129:7002 [cluster] root 40424 1 0 12:36 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.129:7003 [cluster] root 40429 38753 0 12:36 pts/0 00:00:00 grep redis [root@wjq1 ~]# netstat -tuplan | grep redis tcp 0 0 10.10.1.129:17003 0.0.0.0:* LISTEN 40424/redis-server tcp 0 0 10.10.1.129:7001 0.0.0.0:* LISTEN 40414/redis-server tcp 0 0 10.10.1.129:7002 0.0.0.0:* LISTEN 40419/redis-server tcp 0 0 10.10.1.129:7003 0.0.0.0:* LISTEN 40424/redis-server tcp 0 0 10.10.1.129:17001 0.0.0.0:* LISTEN 40414/redis-server tcp 0 0 10.10.1.129:17002 0.0.0.0:* LISTEN 40419/redis-server
节点二:
[root@wjq2 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7004/redis.conf [root@wjq2 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7005/redis.conf [root@wjq2 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7006/redis.conf [root@wjq2 ~]# ps -ef | grep redis root 39261 1 0 12:38 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.130:7004 [cluster] root 39266 1 0 12:38 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.130:7005 [cluster] root 39271 1 0 12:38 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.130:7006 [cluster] root 39276 38355 0 12:38 pts/0 00:00:00 grep redis [root@wjq2 ~]# netstat -tuplan | grep redis tcp 0 0 10.10.1.130:17004 0.0.0.0:* LISTEN 39261/redis-server tcp 0 0 10.10.1.130:17005 0.0.0.0:* LISTEN 39266/redis-server tcp 0 0 10.10.1.130:17006 0.0.0.0:* LISTEN 39271/redis-server tcp 0 0 10.10.1.130:7004 0.0.0.0:* LISTEN 39261/redis-server tcp 0 0 10.10.1.130:7005 0.0.0.0:* LISTEN 39266/redis-server tcp 0 0 10.10.1.130:7006 0.0.0.0:* LISTEN 39271/redis-server
节点三:
[root@wjq3 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7007/redis.conf [root@wjq3 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7008/redis.conf [root@wjq3 ~]# /usr/local/redis/bin/redis-server /etc/redis/redis_cluster/7009/redis.conf [root@wjq3 ~]# [root@wjq3 ~]# ps -ef | grep redis root 24742 1 0 13:00 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.131:7007 [cluster] root 24758 1 0 13:01 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.131:7008 [cluster] root 24763 1 1 13:01 ? 00:00:00 /usr/local/redis/bin/redis-server 10.10.1.131:7009 [cluster] root 24768 23890 1 13:01 pts/0 00:00:00 grep redis [root@wjq3 ~]# [root@wjq3 ~]# netstat -tuplan | grep redis tcp 0 0 10.10.1.131:17007 0.0.0.0:* LISTEN 24742/redis-server tcp 0 0 10.10.1.131:17008 0.0.0.0:* LISTEN 24758/redis-server tcp 0 0 10.10.1.131:17009 0.0.0.0:* LISTEN 24763/redis-server tcp 0 0 10.10.1.131:7007 0.0.0.0:* LISTEN 24742/redis-server tcp 0 0 10.10.1.131:7008 0.0.0.0:* LISTEN 24758/redis-server tcp 0 0 10.10.1.131:7009 0.0.0.0:* LISTEN 24763/redis-server
注:确保每个节点配置正确,并且能够成功启动起来
随便找个节点测试一下:
[root@wjq1 ~]# /usr/local/redis/bin/redis-cli -h 10.10.1.129 -p 7002 10.10.1.129:7002> 10.10.1.129:7002> keys * (empty list or set) 10.10.1.129:7002> 10.10.1.129:7002> set name wjq (error) CLUSTERDOWN Hash slot not served
连接成功了,但好像报错了???
(error) CLUSTERDOWN Hash slot not served(不提供集群的散列槽),这是什么鬼?
这是因为虽然我们配置并启动了 Redis 集群服务,但是他们暂时还并不在一个集群中,互相直接发现不了,而且还没有可存储的位置,就是所谓的slot(槽)
四、redis-trib创建集群
Redis的实例全部运行之后,还需要redis-trib.rb工具来完成集群的创建,redis-trib.rb二进制文件在Redis包主目录下的src目录中,运行该工具依赖Ruby环境和gem,因此需要提前安装。
1、安装ruby【任意一个节点安装即可】
[root@wjq1 ~]# yum install ruby [root@wjq1 ~]# ruby -v ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux] [root@wjq1 ~]# [root@wjq1 ~]# gem -v -bash: gem: command not found
使用yum安装ruby后,但是没有gem命令并且ruby的版本是1.8.7并不满足后续的要求;最新redis要求ruby版本在2.2以上,系统自带ruby大部分都低于2.2,输入以下命令,删除旧版本:
[root@wjq1 ~]# yum remove ruby
下面是完成的安装ruby2.4的步骤:
首先下载ruby2.4或高版本
下载地址:https://www.ruby-lang.org/en/downloads/
安装ruby之前,首选安装openssl,否则后续再安装ruby的过程中遇到非常多的问题,详细的错误在文章后边有相应的解决方法
OpenSSL官网:https://www.openssl.org/
下载OpenSSL版本1.0.2n源码:
[root@wjq1~]# wget https://www.openssl.org/source/openssl-1.0.2n.tar.gz
解压并进入openssl代码根目录:
[root@wjq1 ~]# tar zxvf openssl-1.0.2n.tar.gz [root@wjq1 ~]# cd openssl-1.0.2n
配置、编译、安装:
[root@wjq1 openssl-1.0.2n]# ./config [root@wjq1 openssl-1.0.2n]# make [root@wjq1 openssl-1.0.2n]# make install
安装完成后,默认的安装位置为/usr/local/ssl
(3)解压、编译安装ruby
[root@wjq2 ~]# mkdir -p /usr/local/ruby2.4 [root@wjq2 ~]# cd /wjq-software/ [root@wjq2 wjq-software]# ll total 120240 drwxr-xr-x 20 root root 4096 Jun 5 15:57 openssl-1.0.2n -rw-r--r-- 1 root root 5375802 Jun 5 15:51 openssl-1.0.2n.tar.gz -rw-r--r-- 1 root root 91648 Jun 5 15:50 redis-4.0.1.gem -rw-r--r-- 1 root root 14225338 Jun 5 15:53 ruby-2.4.4.tar.gz [root@wjq2 wjq-software]# [root@wjq2 wjq-software]# tar -zxvf ruby-2.4.4.tar.gz [root@wjq2 ruby-2.4.4]# ./configure -prefix=/usr/local/ruby2.4 --with-openssl-include=/usr/local/ssl/include/ --with-openssl-lib=/usr/local/ssl/lib [root@wjq2 ruby-2.4.4]# make [root@wjq2 ruby-2.4.4]# make install [root@wjq2 ruby-2.4.4]# /usr/local/ruby2.4/bin/ruby -v ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-linux] [root@wjq2 ruby-2.4.4]# [root@wjq2 ruby-2.4.4]# /usr/local/ruby2.4/bin/gem -v 2.6.14.1 [root@wjq2 ruby-2.4.4]# vim ~/.bash_profile RUBY_PATH=/usr/local/ruby2.4/bin PATH=$PATH:$HOME/bin:/usr/local/mongdb/bin:$RUBY_PATH
使用gem安装redis安装redis的接口
[root@wjq2 ~]# gem install redis
由于源的原因,可能下载失败,就手动下载下来安装
下载地址:https://rubygems.org/gems/redis/versions/
[root@wjq2 ~]# gem install /wjq-software/redis-4.0.1.gem Successfully installed redis-4.0.1 Parsing documentation for redis-4.0.1 Installing ri documentation for redis-4.0.1 Done installing documentation for redis after 0 seconds WARNING: Unable to pull data from 'https://rubygems.org/': timed out (https://api.rubygems.org/specs.4.8.gz) 1 gem installed
3、开始创建集群,这才是真正的集群
Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中
简单解释一下这个命令:调用 ruby 命令来进行创建集群:
–replicas 1 表示主从复制比例为 1:1,即一个主节点对应一个从节点;然后,默认给我们分配好了每个主节点和对应从节点服务,以及 solt 的大小,因为在 Redis 集群中有且仅有 16383 个 solt ,默认情况会给我们平均分配,当然你可以指定,后续的增减节点也可以重新分配。
[root@wjq2 ~]# /usr/local/redis/redis-4.0.9/src/redis-trib.rb create --replicas 1 \ > 10.10.1.129:7001 10.10.1.129:7002 10.10.1.129:7003 \ > 10.10.1.130:7004 10.10.1.130:7005 10.10.1.130:7006 \ > 10.10.1.131:7007 10.10.1.131:7008 10.10.1.131:7009 >>> Creating cluster >>> Performing hash slots allocation on 9 nodes... Using 4 masters: 10.10.1.129:7001 10.10.1.130:7004 10.10.1.131:7007 10.10.1.129:7002 Adding replica 10.10.1.131:7008 to 10.10.1.129:7001 Adding replica 10.10.1.129:7003 to 10.10.1.130:7004 Adding replica 10.10.1.130:7006 to 10.10.1.131:7007 Adding replica 10.10.1.131:7009 to 10.10.1.129:7002 Adding replica 10.10.1.130:7005 to 10.10.1.129:7001 M: 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 10.10.1.129:7001 slots:0-4095 (4096 slots) master M: 924d61969343b5cc2200bd3a2277e815dc76048c 10.10.1.129:7002 slots:12288-16383 (4096 slots) master S: b9ba251f575b5396da4bea307e25a98d85b3c504 10.10.1.129:7003 replicates a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 M: a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 10.10.1.130:7004 slots:4096-8191 (4096 slots) master S: bdc2f6b254459a6a6d038d93e5a3d3a67fe3e936 10.10.1.130:7005 replicates 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 S: 4ae20400d02e57e274f9b9f29d4ba120aa2b574c 10.10.1.130:7006 replicates 2b0f974e151cd798f474107ac68a47e188cc88a2 M: 2b0f974e151cd798f474107ac68a47e188cc88a2 10.10.1.131:7007 slots:8192-12287 (4096 slots) master S: b240d86fdf6abc73df059baf64b930387664da15 10.10.1.131:7008 replicates 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 S: 5b7989d5370aef41679e92a6bd34c30ac3be3581 10.10.1.131:7009 replicates 924d61969343b5cc2200bd3a2277e815dc76048c 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 10.10.1.129:7001) M: 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 10.10.1.129:7001 slots:0-4095 (4096 slots) master 2 additional replica(s) S: 4ae20400d02e57e274f9b9f29d4ba120aa2b574c 10.10.1.130:7006 slots: (0 slots) slave replicates 2b0f974e151cd798f474107ac68a47e188cc88a2 M: 924d61969343b5cc2200bd3a2277e815dc76048c 10.10.1.129:7002 slots:12288-16383 (4096 slots) master 1 additional replica(s) M: 2b0f974e151cd798f474107ac68a47e188cc88a2 10.10.1.131:7007 slots:8192-12287 (4096 slots) master 1 additional replica(s) S: 5b7989d5370aef41679e92a6bd34c30ac3be3581 10.10.1.131:7009 slots: (0 slots) slave replicates 924d61969343b5cc2200bd3a2277e815dc76048c S: b9ba251f575b5396da4bea307e25a98d85b3c504 10.10.1.129:7003 slots: (0 slots) slave replicates a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 S: b240d86fdf6abc73df059baf64b930387664da15 10.10.1.131:7008 slots: (0 slots) slave replicates 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 S: bdc2f6b254459a6a6d038d93e5a3d3a67fe3e936 10.10.1.130:7005 slots: (0 slots) slave replicates 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 M: a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 10.10.1.130:7004 slots:4096-8191 (4096 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
出现上述的输出则代表集群搭建成功啦!!!
说明:
M: 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 为主节点id
S: b240d86fdf6abc73df059baf64b930387664da15 为从节点的id
目前来看,7001、7002、7004、7007 为主节点,7003、7005、7008、7009 为从节点,并向你确认是否同意这么配置。输入 yes 后,会开始集群创建。
五、集群验证
1、随意登录一个节点,查看集群的信息和节点的信息
加参数 -C 可连接到集群,因为 redis.conf 将 bind 改为了ip地址,所以 -h 参数不可以省略,-p 参数为端口号
[root@wjq2 ~]# /usr/local/redis/bin/redis-cli -h 10.10.1.130 -p 7005 -c 10.10.1.130:7005> 10.10.1.130:7005> cluster info cluster_state:ok #集群状态 cluster_slots_assigned:16384 #被分配的槽位数 cluster_slots_ok:16384 #正确分配的槽位 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:9 #集群节点数 cluster_size:4 cluster_current_epoch:9 cluster_my_epoch:1 cluster_stats_messages_ping_sent:215 cluster_stats_messages_pong_sent:225 cluster_stats_messages_meet_sent:5 cluster_stats_messages_sent:445 cluster_stats_messages_ping_received:222 cluster_stats_messages_pong_received:220 cluster_stats_messages_meet_received:3 cluster_stats_messages_received:445 10.10.1.130:7005> cluster nodes 4ae20400d02e57e274f9b9f29d4ba120aa2b574c 10.10.1.130:7006@17006 slave 2b0f974e151cd798f474107ac68a47e188cc88a2 0 1528186867658 7 connected 924d61969343b5cc2200bd3a2277e815dc76048c 10.10.1.129:7002@17002 master - 0 1528186865000 2 connected 12288-16383 b240d86fdf6abc73df059baf64b930387664da15 10.10.1.131:7008@17008 slave 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 0 1528186865643 8 connected 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 10.10.1.129:7001@17001 master - 0 1528186862612 1 connected 0-4095 bdc2f6b254459a6a6d038d93e5a3d3a67fe3e936 10.10.1.130:7005@17005 myself,slave 7a047cfaae70c30d0d7e1a5d9854eb7f11afe957 0 1528186863000 5 connected b9ba251f575b5396da4bea307e25a98d85b3c504 10.10.1.129:7003@17003 slave a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 0 1528186865000 4 connected a4a5de0be9bb5704eec17cbe0223076eb38fc4a4 10.10.1.130:7004@17004 master - 0 1528186866650 4 connected 4096-8191 5b7989d5370aef41679e92a6bd34c30ac3be3581 10.10.1.131:7009@17009 slave 924d61969343b5cc2200bd3a2277e815dc76048c 0 1528186866000 9 connected 2b0f974e151cd798f474107ac68a47e188cc88a2 10.10.1.131:7007@17007 master - 0 1528186864631 7 connected 8192-12287 10.10.1.130:7005>
2、在其中的一个节点插入一个key
10.10.1.130:7005> keys * (empty list or set) 10.10.1.130:7005> 10.10.1.130:7005> set name wjq -> Redirected to slot [5798] located at 10.10.1.130:7004 OK 10.10.1.130:7004> get name "wjq"
在其他的节点验证是否成功
[root@wjq3 ~]# /usr/local/redis/bin/redis-cli -h 10.10.1.131 -p 7009 -c 10.10.1.131:7009> get name -> Redirected to slot [5798] located at 10.10.1.130:7004 "wjq" 10.10.1.130:7004>
小结
redis cluster在设计的时候,就考虑到了去中心化、去中间件,也就是说,集群中的每个节点都是平等关系,都是对等的,每个节点都保存各自的数据和整个集群的状态。每个节点都和其他所有节点连接,而且这些连接保持活跃,这样就保证了我们只需要连接集群中的任意一个节点,就可以获取到其他节点的数据。
Redis 集群没有并使用传统的一致性哈希来分配数据,而是采用另外一种叫做哈希槽(hash slot)的方式来分配的。redis cluster默认分配了16384个slot当我们set一个key时,会用CRC16算法来取模得到所属的slot,然后将这个key分到哈希槽区间的节点上具体算法就是CRC16(key)%16384。所以我们在测试的时候看到set和get的时候,直接跳转到了7000端口的节点。
Redis集群会把数据存在一个master节点,然后在这 master和其对应的salve之间进行数据同步。当读取数据时,也根据一致性哈希算法到对应的master节点获取数据。只有当一个master挂掉之后,才会启动一个对应的salve节点,充当master。
需要注意的是:必须要3个或以上的主节点,否则在创建集群时会失败,并且当存活的主节点数小于总节点数的一半时,整个集群就无法提供服务了。
这一篇 Redis 集群部署搭建的文章真的是一步一步的走下来的,只要你安装我的步骤来,就保证你能成功搭建一个Redis集群玩玩,也可以这么说,除了步骤繁琐外,几乎不存在技术含量,估计能看完的人都感觉累(说真的,写这种文章真的很累人)。
接下来可能就是动态扩容、增加节点和减少节点,重新分配槽大小等,当然,还有最重要的就是怎么和我们程序结合起来,以及如何更好的把 Redis 缓存集群发挥出应有的效果,这些才是最重要的。
搭建过程中遇到的问题总结:
[root@wjq1 ~]# gem install redis
#由于源的原因,可能下载失败,就手动下载下来安装
[root@wjq2 ~]# gem install /wjq-software/redis-4.0.1.gem ERROR: While executing gem ... (Gem::Exception) Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources
原因:
缺少openssl,需要安装openssl包,但是之前我已经安装一个openssl-1.0.2n.tar.gz
解决方法:
[root@wjq1 ruby-2.4.4]# cd ./ext/openssl/ [root@wjq1 openssl]# ruby extconf.rb checking for t_open() in -lnsl... no checking for socket() in -lsocket... no checking for openssl/ssl.h... no
提示没有找到ssl.h, 因为出现了错误:openssl/ssl.h:没有那个文件,接着按照下面的方法执行