redis
2019-07-12 10:03:54 66 举报
redis的一些场景图分析
作者其他创作
大纲/内容
解决异步复制和脑裂导致的数据丢失min-slaves-to-write 1min-slaves-max-lag 10要求至少有1个slave,数据复制和同步的延迟不能超过10秒如果说一旦所有的slave,数据复制和同步的延迟都超过了10秒钟,那么这个时候,master就不会再接收任何请求了上面两个配置可以减少异步复制和脑裂导致的数据丢失(1)减少异步复制的数据丢失有了min-slaves-max-lag这个配置,就可以确保说,一旦slave复制数据和ack延时太长,就认为可能master宕机后损失的数据太多了,那么就拒绝写请求,这样可以把master宕机时由于部分数据未同步到slave导致的数据丢失降低的可控范围内(2)减少脑裂的数据丢失如果一个master出现了脑裂,跟其他slave丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的slave发送数据,而且slave超过10秒没有给自己ack消息,那么就直接拒绝客户端的写请求这样脑裂后的旧master就不会接受client的新数据,也就避免了数据丢失上面的配置就确保了,如果跟任何一个slave丢了连接,在10秒后发现没有slave给自己ack,那么就拒绝新的写请求因此在脑裂场景下,最多就丢失10秒的数据
12点,redis有1000条数据
内存slave
OS cache
A
库存服务1
高并发下缓存和数据库数据不一致问题
B
4.slave先把RDB写入磁盘
redis
RDB持久化
client
4.master启动全量复制,将自己所有的数据都发送给slave,实现数据的同步
AOF
限流组件,可以设置假设每秒就2000个请求,一秒过来5000个请求,此时只有2000个可以通过,进入数据库
1.当数据写满了,会进行LRU清除,比如清除了50w数据
由于网络故障导致哨兵不能和master连通,哨兵开启选举将salve升级为master
master
redis基于哨兵的高可用
一致性hash算法
mysql
redis cluster hash slot算法
1.master内存里的一些数据还没来得及给slave,自己就挂了,
redis中的数据,是由一定限量的,不会一直无限增长导致AOF无限增长,内存大小是一定的,到一定时候,redis就会用缓存淘汰算法自动清除一部分数据。AOF是存放每条写的命令,会不断膨胀,当大到一定的时候,AOF会做rewrite操作,会基于当时redis内存中的数据,来重新构造一个更小的AOF文件,将旧的删除。
C
多个哨兵发现有master挂掉之后会通知其他哨兵进行掉线验证(主观下线和客观下线),有一半以上节点确认下线后会进行master切换,优先顺序为先看有无优先级配置,然后看响应时间,offset,最后看run id最小
3.发现run id变化了,就触发一次全量复制
事中:本地ehcache缓存+限流组件
redis限定内存大小1G,100w数据
RDB
RDB1
sentinal cluster哨兵集群
5.每次master接收到新的数据,都异步发送给slave node
redis slave
3.生成之后发给slave(触发full resynchronization全量复制)
20万读QPS
1.主从架构,每个节点存放的都为全量数据
集群脑裂导致的数据丢失问题
100w最新的指令日志
每个slave平均分担5万QPS
socket网络连接
更新缓存之前先获取分布式锁
剩余的3000个请求走降级,限流组件会发现有3000个请求没法通过自己,会调用自己开发好的一个降级的组件,返回一些默认的值,如:友情提示,或者空白页面
2.开始全量复制的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时将客户端的所有写命令缓存到内存中
master100w条数据
期望是 set key 1 09:00:01 -> 3 09:00:09 -> (2 09:00:05 比较时间戳,如果比上一个小就不进行更新操作)
master node
set key 1
master发送部分缺少的数据给slave
不是第一次链接
1.在本地保存master node的host和ip
水平扩容,如果QPS增加redis压力大,可以增加slave数量
set key 1 -> 3 -> 2
此架构为一主多从,主负责写入数据并同步复制到其他slave节点,从节点负责读,所有读请求全部走从节点
系统A
slave
缓存雪崩解决方案
1.第一次链接master 发送PSYNC命令
key 0
ehcache
RDB2
复制的完整的基本流程
3.如果master配置了requirepass,那么slave发送masterauth口令过去认证
普通hash算法
2.检测到master挂掉之后,哨兵会提升slave为master
按照队列里的顺序进行操作,先更新,再查询
数据写入
master run id的作用
异步复制导致的数据丢失问题
set key 2
zookeeper
如果redis中没有数据就加入内存队列排队,对于相同的查询操作做去重操作
sentinal,中文名是哨兵哨兵是redis集群架构中非常重要的一个组件,主要功能如下(1)集群监控,负责监控redis master和slave进程是否正常工作(2)消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员(3)故障转移,如果master node挂掉了,会自动转移到slave node上(4)配置中心,如果故障转移发生了,通知client客户端新的master地址哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作(1)故障转移时,判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题(2)即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了目前采用的是sentinal 2版本,sentinal 2相对于sentinal 1来说,重写了很多代码,主要是让故障转移的机制和算法变得更加健壮和简单2、哨兵的核心知识(1)哨兵至少需要3个实例,来保证自己的健壮性(2)哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性(3)对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练3、为什么redis哨兵集群只有2个节点无法正常工作?哨兵集群必须部署2个以上节点如果哨兵集群仅仅部署了个2个哨兵实例,quorum=1Configuration: quorum = 1master宕机,s1和s2中只要有1个哨兵认为master宕机就可以还行切换,同时s1和s2中会选举出一个哨兵来执行故障转移同时这个时候,需要majority,也就是大多数哨兵都是运行的,2个哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2个哨兵都运行着,就可以允许执行故障转移但是如果整个M1和S1运行的机器宕机了,那么哨兵只有1个了,此时就没有majority来允许执行故障转移,虽然另外一台机器还有一个R1,但是故障转移不会执行4、经典的3节点哨兵集群Configuration: quorum = 2,majority如果M1所在机器宕机了,那么三个哨兵还剩下2个,S2和S3可以一致认为master宕机,然后选举出一个来执行故障转移同时3个哨兵的majority是2,所以还剩下的2个哨兵运行着,就可以允许执行故障转移
实际上原master并没有挂,只是网络造成,出现两个master,client连接其中一个,当网络恢复的时候,原master可能降为slave,就导致其中内存里的数据丢失
磁盘
12点05,redis有1500条数据
slave node
2.rdb的冷备,直接取到20个小时之间的一份rdb的备份,然后回复到master中,此时master中的数据就完全不一样了,而且run id也变化了
slave100w条数据
nginx
请求会根据key计算CRC16的值然后对16384取模,每个节点会有一部分hash slot,从而落到不同的机器上。任何一个节点宕机,另外两个节点不受影响,因为key找的是hash solt而不是具体的某个节点
每隔1秒调用一次操作系统fsync操作,强制将os cache中的数据刷入磁盘文件
1.offset等信息来要求数据同步,有问题
某个master宕机就将它的 hash slot 移动到其他 master 上去。移动 hash slot 的成本是非常低的。客户端的 api,可以对指定的数据,让他们走同一个 hash slot,通过 hash tag 来实现。同理增加节点也是一样。
事前:保证redis集群的高可用
大量请求
new slave
hystrix限流
例如有三个节点,一致性hash算法保证,任何一个节点宕机只会影响到宕机节点的数据,落到hash环上的key会顺时针找最近的节点。为了解决某个节点挂掉之后该节点的数据都落到下一个节点,导致下一个节点压力过大(缓存热点问题),会在hash环上做虚拟节点,这样分布在该区间的数据会相对均匀的顺时针落到不同的节点上。
aof的时候数据会先写入linux OS cache
要写入缓存的数据,都是从mysql里查出来的,都得写入mysql中,写入mysql中的时候必须保存一个时间戳,从mysql查出来的时候,时间戳也查出来如1:09:00:012:09:00:053:09:00:09
3.此时的master中的数据不包含老的master中内存的数据,导致数据丢失
AOF文件
3.AOF执行rewrite,基于当前内存中最新的100w数据构建
因为master -> slave的复制是异步的,所以可能有部分数据还没复制到slave,master就宕机了,此时这些部分数据就丢失了
同步完之后就剩80W条数据了
RDB每隔一段时间就会生成一份完整的快照
1.用户发送一个请求2.你收到请求,先查本地的ehcache缓存,如果没有再查redis3.如果redis也没有,再查数据库4.将数据库中的结果写入ehcache和redis
2-1.内存中缓存最新的一些数据
监控master
sentinal集群哨兵
sentinal哨兵
6.master再把2-1内存中的缓存写命令发给slave
客户端
2.主从架构同步过程
redis高可用架构,叫故障转移,failover,也可以叫主备切换
1500条
获取到锁的进行更新操作
20小时之前只有80W数据run id变化
根据key算出hash对节点个数取模,落到不同的节点上,一旦有一个节点宕机,导致取模基数变化(3-2),导致大部分请求都不能从缓存中拿到数据,从而走数据库,容易导致数据库宕机。
2.slave内部有定时任务,每秒都会check是否有master要连接,如果有就跟master建立socket网络连接
redis并发竞争问题及解决方案
1000条
5.再从磁盘加载到内存
一秒5000个请求
set key 3
库存服务2
redis持久化:AOF,RDB
redis master
期望是 set key 1 -> 2 -> 3
2.当数据指令达到150w时,已经很大了。
事后:redis持久化机制,尽快恢复缓存集群,一旦重启,自动从磁盘上加载缓存数据
好处1:数据库绝对不会死的,限流组件就确保了每秒只会过去2000个请求好处2:只要数据库不死,就是说对用户来说,2/5的请求都是可以被处理的好处3:只要有2/5的请求可以被处理,就意味着你的系统没死,对用户来说就是可能多点几次才会刷出来一次
根据相同的商品id,进行hash取值,再加上对内存队列的数量进行取模,每个商品都可以路由到某一个队列内
0 条评论
下一页