redis04_ 集群模式(cluster)

一、集群模式

1.1 集群模式的作用

        redis 为了提高项目响应速度,经常把热点数据(项目中经常访问的数据)保存到缓存中不是直接从数据库获取。一般大型网站存在28定律,80%的访问量集中在20%的业务,20%业务产生的数据就是热点数据,大型网站热点数据量往往是巨大,单台的缓存服务器是无法满足需求的(单台服务器内存有限),使用多台进行集群作为缓存服务器。

1)高可用,防止单点故障

2)高性能,集群后,集群中每个一节点和单机版能力同级的

3)扩展方便,按需动态增加或者减少集群中节点的数量

4)解决的master写压力 (使用集群可以多个主节点同时写)

1.2 集群模式的优缺点

        优点:

        1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

        2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

        3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

               假如1000个节点    16384    一个节点上只放  16.3 槽     数据更均匀的存放不同的服

        务器,假如该服务器的内存全用来缓存,能缓存的数据会更多    

        4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

        5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成

        Slave到 Master 的角色提升。

        Gossip (疫情传播算法)过程是由种子节点发起,当一个种子节点有状态需要更新到网络中的其他节点时,它会随机的选择周围几个节点散播消息,收到消息的节点也会重复该过程,直至最终网络中所有的节点都收到了消息。

        缺点:

        1、资源隔离性较差,容易出现相互影响的情况(多个应用同时使用一个redis集群时,可能会出现)。

        2、数据通过异步复制,不保证数据的强一致性

        3、自动故障切换时,集群状态fail 无法对外提供服务

二、集群模式的实现

 2.1 集群模式规划图

2.2 集群模式的具体配置

2.2.1 具体配置

        在3台redis服务器创建集群目录,在allsession中执行:

                mkdir /usr/redis/cluster

        查看,在allsession中执行:

                ls /usr/redis/

        分别在redis1,redis2,redis3执行:

                mkdir /usr/redis/cluster/8001  /usr/redis/cluster/8002 redis1执行

                ls /usr/redis/cluster

                mkdir /usr/redis/cluster/8003  /usr/redis/cluster/8004 redis2执行

                mkdir /usr/redis/cluster/8005  /usr/redis/cluster/8006 redis3执行

        复制配置文件到集群节点目录下,在redis1操作

                 cp /usr/redis/redis-5.0.5/redis.conf   /usr/redis/cluster/8001/

        修改配置文件,配置集群:

                vim /usr/redis/cluster/8001/redis.conf

        具体配置

        bind 本机ip    //默认ip为127.0.0.1 需要改为其他节点机器可访问的ip 否则创建集群时无法访问对应的端口,无法创建集群

        :69              bind 192.168.140.41

        : 92              port 8001

        :136           daemonize    yes                                //redis后台运行

         :158          pidfile  /var/run/redis_8001.pid          //保存进程id

         :699        appendonly  yes      //aof日志开启  有需要就开启,它会每次写操作都记录一条日志

        :729         appendonly everysec   

        : 832      appendonly everysec         //开启集群  把注释#去掉

        :840     cluster-config-file  nodes_8001.conf   //集群的配置  配置文件首次启动自动生成

         :846     cluster-node-timeout  15000         //请求超时  默认15秒,可自行设置

        复制已经配置好的文件到其他集群节点下:

         在redis1执行    将redis1中文件cp到redis2、redis3中

 远程登录:   方式一 :scp    方式二:ssh

复制已经配置好的文件到其他集群节点下:

 方式一:操作

redis1执行 

        cp /usr/redis/cluster/8001/redis.conf  /usr/redis/cluster/8002/       

        scp /usr/redis/cluster/8001/redis.conf  192.168.140.42:/usr/redis/cluster/8003/

        scp /usr/redis/cluster/8001/redis.conf  192.168.140.43:/usr/redis/cluster/8005/

 在redis2中执行

         ls /usr/redis/cluster/8003/ 

        scp /usr/redis/cluster/8003/redis.conf  /usr/redis/cluster/8004/

在redis3中执行

         ls /usr/redis/cluster/8005/ 

        scp /usr/redis/cluster/8005/redis.conf  /usr/redis/cluster/8006/

修改redis.conf配置文件(8002、8003、8004、8005、8006)

  在redis1中操作(redis2、redis3类似) 

        vim /usr/redis/cluster/8002/redis.conf

        :69     看IP是否需要改        (01-02、03-04、05-06一致)

        输入   :%s/8001/8002/g      将文件中8001替换为8002  8003  8004 8005 8006

        :92     :158     :840        查看全部替换为8002

redis1中操作:ssh 192.168.140.42 

在redis2的test811文件夹下添加文件和文件夹

 redis2中操作: ls

2.2.2 启动所有节点,创建集群,测试集群

        启动所有节点

        redis1执行:

                /usr/redis/bin/redis-server  /usr/redis/cluster/8001/redis.conf

                /usr/redis/bin/redis-server  /usr/redis/cluster/8002/redis.conf

                ps -ef |grep redis |grep -v grep 查看是否启动成功

        redis2执行

                /usr/redis/bin/redis-server  /usr/redis/cluster/8003/redis.conf

                /usr/redis/bin/redis-server  /usr/redis/cluster/8004/redis.conf

                ps -ef |grep redis |grep -v grep 查看是否启动成功

        redis3执行:

                /usr/redis/bin/redis-server  /usr/redis/cluster/8005/redis.conf

                /usr/redis/bin/redis-server  /usr/redis/cluster/8006/redis.conf

                ps -ef |grep redis |grep -v grep 查看是否启动成功

        创建集群:

        语法:

        redis-cli --cluster         执行是集群操作

        create                          创建集群

        ip:port                          ip:port 参与集群的所有节点 中间用空格分割

        --cluster-replicas 1 执行集群中一个主节点的从节点个数(当前总结是6,1主1从,最终为3主,3从)

        /usr/redis/bin/redis-cli --cluster create 192.168.140.41:8001 192.168.140.41:8002 192.168.140.42:8003 192.168.140.42:8004 192.168.140.43:8005 192.168.140.43:8006 --cluster-replicas 1 

看到该提示,说明成功

2.2.3  测试:

        客户端连接集群:

        语法:

        redis-cli -c 连接集群               

        -h ip/host 指定要连接的主机或者IP

        -p port 指定主机上redis实例端口 

        redis1上操作

                /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8001 -c

                cluster info                提供当前集群节点状态信息

         cluster nodes               获取集群节点配置(显示主从配置信息)

2.2.4 启动关闭集群脚本:

        上面步骤知道了集群启动和关闭,如果要频繁的启动或关闭,非常麻烦,所以使用启动关闭脚本,来完成集群的启动和关闭。

       创建一个脚本文件夹存放脚本文件

        mkidr  shelldir

        创建脚本文件

        vim shelldir/redis-start-stop.sh

        编写脚本文件

#!/bin/bash
# 判断redis进程是否运行
#定义一个变量并赋值为当前服务器运行redis-server进程的数量
redisServerNum=`ps -ef |grep redis-server |grep -v grep|wc -l`
#判断当前服务器有没有redis服务进程在运行 如果没有启动,如果有关闭
if [ $redisServerNum == 0 ]; then
  echo 'redis集群开始启动'
  ssh 192.168.140.41 /usr/redis/bin/redis-server  /usr/redis/cluster/8001/redis.conf
  ssh 192.168.140.41 /usr/redis/bin/redis-server  /usr/redis/cluster/8002/redis.conf
  ssh 192.168.140.42 /usr/redis/bin/redis-server  /usr/redis/cluster/8003/redis.conf
  ssh 192.168.140.42 /usr/redis/bin/redis-server  /usr/redis/cluster/8004/redis.conf
  ssh 192.168.140.43 /usr/redis/bin/redis-server  /usr/redis/cluster/8005/redis.conf
  ssh 192.168.140.43 /usr/redis/bin/redis-server  /usr/redis/cluster/8006/redis.conf
  echo 'redis集群启动完毕'
else
  echo 'redis集群开始关闭'
  ssh 192.168.140.41 /usr/redis/bin/redis-cli  -h 192.168.140.41 -p 8001 shutdown
  ssh 192.168.140.41 /usr/redis/bin/redis-cli  -h 192.168.140.41 -p 8002 shutdown
  ssh 192.168.140.42 /usr/redis/bin/redis-cli  -h 192.168.140.42 -p 8003 shutdown
  ssh 192.168.140.42 /usr/redis/bin/redis-cli  -h 192.168.140.42 -p 8004 shutdown
  ssh 192.168.140.43 /usr/redis/bin/redis-cli  -h 192.168.140.43 -p 8005 shutdown
  ssh 192.168.140.43 /usr/redis/bin/redis-cli  -h 192.168.170.43 -p 8006 shutdown
  echo 'redis集群关闭完毕'
fi

给脚本赋权限 

chmod u+x shelldir/redis-start-stop.sh 

可以反复执行,启动或者关闭

./shelldir/redis-start-stop.sh 

2.2.5 cluster原理(集群实现细节)

一、节点-槽-值的关系

        使用脚本启动集群

         /root/shelldir/redis-start-stop.sh

        连接集群

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8001

        使用cluster info 查看集群状态信息

 使用cluster nodes 查看节点主从信息

从上图可以看出主从关系:

        槽slot:redis存放数据的单位 槽的总数量是16384 在创建集群会按照配置的主节点数量,大概平均分配在不同的节点上

当前登录的节点显示myself

槽和值的关系:

        redis中存放数据都是键值对方式进行存储,所有的数据类型存入redis时都有对应的key, 每次向redis写入数据时,redis会根据key的值使用CRC16算法进行计算得到一个数字,再使用该数字对16384取余,余数是几就会把该数据放入该槽中。

使用客户端连接执行下面命令,如果set没有跳转就使用get:

                         槽                                      主节点        从节点            槽

set  aaa 111    10439                                 8004            8001            0-5460

set  bbb 222    5287                                   8003            8006           5461-10922

set  ddd 444    11367                                 8005            8002           10923-16383

 key所在的卡槽不在这个节点所在的范围  通过get进行跳转

          数据(key-value)                  槽                 节点

CRC16('aaa')%16384=10439         10439         8003[5461-10922]

CRC16('bbb')%16384=5287            5287          8001[ 0-5460 ]

CRC16('ddd')%16384=11367          5287          8005[ 10923-16383 ]

二、集群架构的实现细节

  • 所有的redis节点相互都是互联的,内部使用(ping-pong)机制。
  • 集群某一个节点如果失败fail,并不是一个节点说了算,而是集群中超过半数的节点都和该节点无法通信,表明该节点失败fail
  • 客户端连接集群时,不需要连接集群所有节点,只需要连接集群中任意一个节点
  • 每个节点都会保存各自的数据和整个集群的状态

三、集群的自动故障切换

        在创建集群时,为了保证集群的高可用,设置了1主1从,实际工作使用过程中,可以设置1主多从,让集群具有更高可用性。平时进行数据读写时都是主节点来执行,从节点使用主从同步,备份主节点数据,当主机点意外宕机,从节点就会自动转换为主节点,当前主节点保存的数据就可以正常的读写。如果主节点恢复,自动变为从节点。

        当前集群中的主从关系:

        主节点         从节点

        8004             8001

        8003             8006

        8005             8002

        让8004节点宕机(直接使用下面命令关闭8004 redis实例)

        /usr/redis/bin/redis-cli  -h 192.168.140.42 -p 8004 shutdown

        ps -ef |grep redis-server |grep -v grep      就剩8002

        等待一定时长 后,使用除了8004之外的其他节点进行连接

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8002 -c

        cluster info 发现ok

        然后使用cluster nodes

发现 8001变为主节点 8004还处于失败状态

退出     quit

在redis2中 让8004恢复正常

/usr/redis/bin/redis-server  /usr/redis/cluster/8004/redis.conf

稍等后查看节点主从情况

         这就是自动故障替换  即当master宕机后自动将他的从节点转换为master

        当前集群中的主从关系变为:

        主节点         从节点

        8001            8004

        8003            8006

        8005            8002

四、集群的失败

1、当没有从节点的主节点宕机,集群状态会失败

        当前集群中的主从关系变为:

        主节点         从节点

        8001             8004

        8003             8006

        8005             8002

        先让8006 从节点宕机

        /usr/redis/bin/redis-cli  -h 192.168.140.43 -p 8006 shutdown

       在redis中查看  ps -ef |grep redis-server |grep -v grep

        使用除了8006任意节点进行连接:

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8002 -c

        cluster info       发现 ok

        cluster nodes   发现 8006 slave,fail

        在让8003宕机

        /usr/redis/bin/redis-cli  -h 192.168.140.42 -p 8003 shutdown

        使用除了8003、8006任意节点进行连接:

         /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8002 -2

        cluster info     

        cluster nodes    发现 8006 slave,fail     8003 master,fail

2、当超过半数的主节点同时宕机,集群状态会失败

        上面演示效果时,把8003和8006关掉了,再次启动他们,让集群正常

        /usr/redis/bin/redis-server  /usr/redis/cluster/8003/redis.conf

        /usr/redis/bin/redis-server  /usr/redis/cluster/8006/redis.conf

        让两个主节点同时宕机,中间间隔不能超过15秒:     

        当前集群中的主从关系变为:

        主节点         从节点

        8001             8004

        8003             8006

        8005             8002

        让8003 8005 宕机

        /usr/redis/bin/redis-cli -c  -h 192.168.140.42 -p 8003 shutdown

        /usr/redis/bin/redis-cli -c  -h 192.168.140.43 -p 8005 shutdown

        使用除了8003和8005节点进行连接:

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8002 -c

 三、密钥免密登录

        上面每次复制文件时,都必须输入正确密码,向远程服务器复制了4次,需要输入4次密码,能不能不用输入密码,来完成复制或者远程登录

        一般在使用ssh 或者是scp命令时,要免密登录

具体使用:

        ls -a         在当前登录用户的主目录查看 发现一个.ssh目录 这个目录就是生成公钥和私钥目录,如果从来没有执行ssh或者scp 就没有该目录

        ls .ssh/    发现只有一个kwon_hosts

         ssh-keygen -t rsa  使用rsa加密方式生成公钥和私钥 (非对称加密) 回车3次

         ls .ssh/    多出来两个文件

        id_rsa  私钥文件(不用于传输) id_rsa.pub pub=public  公钥文件(用于传输)

私钥加密的内容,必须是公钥解密 公钥加密的内容,必须是私钥解码

        cat .ssh/id_rsa.pub    查看公钥内容

        ssh-copy-id 192.168.140.42  发送公钥到要免密登录的服务器上,第一次发送公钥是需要密码 没有执行前,可以查看远程服务器是否存在公钥文件   

        ls -a       在redis2执行 发现有.ssh目录

        ls .ssh    在redis2执行 发现有 authorized_keys

        cat .ssh/authorized_keys 

 ssh 192.168.140.42  再执行远程登录ssh或者远程scp 发现不需要输入密码,具体原理如下

四、集群模式启动失败修复

        当之前集群模式配置正常后,由于某种原因造成启动失败后的修复

 

        在allsession中输入:  

        rm -rf appendonly.aof dump.rdb nodes-800*     

        移除appendonly.aof  、dump.rdb  、和以nodes-800开头的文件

        再一次输入启动脚本,启动所有节点:

        ./shelldir/redis-start-stop.sh

        在通过下面指令使客户端连接到服务器:

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8001

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8002

         重新创建集群:

/usr/redis/bin/redis-cli --cluster create 192.168.140.41:8001 192.168.140.41:8002 192.168.140.42:8003 192.168.140.42:8004 192.168.140.43:8005 192.168.140.43:8006 --cluster-replicas 1

        随便连接一个节点查看集群的状态

        /usr/redis/bin/redis-cli -c  -h 192.168.140.41 -p 8001

        cluster info 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸡本蔡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值