Redis集群搭建

   首先说一下,为何要搭建Redis集群。Redis是在内存中保存数据,而我们的电脑一般内存都不大,这也就意味着Redis不适合存储大数据。适合存储大数据的是Hadoop生态系统的HBase或者是MogoDB。Redis更适合处理高并发,一台设备的存储能力是很有限的,但是多台设备协同合作,就可以让内存增大很多倍,这就需要用到集群。

        我们来看一下集群图,如下图所示。可以看到Redis集群是没有统一入口的,客户端连集群中的哪台设备都行,集群中各个设备之间都定时进行交互,以便知道节点是否还正常工作。


        那么假如某个节点挂掉了怎么办?Redis集群是有容错投票机制的,如下图所示。浅黄色的那个节点向红色的那个节点发出ping命令,红色节点没有回应,这时浅黄色节点便认为这个节点可能挂掉了,它会投上一票,不过这时只是疑问,所以浅黄色节点画了一个"?",然后浅黄色节点告诉别的节点说这个红色的节点可能挂掉了,第二个节点去尝试和这个红色节点联系,发现也ping不同,于是第二个节点也认为这个红色节点挂掉了,第二个节点也投上一票,接着第三个节点去和红色节点联系,也联系不上,于是也投上一票,这样便三票了。Redis的容错投票机制是集群中过半数的节点认为某个节点挂了,那么就认定这个节点挂了。这时要看这个红色节点还有没有备用节点,如果没有备用节点了,那么整个集群将停止对外提供服务,如果有备份节点,那么会将备份节点扶正,继续对外提供服务。


         那么为什么一个节点挂掉(并且没有备用节点)的话,整个集群都不能提供服务了呢?其实这跟Redis集群的存储机制有关,Redis集群内置了16384个哈希槽,当需要在Redis集群中放置一个key-value时,redis先对key使用crc16算法算出一个结果,然后把结果对16384求余数,这样每个key都会对应一个编号在0-16383之间的哈希槽,redis会根据节点数量大致均等的将哈希映射到不同的节点。我们以下图为例,我们把这16384个哈希槽分配到三个Server上,假如Server1上卡槽是0-5000,Server2上卡槽是5001-10000,Server3上卡槽是10001-16383。假如我们要保存字符串"hello",而"hello"经过crc16算法再对16384求余后是500,很显然应该存到Server1上,假如要存储的字符串"hello2"经过crc16算法再对16384求余后是11500,那么狠显然应该存到Server3上,同理,"hello3"、"hello1"被分别存到Server2和Server1上了。也就是说每个Server其实存储的内容是不一样的,这也就是为何某个节点挂掉后如果没有备用节点的话,整个集群都会挂掉,因为数据不全了啊。另外,关于每个服务器上卡槽的分布数量可以根据服务器的性能来定,性能好的可以多分配些卡槽,这样在它上面存储的内容也就多了。

   

        下面我们来搭建Redis集群,由于集群的容错机制是超过半数的节点认为某节点挂掉就确认挂掉,因此我们搭建的集群最好是奇数台(>=3)。又由于为了高可用性,每个节点需要有备份节点,因此我们搭建Redis集群至少要有6台虚拟机。下面说下步骤:

第一步:新建6台虚拟机

         大家可以参考http://blog.csdn.net/u012453843/article/details/68947589这篇博客进行搭建

第二步:为每台虚拟机安装redis

         大家可以参考http://blog.csdn.net/u012453843/article/details/70254865这篇博客进行安装

第三步:修改配置文件

        首先将解压包中的redis.conf文件复制到/usr/local/redis/bin目录下

  1. [root@redis1 redis-3.0.0]# pwd
  2. /usr/local/redis-3.0.0
  3. [root@redis1 redis-3.0.0]# cp redis.conf /usr/local/redis/bin/
  4. [root@redis1 redis-3.0.0]# cd /usr/local/redis/bin
  5. [root@redis1 bin]# ll
  6. 总用量 15484
  7. -rwxr-xr-x. 1 root root 4588854 4月 21 05:18 redis-benchmark
  8. -rwxr-xr-x. 1 root root 22177 4月 21 05:18 redis-check-aof
  9. -rwxr-xr-x. 1 root root 45395 4月 21 05:18 redis-check-dump
  10. -rwxr-xr-x. 1 root root 4691761 4月 21 05:18 redis-cli
  11. -rw-r--r--. 1 root root 41403 4月 21 05:28 redis.conf
  12. lrwxrwxrwx. 1 root root 12 4月 21 05:18 redis-sentinel -> redis-server
  13. -rwxr-xr-x. 1 root root 6450289 4月 21 05:18 redis-server
  14. [root@redis1 bin]#
         接着修改redis.conf文件,需要修改两处地方,第一处是要开启后台运行功能,点击Xshell工具的"编辑"菜单,在下拉菜单中点击"查找",在查找对话框中输入"daemonize"即可搜索到相关配置,该配置原来默认值是"no",我们现在把它改为"yes"。


       第二处修改是开启集群,在搜索框中输入"cluster-enabled"便可找到这项配置,该配置原来是被注释掉的,我们把前面的那个注释符"#"去掉,如下图所示。


       这样第一台虚拟机便配置好了,由于六台虚拟机的这两项配置都一样,因此我们把刚修改好的这份配置文件复制到其它5台虚拟机上。

  1. [root@redis1 bin]# scp redis.conf 192.168.156.16:/usr/local/redis/bin/
  2. [root@redis1 bin]# scp redis.conf 192.168.156.17:/usr/local/redis/bin/
  3. [root@redis1 bin]# scp redis.conf 192.168.156.18:/usr/local/redis/bin/
  4. [root@redis1 bin]# scp redis.conf 192.168.156.19:/usr/local/redis/bin/
  5. [root@redis1 bin]# scp redis.conf 192.168.156.20:/usr/local/redis/bin/

第四步:设置开机自启动
        为了避免以后集群所有设备都手工启动redis,可以为这6台设备设置开机自启动,在/etc/rc.d/rc.local文件当中添加/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf这一行命令。     

  1. [root@redis1 bin]# vim /etc/rc.d/rc.local
  2. #!/bin/sh
  3. #
  4. # This script will be executed *after* all the other init scripts.
  5. # You can put your own initialization stuff in here if you don't
  6. # want to do the full Sys V style init stuff.
  7. touch /var/lock/subsys/local
  8. /usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf

第五步:启动六台设备的redis。

        以其中一台设备为例,如下所示。

  1. [root@redis1 bin]# /usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
  2. [root@redis1 bin]# ps aux|grep redis
  3. root 6222 0.2 1.0 137456 2500 ? Ssl 07:00 0:00 /usr/local/redis/bin/redis-server *:6379 [cluster]
  4. root 6256 0.0 0.3 103336 896 pts/1 S+ 07:00 0:00 grep redis
  5. [root@redis1 bin]#

第六步:安装ruby环境
        集群的搭建需要用到ruby环境,因此我们需要安装ruby环境,由于六台设备都需要安装ruby环境,因此我们直接在XShell工具的下面的输入框中输入安装命令(要确认当前 作用的窗口是所有窗口,就是左边的图标是多窗口图标,如果不是多窗口可以点击输入框右边的"三条横线"图标切换窗口)回车即可在六个窗口同时运行yum install ruby命令。


      安装完ruby之后,我们安装rubygem(也就是ruby第三方包管理工具),使用命令yum install rubygems,如下图所示



        安装完ruby和rubygems之后,我们需要安装ruby脚本运行所需要的一个包redis-3.0.0.gem。这个包大家可以到:http://download.csdn.net/detail/u012453843/9821251这个地址进行下载,下载完后上传到每台 设备的/usr/local/software目录下,如下所示。

  1. [root@redis1 redis-3.0.0]# cd /usr/local/software/
  2. [root@redis1 software]# ll
  3. 总用量 1388
  4. -rw-r--r--. 1 root root 57856 4月 21 2017 redis-3.0.0.gem
  5. -rw-r--r--. 1 root root 1358081 4月 20 11:15 redis-3.0.0.tar.gz
  6. [root@redis1 software]#

       下面来安装这个第三方包,在下面的那个输入框中输入gem install redis-3.0.0.gem然后回车,在六个窗口同时进行安装,其中一台的安装信息如下。

  1. [root@redis1 software]# gem install redis-3.0.0.gem
  2. Successfully installed redis-3.0.0
  3. 1 gem installed
  4. Installing ri documentation for redis-3.0.0...
  5. Installing RDoc documentation for redis-3.0.0...
  6. [root@redis1 software]#

第七步:安装集群
        上面做了那么多准备其实是为一个脚本文件(redis-trib.rb)服务的,这个脚本的位置在/usr/local/redis-3.0.0/src目录下,如下所示

  1. [root@redis1 src]# pwd
  2. /usr/local/redis-3.0.0/src
  3. [root@redis1 src]# ll *.rb
  4. -rwxrwxr-x. 1 root root 48141 4月 1 2015 redis-trib.rb
  5. [root@redis1 src]#

         为方便管理,我们把这个脚本复制到/usr/local/redis/bin目录下,如下所示

  1. [root@redis1 src]# cp redis-trib.rb /usr/local/redis/bin
  2. [root@redis1 src]#

         下面正式搭建集群,命令中--replicas是指定每个节点备份的节点的数量,我们现在是每个节点备份一个,因此输入1。如下所示,可以看到从主节点是随机组成的,主节点是192.168.156.17、192.168.156.18、192.168.156.19这三台设备,192.168.156.15、192.168.156.16、192.168.20这三台是备用节点。Adding replica 192.168.156.16:6379 to 192.168.156.19:6379的意思是192.168.156.16作为192.168.156.19的从节点,同理,192.168.156.15作为了192.168.156.18的从节点,192.168.156.20作为了192.168.156.17的从节点。这样我们的集群便搭建完了。

  1. [root@redis1 bin]# ./redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379
  2. >>> Creating cluster
  3. Connecting to node 192.168.156.15:6379: OK
  4. Connecting to node 192.168.156.16:6379: OK
  5. Connecting to node 192.168.156.17:6379: OK
  6. Connecting to node 192.168.156.18:6379: OK
  7. Connecting to node 192.168.156.19:6379: OK
  8. Connecting to node 192.168.156.20:6379: OK
  9. >>> Performing hash slots allocation on 6 nodes...
  10. Using 3 masters:
  11. 192.168.156.19:6379
  12. 192.168.156.18:6379
  13. 192.168.156.17:6379
  14. Adding replica 192.168.156.16:6379 to 192.168.156.19:6379
  15. Adding replica 192.168.156.15:6379 to 192.168.156.18:6379
  16. Adding replica 192.168.156.20:6379 to 192.168.156.17:6379
  17. S: 076bec0407edac2a4d10e4ceaf62d7edf85013ad 192.168.156.15:6379
  18. replicates 42b5398f180aa12951de65757485de6202e9691f
  19. S: bbe64932ee438edf6cb72023457dd503546434f4 192.168.156.16:6379
  20. replicates 138fe0c66e6ee6f33b2f86ff878ad5e2766db281
  21. M: 424f48fe202d6a963938b1073e1d898a1c06621a 192.168.156.17:6379
  22. slots:10923-16383 (5461 slots) master
  23. M: 42b5398f180aa12951de65757485de6202e9691f 192.168.156.18:6379
  24. slots:5461-10922 (5462 slots) master
  25. M: 138fe0c66e6ee6f33b2f86ff878ad5e2766db281 192.168.156.19:6379
  26. slots:0-5460 (5461 slots) master
  27. S: af52e00584397ef503e90cbf76b1aaae3265e9e2 192.168.156.20:6379
  28. replicates 424f48fe202d6a963938b1073e1d898a1c06621a
  29. Can I set the above configuration? (type 'yes' to accept): yes
  30. >>> Nodes configuration updated
  31. >>> Assign a different config epoch to each node
  32. >>> Sending CLUSTER MEET messages to join the cluster
  33. Waiting for the cluster to join.......
  34. >>> Performing Cluster Check (using node 192.168.156.15:6379)
  35. M: 076bec0407edac2a4d10e4ceaf62d7edf85013ad 192.168.156.15:6379
  36. slots: (0 slots) master
  37. replicates 42b5398f180aa12951de65757485de6202e9691f
  38. M: bbe64932ee438edf6cb72023457dd503546434f4 192.168.156.16:6379
  39. slots: (0 slots) master
  40. replicates 138fe0c66e6ee6f33b2f86ff878ad5e2766db281
  41. M: 424f48fe202d6a963938b1073e1d898a1c06621a 192.168.156.17:6379
  42. slots:10923-16383 (5461 slots) master
  43. M: 42b5398f180aa12951de65757485de6202e9691f 192.168.156.18:6379
  44. slots:5461-10922 (5462 slots) master
  45. M: 138fe0c66e6ee6f33b2f86ff878ad5e2766db281 192.168.156.19:6379
  46. slots:0-5460 (5461 slots) master
  47. M: af52e00584397ef503e90cbf76b1aaae3265e9e2 192.168.156.20:6379
  48. slots: (0 slots) master
  49. replicates 424f48fe202d6a963938b1073e1d898a1c06621a
  50. [OK] All nodes agree about slots configuration.
  51. >>> Check for open slots...
  52. >>> Check slots coverage...
  53. [OK] All 16384 slots covered.
  54. [root@redis1 bin]#

测试:

首先启动Redis集群使用命令/usr/local/redis/bin/redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379进行启动,如下所示。可以看到192.168.156.18、192.168.156.19、192.168.156.20这三个节点是主节点,另外三个节点是从节点。槽号为0-5460的卡槽被分配到了192.168.156.20上,5461-10922被分配到了192.168.156.19上,10923-16383被分配到了192.168.156.18上。

  1. [root@redis1 ~]# /usr/local/redis/bin/redis-trib.rb create --replicas 1 192.168.156.15:6379 192.168.156.16:6379 192.168.156.17:6379 192.168.156.18:6379 192.168.156.19:6379 192.168.156.20:6379
  2. >>> Creating cluster
  3. Connecting to node 192.168.156.15:6379: OK
  4. Connecting to node 192.168.156.16:6379: OK
  5. Connecting to node 192.168.156.17:6379: OK
  6. Connecting to node 192.168.156.18:6379: OK
  7. Connecting to node 192.168.156.19:6379: OK
  8. Connecting to node 192.168.156.20:6379: OK
  9. >>> Performing hash slots allocation on 6 nodes...
  10. Using 3 masters:
  11. 192.168.156.20:6379
  12. 192.168.156.19:6379
  13. 192.168.156.18:6379
  14. Adding replica 192.168.156.17:6379 to 192.168.156.20:6379
  15. Adding replica 192.168.156.16:6379 to 192.168.156.19:6379
  16. Adding replica 192.168.156.15:6379 to 192.168.156.18:6379
  17. S: 0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379
  18. replicates 423f334654c3dfdacd39927e0528a95c38aa933f
  19. S: 4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379
  20. replicates b69de3b87aeefac1d4711dd644a8dd5815c56bec
  21. S: 149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379
  22. replicates 6808fa38709cac3a6ec4b232fd1e45980cbb0c96
  23. M: 423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379
  24. slots:10923-16383 (5461 slots) master
  25. M: b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379
  26. slots:5461-10922 (5462 slots) master
  27. M: 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379
  28. slots:0-5460 (5461 slots) master
  29. Can I set the above configuration? (type 'yes' to accept): yes
  30. >>> Nodes configuration updated
  31. >>> Assign a different config epoch to each node
  32. >>> Sending CLUSTER MEET messages to join the cluster
  33. Waiting for the cluster to join....
  34. >>> Performing Cluster Check (using node 192.168.156.15:6379)
  35. M: 0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379
  36. slots: (0 slots) master
  37. replicates 423f334654c3dfdacd39927e0528a95c38aa933f
  38. M: 4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379
  39. slots: (0 slots) master
  40. replicates b69de3b87aeefac1d4711dd644a8dd5815c56bec
  41. M: 149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379
  42. slots: (0 slots) master
  43. replicates 6808fa38709cac3a6ec4b232fd1e45980cbb0c96
  44. M: 423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379
  45. slots:10923-16383 (5461 slots) master
  46. M: b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379
  47. slots:5461-10922 (5462 slots) master
  48. M: 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379
  49. slots:0-5460 (5461 slots) master
  50. [OK] All nodes agree about slots configuration.
  51. >>> Check for open slots...
  52. >>> Check slots coverage...

      既然集群已经启动好了,我们使用redis客户端随意连接一台设备进行测试,比如我们连接192.168.156.16这台设备(这是个从节点,从属于192.168.156.19),如下所示(注意:一定要加上参数"-c"否则没办法重定向 到其它节点)。

  1. [root@redis2 bin]# ./redis-cli -h 192.168.156.16 -p 6379 -c
  2. 192.168.156.16:6379>
      连接上之后,我们先来保存key1,它的值是123,如下所示,可以看到,这个key1经过算法并对16384进行求余之后的数字是9189,这个槽号是在192.168.156.19上,因此key1被保存到了192.168.156.19上。
  1. 192.168.156.16:6379> set key1 123
  2. -> Redirected to slot [9189] located at 192.168.156.19:6379
  3. OK
  4. 192.168.156.19:6379>

      我们再接着保存key2、key3、key4,如下所示,可以看到key2所对应的槽号是4998,显然是在192.168.156.20上,key3所对应的槽号也在0-5640,因此set key2的时候根本就没有重定向,还是停留在192.168.156.20上。key4所对应的槽号是13120,显然是在192.168.156.18上因此被保存到了192.168.156.18上。

  1. 192.168.156.19:6379> set key2 111
  2. -> Redirected to slot [4998] located at 192.168.156.20:6379
  3. OK
  4. 192.168.156.20:6379> set key3 aaa
  5. OK
  6. 192.168.156.20:6379> set key4 bbb
  7. -> Redirected to slot [13120] located at 192.168.156.18:6379
  8. OK
  9. 192.168.156.18:6379>

       我们可以使用命令cluster info查看集群的某些信息,如下所示,可以看到当前集群的状态是OK的,所有的槽号都已分配完毕,没有失败的节点。所有的节点数是6,当前提供服务的有3台

  1. 192.168.156.18:6379> cluster info
  2. cluster_state:ok
  3. cluster_slots_assigned:16384
  4. cluster_slots_ok:16384
  5. cluster_slots_pfail:0
  6. cluster_slots_fail:0
  7. cluster_known_nodes:6
  8. cluster_size:3
  9. cluster_current_epoch:6
  10. cluster_my_epoch:4
  11. cluster_stats_messages_sent:10748
  12. cluster_stats_messages_received:10748
  13. 192.168.156.18:6379>

        还可以通过命令cluster nodes来查看节点信息。

  1. 192.168.156.18:6379> cluster nodes
  2. 423f334654c3dfdacd39927e0528a95c38aa933f 192.168.156.18:6379 myself,master - 0 0 4 connected 10923-16383
  3. 4eecf66148e88917b4ecf4b36e794a6e83e4fe85 192.168.156.16:6379 slave b69de3b87aeefac1d4711dd644a8dd5815c56bec 0 1492869406355 5 connected
  4. 0cbe6fc270afa701156c5dc9c47dba522dd62737 192.168.156.15:6379 slave 423f334654c3dfdacd39927e0528a95c38aa933f 0 1492869405340 4 connected
  5. 149c9e9a0e0febd581193df17d509ce4970e4163 192.168.156.17:6379 slave 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 0 1492869402275 6 connected
  6. 6808fa38709cac3a6ec4b232fd1e45980cbb0c96 192.168.156.20:6379 master - 0 1492869408383 6 connected 0-5460
  7. b69de3b87aeefac1d4711dd644a8dd5815c56bec 192.168.156.19:6379 master - 0 1492869407370 5 connected 5461-10922
  8. 192.168.156.18:6379>

      下面使用JedisCluster来测试集群,我们在taotao-content-service工程的测试类中再添加一个测试方法(与第三十课结合学习),如下所示。运行,发现是可以正常输出"hello jedis cluster"的。

  1. @Test
  2. public void testJedisCluster(){
  3. //创建构造参数Set类型,集合中每个元素是HostAndPort类型
  4. Set <HostAndPort> nodes = new HashSet <>();
  5. //向集合中添加节点
  6. nodes.add(new HostAndPort("192.168.156.15", 6379));
  7. nodes.add(new HostAndPort("192.168.156.16", 6379));
  8. nodes.add(new HostAndPort("192.168.156.17", 6379));
  9. nodes.add(new HostAndPort("192.168.156.18", 6379));
  10. nodes.add(new HostAndPort("192.168.156.19", 6379));
  11. nodes.add(new HostAndPort("192.168.156.20", 6379));
  12. //创建JedisCluster对象
  13. JedisCluster jedisCluster = new JedisCluster(nodes);
  14. //直接使用jedisCluster,自带连接池,jedisCluster可以是单例的
  15. jedisCluster.set("jedis-cluster", "hello jedis cluster");
  16. String result = jedisCluster.get("jedis-cluster");
  17. System.out.println(result);
  18. //系统关闭前关闭jedisCluster
  19. jedisCluster.close();
  20. }
        
      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值