在centos上搭建redis集群并附测试(真集群非伪集群)

环境:centos6.5 x86 32位 redis3.2.8 ruby-2.2.3

一. redis集群原理

redis是单线程,但是一般的作为缓存使用的话,redis足够了,因为它的读写速度太快了。
官方的一个简单测试:
测试完成了50个并发执行100000个请求。
设置和获取的值是一个256字节字符串。
结果:读的速度是110000次/s,写的速度是81000次/s
在这么快的读写速度下,对于一般程序来说足够用了,但是对于访问量特别大的网站来说,还是稍有不足。
那么,如何提升redis的性能呢?看标题就知道了,搭建集群。

先来一张redis集群的架构图:
在这里插入图片描述

在这个图中,每一个蓝色的圈都代表着一个redis的服务器节点。
它们任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,

然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。
 那么redis是怎么做到的呢?首先,在redis的每一个节点上,都有这么两个东西,一个是插槽(slot)可以理解为是一个可以存储两个数值的一个变量。
这个变量的取值范围是:0-16383。还有一个就是cluster我个人把这个cluster理解为是一个集群管理的插件。当我们的存取的key到达的时候,
redis会根据crc16的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,
通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。

在这里插入图片描述

还有就是因为如果集群的话,是有好多个redis一起工作的,那么,就需要这个集群不是那么容易挂掉,所以呢,理论上就应该给集群中的每个节点至少一个备用的redis服务。
这个备用的redis称为从节点(slave)。那么这个集群是如何判断是否有某个节点挂掉了呢?

首先要说的是,每一个节点都存有这个集群所有主节点以及从节点的信息。

它们之间通过互相的ping-pong判断是否节点可以连接上。如果有一半以上的节点去ping一个节点的时候没有回应,集群就认为这个节点宕机了,
然后去连接它的备用节点。如果某个节点和所有从节点全部挂掉,我们集群就进入faill状态。还有就是如果有一半以上的主节点宕机,那么我们集群同样进入发力了状态。
这就是我们的redis的投票机制,具体原理如下图所示:

在这里插入图片描述

(1)投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超时(cluster-node-timeout),认为当前master节点挂掉.
(2):什么时候整个集群不可用(cluster_state:fail)?
a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完整时进入fail状态.
ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.
b:如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态.

二 . 集群安装配置

2.1 安装配置redis

 此步省略,请参考我到博文【http://blog.csdn.net/wx5040257/article/details/78347729】【http://blog.csdn.net/wx5040257/article/details/78388588】

我准备的服务器ip及各服务器角色如下图所示:
在这里插入图片描述

各节点间互联互通,master和slave由创建集群时确定。

2.2 安装cluster依赖环境
只需在任意一台主机上(如169.254.130.122)安装即可。

 先按照Ruby,注意,不要用yum命令安装,yum命令安装的版本较低,后续步骤会报错,如图:

在这里插入图片描述

建议进行源码安装。

2.2.1 安装ruby

  解压缩源码包,并移动到/usr/local/src目录下

tar -zxf

mv ruby-2.2.3 /usr/local/src/ruby

  进入源码目录进行安装

cd /usr/local/src/ruby

./configure

make && make install

安装完毕后如图所示:
在这里插入图片描述

提示系统缺失zlib,可能后续还要安装zlib包,请继续往下看。可用ruby -v命令查看安装成功的ruby版本。

2.2.2 安装ruby redis接口

gem install redis

报错,如图所示:

解决方案,安装zlib-dev,yum命令安装即可

yum -y install zlib-devel

然后进入ruby源码文件夹
安装ruby自身提供的zlib包
#cd ext/zlib
#ruby ./extconf.rb
#make
#make install

接下来再执行

gem install redis

又报错,如下所示:

    [root@localhost zlib]# gem install redis
    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.1s.tar.gz(下载链接:http://www.openssl.org/source/)
解决方法步骤:
1.解压在/usr/local/src目录下,进入/usr/local/src/openssl目录准备安装:

    [root@localhost src]# cd /usr/local/src/openssl
    [root@localhost openssl]# ./config -fPIC --prefix=/usr/local/openssl enable-shared  
    [root@localhost openssl]# ./config -t  
    [root@localhost openssl]# make && make install

openssl的配置文件必须要配置-fPIC参数,如果没有该参数下面的安装中会出现问题!
安装完成,可以检测一下是否安装成功:

    [root@localhost openssl]# openssl version
    OpenSSL 1.0.1e-fips 11 Feb 2013

2.进入ruby源码[/usr/local/src/ruby]目录下的ext/openssl 目录:

    [root@localhost openssl]# cd ../ruby-2.3.0  
    [root@localhost ruby]# cd ext/openssl  
    [root@localhost openssl]# ruby extconf.rb  
    checking for t_open() in -lnsl... no  
    checking for socket() in -lsocket... no  
    checking for assert.h... yes  
    checking for openssl/ssl.h... no  

提示没有找到ssl.h, 因为出现了错误:openssl/ssl.h … no ,输入如下代码,重新执行:
# ruby extconf.rb --with-openssl-include=/usr/local/openssl/include/ --with-openssl-lib=/usr/local/openssl/lib

    checking for EVP_CIPHER_CTX.engine in openssl/evp.h... yes
    checking for X509_ATTRIBUTE.single in openssl/x509.h... yes
    checking for OPENSSL_FIPS in openssl/opensslconf.h... no
    checking for EVP_CTRL_GCM_GET_TAG in openssl/evp.h... yes
    creating extconf.h
    creating Makefile
    [root@localhost openssl]#

ok,成功
3.接下来并且将ruby 源码目录下的include目录软链接到 / 目录下:

ln -s /usr/local/src/ruby/include /

注意:创建软链的时候一定要写全路径,不能写相对路径

  1. 接下来,继续在ext/openssl 目录下执行:
    [root@localhost openssl]# pwd
    /usr/local/src/ruby/ext/openssl
    [root@localhost openssl]# make && make install

再次使用gem install 安装 ruby redis 接口:

gem install redis

仍然报错:

    [root@localhost openssl]# 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)

意思上无法自动下载rubygems安装,那好吧,我们自己下载安装,例如我下载的是:redis-3.2.1.gem

    [root@localhost soft]# gem install redis-3.2.1.gem 
    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 1 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
ok,安装成功了!
2.3 接下来进行集群的创建

  1. 在各节点进行集群配置,如图:
    在这里插入图片描述

vi /usr/redis/redis.conf

cluster-enabled yes ==>表示开启集群功能

cluster-config-file nodes-6379.conf ====>表示自动生成的集群配置文件

cluster-node-timeout 15000====> 表示集群节点连接超时时间

  1. 创建集群

创建集群环境的命令格式为redis-trib.rb create --replicas masterNode1,masterNode2,masterNodeN,slaveNode1,slaveNode2,slaveNodeN
Node的格式为"IP:port",slaveCount表示每个masterNode对应的slaveNode个数,在集群环境中可以没有slave(在命令中省略掉slaveNode部分即可)。
但如果有slave,则命令中,前n中个节点都为master,后n个节点都为slave,第n个master节点对应的slave应该是第n个。

注意:创建集群前,每个节点到数据都要清空,用flushall命令

    127.0.0.1:6379 > flushall

执行命令创建集群:

    redis-trib.rb create --replicas 1 169.254.130.122:6379 169.254.130.10:6379 169.254.130.20:6379 
    169.254.130.12:6379 169.254.130.11:6379 169.254.130.25:6379  

注意:这条命令没有跨行
出现如下提示信息:

	--------------------------------------------------------------------
	注:如果你对python感兴趣,我这有个学习Python基地,里面有很多学习资料,感兴趣的+Q群:895817687
	--------------------------------------------------------------------

     Creating cluster
    Performing hash slots allocation on 6 nodes...
    Using 3 masters:
    169.254.130.122:6379
    169.254.130.10:6379
    169.254.130.20:6379
    Adding replica 169.254.130.12:6379 to 169.254.130.122:6379
    Adding replica 169.254.130.11:6379 to 169.254.130.10:6379
    Adding replica 169.254.130.25:6379 to 169.254.130.20:6379
    M: 89d0ca92c42dfd6fa8cd2286099a331687cc3620 169.254.130.122:6379
       slots:0-5460,9189 (5462 slots) master
    M: b5d5a4a43778b7fdb64520538ace4a3a258b552a 169.254.130.10:6379
       slots:5461-10922 (5462 slots) master
    M: daf3d1fa25405ae834db58d071f9b9a5165125ba 169.254.130.20:6379
       slots:312,700,741,2076,2880,4377,4576,7141,8931,8975,9189,10780,10923-16383 (5473 slots) master
    S: c79959320e43ea0884d6f5914ead5198cd3d3f22 169.254.130.12:6379
       replicates 89d0ca92c42dfd6fa8cd2286099a331687cc3620
    S: 8a38aee74310f5aeffbcabdc676f64853acf77d5 169.254.130.11:6379
       replicates b5d5a4a43778b7fdb64520538ace4a3a258b552a
    S: a3b0e2a4ce8c4df395506942163f21db39ae9fb3 169.254.130.25:6379
       replicates daf3d1fa25405ae834db58d071f9b9a5165125ba
    Can I set the above configuration? (type 'yes' to accept): 

从上面可看出,六个节点都处于"OK"状态,并且前三个6379端口的都为master,而都三个6379端口的都为slave。
此时出现提示,键入yes后,各节点将会进行互联操作
输入yes,接下来报错了:

    Can I set the above configuration? (type 'yes' to accept): yes
    /usr/local/lib/ruby/gems/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:113:in `call': ERR Slot 4788 is already busy (Redis::CommandError)
            from /usr/local/lib/ruby/gems/2.2.0/gems/redis-3.2.1/lib/redis.rb:2556:in `block in method_missing'
            from /usr/local/lib/ruby/gems/2.2.0/gems/redis-3.2.1/lib/redis.rb:37:in `block in synchronize'
            from /usr/local/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
            from /usr/local/lib/ruby/gems/2.2.0/gems/redis-3.2.1/lib/redis.rb:37:in `synchronize'
            from /usr/local/lib/ruby/gems/2.2.0/gems/redis-3.2.1/lib/redis.rb:2555:in `method_missing'
            from /usr/redis/src/redis-trib.rb:212:in `flush_node_config'
            from /usr/redis/src/redis-trib.rb:776:in `block in flush_nodes_config'
            from /usr/redis/src/redis-trib.rb:775:in `each'
            from /usr/redis/src/redis-trib.rb:775:in `flush_nodes_config'
            from /usr/redis/src/redis-trib.rb:1296:in `create_cluster_cmd'
            from /usr/redis/src/redis-trib.rb:1701:in `<main>'

错误提示是
slot插槽被占用了(这是 搭建集群前时,以前redis的旧数据和配置信息没有清理干净。)
解决方案是
用redis-cli 登录到每个节点执行 flushall 和 cluster reset 就可以了。
然后重新执行创建集群的命令:

redis-trib.rb create --replicas 1 169.254.130.122:6379 169.254.130.10:6379 …(省略)

接下来又卡住了,如下:

    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........................................................................
    .......................................................................................................
    ....................................................................................

原因:
redis集群不仅需要开通redis客户端连接的端口,而且需要开通集群总线端口
集群总线端口为redis客户端连接的端口 + 10000
如redis端口为6379
则集群总线端口为16379
故,所有服务器的点需要开通redis的客户端连接端口和集群总线端口
注意:iptables 放开,如果有安全组,也要放开这两个端口
受不了啦,把所有节点的防火墙全部关闭算了。重新执行创建集群的命令,这回成功了:

    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
    2210:M 04 Nov 04:02:59.467 # IP address for this node updated to 169.254.130.122
    Waiting for the cluster to join.
    >>> Performing Cluster Check (using node 169.254.130.122:6379)
    M: 89d0ca92c42dfd6fa8cd2286099a331687cc3620 169.254.130.122:6379
       slots:0-5460 (5461 slots) master
       1 additional replica(s)
    S: 8a38aee74310f5aeffbcabdc676f64853acf77d5 169.254.130.11:6379
       slots: (0 slots) slave
       replicates b5d5a4a43778b7fdb64520538ace4a3a258b552a
    M: daf3d1fa25405ae834db58d071f9b9a5165125ba 169.254.130.20:6379
       slots:10923-16383 (5461 slots) master
       1 additional replica(s)
    M: b5d5a4a43778b7fdb64520538ace4a3a258b552a 169.254.130.10:6379
       slots:5461-10922 (5462 slots) master
       1 additional replica(s)
    S: a3b0e2a4ce8c4df395506942163f21db39ae9fb3 169.254.130.25:6379
       slots: (0 slots) slave
       replicates daf3d1fa25405ae834db58d071f9b9a5165125ba
    S: c79959320e43ea0884d6f5914ead5198cd3d3f22 169.254.130.12:6379
       slots: (0 slots) slave
       replicates 89d0ca92c42dfd6fa8cd2286099a331687cc3620
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.
    [root@localhost redis]# 2210:M 04 Nov 04:03:02.322 * Slave 169.254.130.12:6379 asks for synchronization
    2210:M 04 Nov 04:03:02.322 * Full resync requested by slave 169.254.130.12:6379
    2210:M 04 Nov 04:03:02.322 * Starting BGSAVE for SYNC with target: disk
    2210:M 04 Nov 04:03:02.326 * Background saving started by pid 2502
    2502:C 04 Nov 04:03:02.347 * DB saved on disk
    2502:C 04 Nov 04:03:02.348 * RDB: 0 MB of memory used by copy-on-write
    2210:M 04 Nov 04:03:02.352 * Background saving terminated with success
    2210:M 04 Nov 04:03:02.352 * Synchronization with slave 169.254.130.12:6379 succeeded
    2210:M 04 Nov 04:03:04.371 # Cluster state changed: ok

从上面可看出16384个哈希槽已均匀分配给了三个master节点,分别为:
169.254.130.20:6379(10923-16384)
169.254.130.10:6379(5461-10922)
169.254.130.122:6379(0-5460)
大功告成!!!

2.5 进行测试

登录122主机,用redis-cli -c命令

-c命令在连接集群结点时使用,此选项可防止moved和ask异常。

    [root@localhost redis]# redis-cli -c
    127.0.0.1:6379> set key1 "hello redis cluster"
    -> Redirected to slot [9189] located at 169.254.130.10:6379
    OK
    169.254.130.10:6379> set key2 java
    -> Redirected to slot [4998] located at 169.254.130.122:6379
    OK
    169.254.130.122:6379> 
    169.254.130.122:6379> keys *
    1) "key2"
    169.254.130.122:6379> get key2
    "java"
    169.254.130.122:6379> get key1
    -> Redirected to slot [9189] located at 169.254.130.10:6379
    "hello redis cluster"
    169.254.130.10:6379> get key20
    -> Redirected to slot [905] located at 169.254.130.122:6379
    "html"
    169.254.130.122:6379> 

从中可以发现存时是分布式存储,取时也是从集群中取,测试成功

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值