架构图

redis服务器宕机 redis master宕机_数据丢失

redis压测


可以对搭建好的redis实例做一个基准压测,网络开销、复杂操作、value的大小都会影响到redis的性能和QPS。

redis进行压测redis-benchmark -h 192.168.56.1 -p 6379 -t get,set -c 20 -n 100000 -d 10对192.168.56.1端口号6379的redis进行压测,只压测get和set命令,20个客户端连接,100000个请求,10个字节
1 -h 指定服务器主机名 127.0.0.12 -p 指定服务器端口 63793 -s 指定服务器 socket4 -c 指定并发连接数 505 -n 指定请求数 100006 -d 以字节的形式指定 SET/GET 值的数据大小 27 -k 1=keep alive 0=reconnect 18 -r SET/GET/INCR 使用随机 key, SADD 使用随机值9 -P 通过管道传输 请求 110 -q 强制退出 redis。仅显示 query/sec 值11 --csv 以 CSV 格式输出12 -l 生成循环,永久执行测试13 -t 仅运行以逗号分隔的测试命令列表。14 -I Idle 模式。仅打开 N 个 idle 连接并等待。

sentinel作用


sentinel哨兵是redis主从架构中非常重要的一个组件。主要功能如下:

  • 集群监控,负责监控redis master和slave进程是否正常工作。
  • 消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  • 故障转移,如果master node宕机,会自动转移到slave node上,选举某个slave node作为master。
  • 配置中心,如果故障转移发生了,通知client客户端新的master地址。

故障转移机制


哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。目前采用的是sentinal2.0版本,sentinal2.0版本相对于sentinal1.0版本来说,重写了很多代码,主要是让故障转移的机制和算法变得更加简单和健壮。

  • 故障转移时,判断一个master node是否宕机,需要大部分哨兵都同意才行,涉及到了分布式选举的问题。
  • 即使部分哨兵节点挂掉,哨兵集群还是能正常工作,因为如果一个作为高可用机制重要组成部分的故障转移系统是单点的,那么将无法实现高可用。
  • 哨兵集群至少需要3个实例,来保证自己的的健壮性。
  • 哨兵+redis主从的部署架构,是不能保证数据零丢失的,只能保证redis集群的高可用性。
  • 对于哨兵+redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。可以将生产环境的数据脱敏后进行场景模拟测试。
  • 哨兵集群必须是2个以上的节点。如果哨兵集群仅仅部署了2个哨兵实例,配置quorum=1,master宕机后,sentinal1和sentinal2中只要有1个哨兵认为master宕机就可以进行切换,同时sentinal1和sentinal2选举出一个哨兵来执行故障转移。同时这个时候需要进行majority,也就是需要哨兵集群中的大多数哨兵节点都是运行的,2个哨兵集群majority就是2(3个哨兵集群majorit=2,4ge哨兵集群的majority=2,5个哨兵集群的majority=3),两个哨兵都运行这就可以进行故障转移。但是如果2个哨兵集群中有一个sentinal宕机了。此时就不符合majority条件来执行故障转移,因此故障转移不会执行。

哨兵主从切换数据丢失

哨兵+redis主从部署的架构有两种丢失数据的情况,因为会发生主备切换所以会导致数丢失。

异步复制导致的数据丢失。因为master和slave的复制是异步的,所以可能有部分数据还没复制到slave,master宕机,此时这些部分数就丢失了。

redis服务器宕机 redis master宕机_redis 集群 部分宕机_02

集群脑裂导致的数据丢失。脑裂是指,某个master所在的机器突然脱离了正常的网络,跟其他的slave机器不能连接,但是实际上master还正常运行着,此时哨兵可能认为master宕机了,然后开始选举,将其他的slave切换成了master,这个时候集群中就有了两个master,这就是所谓的脑裂。此时虽然某个slave被切换成了master,但是可能client还没来得及切换到新的master,还继续写向旧的master,这部分数据可能也会丢失了。因为当旧的master再次恢复的时候(网络正常,加入的senttina监控的主从架构中),会被作为一个slave挂在到新的master上去,自己的数据会清空,重新从新的master复制数。

redis服务器宕机 redis master宕机_数据丢失_03

哨兵主从数据丢失解决方案

解决异步复制和脑裂导致的数据丢失,master的redis.conf添加配置。

老版本min-slaves-to-write 1min-slaves-max-lag 10新版本min-replicas-to-write 1min-replicas-max-lag 10PS:要求至少有一个slave,数据复制和同步的延迟不能超过10秒,如果说一旦所有的slave,数据复制和同步的延迟超过10秒,那么这个时候master就不会再接收任何请求了。上米娜两个配置可以减少异步复制和脑裂导致的数据丢失。

哨兵机制的核心原理

  • sdown和odown转换机制。sdown和odown是哨兵判断master的两种失败状态。sdown是主观宕机,就是一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机,odown是客观宕机,如果quorum数量的哨兵都觉得master宕机了,那么就是客观宕机。sdown达成的条件很简单,如果一个哨兵ping一个master,超过了is-master-down-after-milliseconds指定的毫秒数之后,就主观认为master宕机了。sdown和odown转换的条件很简单,如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为master是sdown了,那么就认为是odown了,客观认为master宕机了。
  • 哨兵集群的自动发现机制。哨兵互相之间的发现,是通过redis的pub/sub系统实现的,每个哨兵都会往_sentinal_:hello这个channel里发送一个消息,这时候所有的其他哨兵都可以消费这个消息,并感知到其他哨兵的存在,每隔两秒钟,每隔哨兵都会往自己监控的每个master+slaves对应的_sentinal_:hello的channel里发送一个消息,消息的内容是自己的host、ip、runid和对这个master的监控配置,每个哨兵也会去监听自己监控的每个master+slaves对应的_sentinal_:hello的channel,然后感知到同样在监听这个master+slaves的其他哨兵的存在,每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步。
  • 哨兵会自动修正slave的一些配置,比如slave如果要成为潜在的master候选人,哨兵会确保slave复制现有的master数据。如果slave连接到了一个错误的master上,比如故障转移后,那么哨兵会确保他们连接到正确的master上。
  • slave转换成master的选举算法。如果一个mater被认为odown了,而且majority哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave作为master。选举考虑条件,跟master断开连接的时长、slave优先级、复制offset、runid。
  • 如果一个slave跟master断开连接已经超过了down-after-milliseconds的10倍,外加master宕机的时长,那么slave就被认为不适合选举为master{(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state}
  • 接下来会对slave进行排序
  • [按照slave优先级进行排序,slave priority越低,优先级就越高]
  • [如果slave priority相同,那么看replica offset,哪个slave复制了越多的数据,offset越靠后,优先级就越高]
  • [如果上面两个条件都相同,那么选择一个run id比较小的那个slave]
  • quorum和majority。每次一个哨兵要做主备切换,首先需要quorum数量的哨兵认为odown,然后选举出一个哨兵来做切换,这个哨兵还得得到majority哨兵的授权,才能正式执行切换,如果quorum < majority,比如5个哨兵,majority就是3,quorum设置为2,那么就3个哨兵授权就可以执行切换;但是如果quorum >= majority,那么必须quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换
  • configuration epoch。哨兵会对一套redis master+slave进行监控,有相应的监控的配置。执行切换的那个哨兵,会从要切换到的新master(salve->master)那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的。如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号。
  • configuraiton传播。哨兵完成切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制。这里之前的version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的。其他的哨兵都是根据版本号的大小来更新自己的master配置的