zoukankan      html  css  js  c++  java
  • Redis集群的三种模式

    Redis是什么

    Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:

    ·         基于内存运行,性能高效

    ·         支持分布式,理论上可以无限扩展

    ·         key-value存储系统

    ·         开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API

     

    -主从(master-salver2.8之前

    redismysql一样,虽然读写都很快,但是也会产生读写压力大的情况。为了分担读的压力,Redis支持主从复制,master进行写操作,slave进行读操作。Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步

     

    -哨兵(sentinel2.8之后

    由于redis单一的主从复制模式下,容灾性较差,当集群中master由于故障下线了,那么slaver因为没有master而同步中断,因而需要人工进行故障转移工作。

    Redis2.8之后的版本提供了一种高可用的方案——哨兵模式(Sentinel),由一个或者多个哨兵节点组成Sentinel系统用于监听一个或多个redis集群,监听群内主节点以及其从节点服务提供状态,并且当监听的redis集群中master下线后,从master的从属节点中选举出新的master并维护新的主从关系。

    注:哨兵监视redis集群的同时,哨兵节点之间也会相互监听。


    哨兵模式过程

    1、监听

    sentinel在监听redis的集群过程中会周期性的对redis集群发送指令进行状态监控

    周期

    消息类型

    动作

    方向

    作用

    10s

    info命令

    哨兵每隔10s向监听的redis集群所有节点发送info命令

    sentinel --> master

    sentinel --> slave

    1、通过info指令定期更新当前节点最新的节点信息

    2、发现新加入的slave节点,确认其主从关系

    2s

    sentinel:hello订阅

    master节点上会发布一个由哨兵订阅的频道,哨兵每隔2s发送自己的信息以及主节点判断到频道上

    sentinel --> master

    1、所有的sentinel都会订阅该频道,sentinel通过该频道相互发现,同时建立连接与监听

    2sentinel之间会交换对主节点的状态,为后续领导选举与客观下线做准备

    1s

    PING - PONG

    1s会对每个masterslavesentinel发送心跳包

    sentinel --> master

    sentinel --> slave

    sentinel --> sentinel

    1、实现了对每个节点的监控,是sentinel对节点判断是否下线的依据

     

     

    2、主观下线与客观下线

    sentinel集群在监听redis集群的过程中,每个哨兵会对master发送心跳PING来确认master的存活,如果master在“一定时间范围”内不回应PONG,或者回应了一个错误的消息,该sentinel会认为当前集群的master已经无法使用(主观下线),并同时向sentinel集群中的其他节点发送sentinel ismaster-down-by-addr命令询问其他节点对主机的状态判断,当超过一定数量的sentinel确认master已经无法使用,这时候master下线的判定就认为是客观的。

    注:客观下线后故障转移决定需要由sentinel中的leader进行裁决,sentinel在发送is-master-down-by-addr的同时使用Raft实现leader选举


    3、领导者选举

    1)每个在线的Sentinel节点都有资格成为领导者,当它确认主节点主观下线时候,会向其他Sentinel节点发送sentinel is-master-down-by-addr命令, 要求将自己设置为领导者

    2)收到命令的Sentinel节点,如果没有同意过其他Sentinel节点的sentinel is-master-down-by-addr命令,将同意该请求,否则拒绝

    3)如果该Sentinel节点发现自己的票数已经大于等于max(quorum,num(sentinels)/2+1),那么它将成为领导者

    4)如果此过程没有选举出领导者,将进入下一次选举

     

     

    4、故障转移

    故障转移就是当master宕机,sentinel集群会在redis集群中,自动选择一个合适的slave节点来升级为master节点的操作,不需要人工故障转移。

     1、筛选slave成为master

    1)过滤掉无法使用的slave(主观下线,断线)未回复Sentinel节点Pong相应的节点;

    2)选择slave-priority最大的从节点(可能存在多个相同大小),如果只存在一个,则完成选择,否则继续;

    slave-priority值在redis启动文件中配置,用于决定故障转移优先级,以及数据备份时的备份顺序;

    3)选择复制偏移量最大的从节点(复制最完整的)如果存在,则完成选择,否则继续;

    redis集群中slavemaster同步时,每台slave进与redis同步并非完全同步,不同slave同步master的进度可能不一致,在info relication中存在一项参数 master_repl_offset(复制偏移量)来表记录主从同步的程度,每完成一次同步此值会进行累加,从多个slave中选择偏移量最大的slave则能选出复制maste最完整的主机;

    作用:通过对比主从节点的复制偏移量,可以判断主从节点数据是否一致。可以通过主节点的统计信息,计算出master_repl_offset-slave_offset字节量,判断主从节点复制相差的数据量,根据这个差值判定当前复制的健康度。如果主从之间复制偏移量相差较大,则可能是网络延迟或命令阻塞等原因引起

    4)选择runid(服务器运行的唯一ID)最小的从节点;

    2、对新master发送 slaveof no one 指令,停止其主从复制

    3、修改程序段连接到新的master

    4、向集群中其他slave发送指令修改为新master的从机

    5、原master重启后修改为新masterslave


    缺点:

    1、如果是从节点下线了,sentinel是不会对其进行故障转移的,连接从节点的客户端也无法获取到新的可用从节点

    2、较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

    3、集群中只有一个主节点,当写操作并发量特别大的时候,并无法缓解写操作的压力

     

    -集群(cluster3.0之后

    为了解决Redis高可用模式下集群动态扩容困难、写操作并发瓶颈问题,在3.0之后redis推出了Redis-Cluster集群模式。

    redis-cluster采用无中心结构,每个节点保存各自的数据和整个集群的状态,每个节点都和其他所有节点连接,客户端连接任意主节点可以对整个集群中数据进行读写,所有的slave节点仅用于数据备份与故障转移。 


    raft集群至少需要奇数个节点,所以至少需要3redis作为集群中的master节点,而为了实现高可用(避免挂一台导账集群无法使用)每个master至少需要一个slave来进行主从复制,所以一个redis-Cluster集群至少需要六台机器。

     

    分布式存储

    redis-Cluster集群采用分布式存储的机制,每个master以及其slave只存储自己节点下的数据,客户端与任意master节点进行读写操作,会通过cluster的集群算法路由到对应的机器上【一致性哈希算法】。

    一致性哈希算法简单的来说就是,redis-cluster把所有的redis节点映射到[0-16383]slot上(不一定是平均分配,图示中物理机的哈希值为54611092216383),每一次读写操作集群会计算key的哈希值,然后根据哈希值选择对应机器进行读写。

    [0-16383]slot进行首尾相连,形成哈希环,对于每个redis节点会分配到一个值,该节点就负责自己节点值到上一节点值的所有slot值数据的存储。

    当集群要对一个key进行读写的时候,将key值计算出来的hash值向16384进行取模,将模值放入哈希环,并向后寻找第一个redisslot值,然后将key值存入redis上。


    通过这种方式,能够保证集群中存在多台master同时进行写操作,极大的降低了单节点高并发写的压力。

     

    动态扩容

    redis-cluster集群的一致性哈希算法支持动态扩容。动态扩容在一致性算法中涉及到两个问题,slot桶的重新分配、数据转移。


    上图所示是一个3节点redis-cluster集群里,redsi节点与key在哈希环上的映射关系,可以看出12两个key会存储在redis1上,3456四个key会存储在redis2上,而redis3只存储了key7。当我们需要往集群中新增一台redis,如果改变了全部redis分配的slot,那么数据的转移会涉及到整个集群, 那将是灾难性的。

    在一致性哈希算法下,会将新的redis节点计算出哈希值,放入哈希环中,这时,redis2H(key)<=7866的所有key值会进行转移,转移到redis4中;而当我们需要在新集群中删除掉其中一台redis2redis2中的所有key将会根据算法迁移到redis3上进行存储;


    一致性哈希算法在保持了单调性的同时,还是数据的迁移达到了最小,这样的算法对分布式集群来说是非常合适的,避免了大量数据迁移,减小了服务器的的压力;

     

    故障发现与故障转移

    Cluster集群在运行时所有的redis节点之间会通过ping/pong消息实现节点通信,消息不但传输节点槽信息,也能传播节点状态:主从状态,节点故障等。

    当集群中某一个节点出现问题时,集群会通过消息进行发现。与sentinel模式相同,节点故障在集群中也会经过主观下线、客观下线的过程,但是cluster集群中,并不需要sentinel来进行节点监控与故障转移,而是由集群中的master们来处理的。

  • 相关阅读:
    【leetcode】1365. How Many Numbers Are Smaller Than the Current Number
    【leetcode】1363. Largest Multiple of Three
    【leetcode】1362. Closest Divisors
    【leetcode】1361. Validate Binary Tree Nodes
    【leetcode】1360. Number of Days Between Two Dates
    【leetcode】1359. Count All Valid Pickup and Delivery Options
    【leetcode】1357. Apply Discount Every n Orders
    【leetcode】1356. Sort Integers by The Number of 1 Bits
    ISE应用入门的一些问题
    DDR的型号问题
  • 原文地址:https://www.cnblogs.com/HDMaxfun/p/15711892.html
Copyright © 2011-2022 走看看