Redis - (二)主从复制、哨兵模式、集群

目录

Redis主从复制

1.是什么

2.能干嘛

3.怎么玩

4.全量复制消耗

5.缺点

redis哨兵模式

1.是什么,能干嘛?

2.哨兵主要功能(做了哪些事)

3.架构

4.怎么玩(实战)?

5.故障转移演示(哨兵的监控和自动故障转移功能)

6.客户端(jedis)访问哨兵系统(自动故障转移功能)

7.基本原理

8.实践建议

9.总结

redis cluster高可用集群

1.redis cluster集群是什么?

2.redis cluster集群搭建

3.集群伸缩

4.cluster客户端

5.故障转移(与哨兵相似)

总结

redis集群演变过程

1.单机版

2.复制

3.哨兵

4.集群


Redis主从复制

1.是什么

1.单机有什么问题:

  • 单机故障
  • 容量瓶颈
  • qps瓶颈

主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,mester以写为主,slaver以读为主

从机默认不能写数据:

#设置slave是否是只读的。从2.6版起,slave默认是只读的。
replica-read-only yes

2.能干嘛

  • 1.读写分离
  • 2.容灾备份

3.怎么玩

玩法原则:

  1. 配从不配主
  2. 使用命令 SLAVEOF 动态指定主从关系 ,如果设置了密码,关联后使用 config set masterauth 密码                         SLAVEOF  ip  端口
  3. 配置文件和命令混合使用时,如果混合使用,动态指定了主从,请注意一定要修改对应的配置文件

 

1.新建redis8000,redis8001,redis8002文件夹

2.将redis.conf文件复制在redis8000下

3.分别修改个目录下的redis.conf文件

  redis8000/redis.conf

1.bind 192.168.0.104 指定本机ip
2.port 8000
3.daemonize yes
4.pidfile /var/run/redis_8000.pid
5.dir /myredis/redis8000
6.requirepass 123456

4.把redis8000/redis.conf文件复制到redis8001,redis8002下

  redis8001/redis.conf

    1. :%s/8000/8001/g 批量替换
    #replicaof 设置当本机为slave服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步
    2. replicaof 192.168.0.104 8000
    3. masterauth 123456

redis8002/redis.conf

    1.  :%s/8000/8002/g    批量替换
    2.  replicaof 192.168.0.104 8000
    3.  masterauth 123456

5.分别启动8000.8001,8002实例

[root@localhost myredis]# /usr/local/bin/redis-server /myredis/redis8000/redis.conf

[root@localhost myredis]# /usr/local/bin/redis-server /myredis/redis8001/redis.conf

[root@localhost myredis]# /usr/local/bin/redis-server /myredis/redis8002/redis.conf

6.客户端连接

/usr/local/bin/redis-cli -h 192.168.0.104 -p 8000 -a 123456

/usr/local/bin/redis-cli -h 192.168.0.104 -p 8001 -a 123456

/usr/local/bin/redis-cli -h 192.168.0.104 -p 8002 -a 123456

查看主从信息  info replication   

 

4.全量复制消耗

  1. bgsave时间
  2. rdb文件网络传输
  3. 从节点请求数据时间
  4. 从节点加载rdb的时间
  5. 可能的aof重写时间

5.缺点

1.由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

2.当主机宕机之后,将不能进行写操作,需要手动将从机升级为主机,从机需要重新制定master

简单总结:

一个master可以有多个Slave

一个slave只能有一个master

数据流向是单向的,只能从主到从

 

redis哨兵模式

1.是什么,能干嘛?

在Redis 2.8版本开始引入。哨兵的核心功能是主节点的自动故障转移。

通俗来讲哨兵模式的出现是就是为了解决我们主从复制模式中需要我们人为操作的东西变为自动版,并且它比人为要更及时

2.哨兵主要功能(做了哪些事)

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障转移(Automatic Failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configuration Provider):客户端在初始化时,通过连接哨兵来获得当前Redis服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。

3.架构

哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的Redis节点,不存储数据。

数据节点:主节点和从节点都是数据节点。

4.怎么玩(实战)?

1.部署主从节点

哨兵系统中的主从节点,与普通的主从节点配置是一样的,并不需要做任何额外配置。

2.部署哨兵节点

哨兵节点本质上是特殊的Redis节点。

3个哨兵节点的配置几乎是完全一样的,主要区别在于端口号的不同(26379 / 26380 / 26381)下面以26379节点为例介绍节点的配置和启动方式;配置部分尽量简化:

#####sentinel-26379.conf

port 26379

daemonize yes

logfile "26379.log"

sentinel monitor mymaster 192.168.0.104 6379 2

其中,sentinel monitor mymaster 192.168. 92.128 6379 2配置的含义是:该哨兵节点监控192.168.0.104 6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移。

哨兵节点的启动有两种方式,二者作用是完全相同的:

redis-sentinel sentinel-26379.conf

redis-server sentinel-26379.conf --sentinel

5.故障转移演示(哨兵的监控和自动故障转移功能)

使用kill命令杀掉主节点

6.客户端(jedis)访问哨兵系统(自动故障转移功能)

public static void main(String[] args)  {
        Logger logger= LoggerFactory.getLogger(TestJedisSentinel.class);
        Set set=new HashSet<>();
        set.add("192.168.0.104:28000");
        set.add("192.168.0.104:28001");
        set.add("192.168.0.104:28002");
        JedisSentinelPool jedisSentinelPool=new JedisSentinelPool("mymaster",set,"123456");
        while (true) {
            Jedis jedis=null;
            try {
                jedis = jedisSentinelPool.getResource();
                String s = UUID.randomUUID().toString();
                jedis.set("k" + s, "v" + s);
                System.out.println(jedis.get("k" + s));
                Thread.sleep(1000);
            }catch (Exception e){
                logger.error(e.getMessage());
            }finally {
                if(jedis!=null){
                    jedis.close();
                }
            }
        }
    }

7.基本原理

关于哨兵的原理,关键是了解以下几个概念:

主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就会将其进行主观下线。顾名思义,主观下线的意思是一个哨兵节点“主观地”判断下线;与主观下线相对应的是客观下线。

客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr命令询问其他哨兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则对该主节点进行客观下线。

需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

定时任务:每个哨兵节点维护了3个定时任务。定时任务的功能分别如下:

1.每10秒通过向主从节点发送info命令获取最新的主从结构;

发现slave节点

确定主从关系

2.每2秒通过发布订阅功能获取其他哨兵节点的信息;SUBSCRIBE c2 PUBLISH c2 hello-redis

交互对节点的“看法”和自身情况

3.每1秒通过向其他节点发送ping命令进行心跳检测,判断是否下线(monitor)。

心跳检测,失败判断依据

 

选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者。选举的具体过程这里不做详细描述,一般来说,哨兵选择的过程很快,谁先完成客观下线,一般就能成为领导者。

故障转移:选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为3个步骤:

在从节点中选择新的主节点:选择的原则是,

1.首先过滤掉不健康的从节点;

2.然后选择优先级最高的从节点(由replica-priority指定);如果优先级无法区分,

3.则选择复制偏移量最大的从节点;如果仍无法区分,

4.则选择runid最小的从节点。

更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节点。

将已经下线的主节点(即6379)保持关注,当6379从新上线后设置为新的主节点的从节点

8.实践建议

哨兵节点的数量应不止一个。一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;另一方面减少对下线的误判。此外,这些不同的哨兵节点应部署在不同的物理机上。

哨兵节点的数量应该是奇数,便于哨兵通过投票做出“决策”:领导者选举的决策、客观下线的决策等。

各个哨兵节点的配置应一致,包括硬件、参数等;此外应保证时间准确、一致。

 

9.总结

在主从复制的基础上,哨兵引入了主节点的自动故障转移,进一步提高了Redis的高可用性;但是哨兵的缺陷同样很明显:哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,需要我们对从节点做额外的监控、切换操作。此外,哨兵仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题

 

redis cluster高可用集群

 

1.redis cluster集群是什么?

redis cluster集群是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。Redis cluster集群不需要sentinel哨兵也能完成节点移除和故障转移的功能。需要将每个节点 设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到 1000节点。redis cluster集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单。

2.redis cluster集群搭建

1.原生搭建

   1> 首先需要修改redis配置文件(redis.conf)如下配置:bind    port    daemonize    pidfile   logfile   dbfilename   masterauth   appendonly   appendfilename   requirepass

Redis - (二)主从复制、哨兵模式、集群_第1张图片

  2> 配置开启cluster节点

  •     cluster-enabled yes(启动集群模式)
  •     cluster-config-file nodes-8001.conf(这里800x最好和port对应上)
  •     cluster-node-timeout 15000
  •     cluster-replica-validity-factor 10
  •     cluster-require-full-coverage  no

   配置一个(端口7000)后,Linux拷贝并替换文件内容命令:sed  's/7000/7001/g'  redis7000/redis.conf  redis7001/redis.conf

  3> 启动各节点

  4> meet,让集群的各节点相互认识

    cluster meet ip port

    如果A关联B,B关联C,那么A和C也会自动关联上

  5> 指派槽位

    查看crc16 算法算出key的槽位命令 cluster keyslot key

   16384/3 0-5461 5462-10922 10923-16383

   16384/4 4096

    cluster addslots slot(槽位下标)

    通过执行如下脚本进行添加:

start=$1
end=$2
port=$3
for slot in `seq ${start} ${end}`
do 
  echo "slot:${slot}"
  /usr/local/bin/redis-cli -h 127.0.0.1 -p ${port} -a 12345 cluster addslots ${slot}
done  

  6> 分配主从

    登陆到从机,执行如下命令,node-id 为要关联的主节点的nodeid

    cluster replicate node-id

  7> 以集群方式连接

    /usr/local/bin/redis-cli -h 127.0.0.1 -p 7000 -a 12345 -c

常用命令:

cluster nodes  查看集群节点

 

2.使用redis提供的rb脚本

redis cluster集群需要至少要三个master节点,我们这里搭建三个master节点,并且给每个 master再搭建一个slave节点,总共6个redis节点,由于节点数较多,这里采用在一台机器 上创建6个redis实例,并将这6个redis实例配置成集群模式,所以这里搭建的是伪集群模 式,当然真正的分布式集群的配置方法几乎一样,搭建伪集群的步骤如下:

第一步:在/usr/local下创建文件夹redis-cluster,然后在其下面分别创建6个文件夾如下

(1)mkdir -p /usr/local/redis-cluster

(2)mkdir 8001、 mkdir 8002、 mkdir 8003、 mkdir 8004、 mkdir 8005、 mkdir 8006

第二步:把之前的redis.conf配置文件copy到8001下,修改如下内容:

(1)daemonize yes (2)port 8001(分别对每个机器的端口号进行设置) (3)bind 127.0.0.1(如果只在本机玩则可以指定为127.0.0.1 如果需要外网访问则需要指定本机真实ip) 定可能会出现循环查找集群节点机器的情况) (4)dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目 录位置,不然会丢失数据) (5)cluster-enabled yes(启动集群模式) (6)cluster-config-file nodes-8001.conf(这里800x最好和port对应上) (7)cluster-node-timeout 5000 (8)appendonly yes

第三步:把修改后的配置文件,分别 copy到各个文夹下,注意每个文件要修改第2、4、6 项里的端口号,可以用批量替换: :%s/源字符串/目的字符串/g

第四步:由于 redis集群需要使用 ruby命令,所以我们需要安装 ruby(redis5.0之后省略)

(1)yum install ruby (2)yum install rubygems (3)gem install redis --version 3.0.0(安装redis和 ruby的接囗)

第五步:分别启动6个redis实例,然后检查是否启动成功

(1)/usr/local/redis/bin/redis-server /usr/local/redis-cluster/800*/redis.conf (2)ps -ef | grep redis 查看是否启动成功

第六步:在redis3的安装目录下执行 redis-trib.rb命令创建整个redis集群

(1)cd /usr/local/redis3/src (2)./redis-trib.rb create --replicas 1 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005

redis5.0使用/usr/local/bin/redis-cli --cluster create 192.168.0.104:7000 192.168.0.104:7001 192.168.0.104:7002 192.168.0.104:7003 192.168.0.104 :7004 192.168.0.104:7005 --cluster-replicas 1   // cluster-replicas后的参数,表示主节点与从节点的比例,1代表1主1从,2代表1主2从

查看集群命令帮助:

/usr/local/bin/redis-cli -h 192.168.0.104 -p 7001 --cluster help

第七步:验证集群:

(1)连接任意一个客户端即可:./redis-cli -c -h -p (-c表示集群模式,指定ip地址和端口 号)如:/usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 800* (2)进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表) (3)进行数据操作验证 (4)关闭集群则需要逐个进行关闭,使用命令: /usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 800* shutdown

3.集群伸缩

1.扩容集群

    1.准备新节点

    2.加入集群

        使用redis-cli   语法:add-node 新节点ip:端口 已存在节点ip:端口    // 添加一个主节点

        /usr/local/bin/redis-cli --cluster add-node 192.168.1.04:7006 192.168.1.04:7000

        使用原生命令   语法:cluster meet ip port 

     3.指定主从

        使用redis-cli 语法(加入时指定):add-node 新节点ip:端口 已存在节点ip:端口 --cluster-slave --cluster-master-id masterID  // 添加一个从节点,并指定其主节点

        /usr/local/bin/redis-cli --cluster add-node 192.168.1.04:7007 192.168.1.04:7000 --cluster-slave --cluster_master-id XXX

        使用原生命令 语法:cluster replicate node-id

    4.迁移槽和数据

        1> 槽迁移计划

            语法:/redis-cli --cluster reshard 已存在节点ip :端口

            /usr/local/bin/redis-cli --cluster reshard 192.168.0.104:7000

        2> 迁移数据

            执行流程:提示要分配多少槽-》接收节点ID-》all/done(all:从已有的全部节点平均分配出来,done:先输入从哪些节点分配,输入完成时输入done)

2.缩容集群

    1.下线迁移槽

        语法:redis-cli --cluster reshard --cluster-from 要迁出节点ID --cluster-to 接收槽节点ID --cluster-slots 迁出槽数量 已存在节点ip 端口

        /usr/local/bin/redis-cli --cluster reshard --cluster-from a2fdd1359d03acacf2a6e558acbc006639445d53 --cluster-to 1794864d5f8af79e88cfc0f699f02b6341c78b5c --cluster-slots 1366 192.168.0.104 7000

    2.忘记节点.关闭节点

        语法: redis-cli --cluster del-node 已存在节点ID:端口 要删除的节点ID

        /usr/local/bin/redis-cli --cluster del-node 192.168.0.104:7000 8de55e2a7419983184cede9daab5d36ee9da1fa3

4.cluster客户端

1.moved重定向:指我们发送命令时,会对发送的key进行crc16算法,得到一个数字,然而我们连接的客户端并不是管理这个数字的范围,所以会返回错误并告诉你此key应该对应的槽位,然后客户端需要捕获此异常,重新发起请求到对应的槽位

2.asx重定向:指在我们送发命令时,对应的客户端正在迁移槽位中,所以此时我们不能确定这个key是还在旧的节点中还是新的节点中

3.smart客户端

    1.从集群中选取一个可运行节点,使用cluster slots初始化槽和节点映射。

    2.将cluster slots的结果映射到本地,为每个节点创建jedispool

    3.准备执行命令

5.故障转移(与哨兵相似)

1.故障发现: 通过ping/pong消息实现故障发现(不依赖sentinel)

2.故障恢复

    1. 检查资格

        1.每个从节点检查与主节点的断开时间,过滤掉不健康的节点 

            超过cluster-node-timeout * cluster-replica-validity-factor 时间取消资格

        2.选择偏移量最大的

    2. 替换主节点

        1.当前从节点取消复制变为主节点(slaveof no one)

        2.撤销以前主节点的槽位,给新的主节点

        3.向集群广播消息,表明已经替换了故障节点

 

总结

redis集群演变过程

1.单机版

核心技术:持久化

持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。

2.复制

复制是高可用Redis的基础,哨兵和集群都是在复制基础上实现高可用的。复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷是故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。

3.哨兵

在复制的基础上,哨兵实现了自动化的故障恢复。缺陷是写操作无法负载均衡;存储能力受到单机的限制。

4.集群

通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案

Redis - (二)主从复制、哨兵模式、集群_第2张图片

Redis - (二)主从复制、哨兵模式、集群_第3张图片

你可能感兴趣的:(NoSQL)