- Redis雪崩?
雪崩是指缓存中大批热点数据过期后系统涌入大量查询请求,因为大部分数据在Redis层已经失效,请求渗透到数据库层,大批量的请求犹如洪水一般涌入,引起数据库压力造成查询阻塞甚至宕机。
解决方案:
- 将缓存失效时间分散开,比如每个key的过期时间都是随机的,防止同时大量数据过期现象发生,如果缓存是分布式部署,将热点数据分布在不同的Redis和数据库中,有效分担压力。
- 简单粗暴法,将Redis数据设置永不过期(如果业务准许,比如不需要更新的名单类)
- Redis穿透?
穿透是指绕过Redis,调用者发起的请求参数(Key)在缓存和数据库中都不存在,通过不存在的key,成功穿透到系统底层,大规模不断发起不存在的Key的检索请求,导致系统压力过大最后故障。
解决方案:
- 分布式布隆过滤器
- 返回空值,遇到数据库和Redis都查不到的值,在Redis里Set一个null value过期时间很短,目的在于同一个Key再次请求时直接返回Null,避免穿透。
- Redis击穿?
击穿:击穿和穿透概念类似,一般是指一个Key被穿透,这个Key是热点Key,同一个Key会被成千上万次请求,比如微博搜索热点排行榜、如果这个Key失效了,就像保险丝熔断了,百万QPS直接压垮数据库。
解决方案:
- 利用互斥锁,简单来说就是在缓存失效的时候,不是直接去Load DB,而是先试用缓存工具的某些带成功操作返回值的操作(Redis SETNX)去Set一个Mutex Key,当操作返回成功时,在进行Load DB的操作,并回设缓存,否则,就重试整个get缓存的方法。
- 热点数据问题如何准确定位?
- 提前获知法:根据业务,人肉统计或者系统统计可能会成为热点的数据,如促销的商品、热门话题等
- Redis客户端收集法:调用端通过计数的方式统计Key的请求次数,但无法预知Key的个数。
- Redis集群代理层统计
- Redis服务端统计:监控Redis单个分片的QPS,发现QPS倾斜到一定成程度的节点进行monitor,获取热点key,Redis提供了monitor命令,可以统计出一段时间内的某个Redis节点上所有的命令,分析热点Key。
- 如何解决热点数据的问题?
- 可从两个方面来考虑,第一是数据分片,让压力均谈到集群多个分片上,防止单个机器打满,第二是迁移隔离。概括描述为:
- Key拆分
- 迁移热点Key
- 热点Key限流
- 增加本地缓存。
- 数据库和缓存的双写一致性问题?
在高并发请求下很容易导致数据不一致的问题,如果业务需要保证强一致性,那么建议不要使用缓存。在数据库和缓存数据的删除或者写入过程中,如果有失败的情况,会导致数据的不一致。
解决方案:
- 双删延时的解决方案:可以先删除缓存数据,然后在更新数据库数据,最后在个固定的时间再次删除缓存。
伪代码:
redis.del(key)
db.update()
Thread.sleep(500)
redis.del(key)
弊端:结合双删策略+缓存超时设置,这样最差的情况就是在超时时间内数据不一致,又增加了写请求的耗时。
- 异步更新缓存(基于订阅的binlog的同步机制,使用Canal)将有变化的key记录下来,并且尝试去不断的去删除缓存(如果上次删除缓存失败)。
MySQL BinLog增量订阅消费+消息队列+增量数据更新到Redis
- 如何实现异步队列?
- 使用List作为队列,RPUSH生产消息,LPOP消费数据。
- 缺点:没有等待队列里有值就直接消费数据。
- 弥补:可以通过在应用层引入sleep机制去调用LPOP重试
- BLPOP Key:阻塞知道队列有消息或者超时
- 缺点:只能提供一个消费者消费
- pub/sub:主题订阅者模式
- 发布者(pub)发送消息,订阅者(sub)接收消息。订阅者可以订阅任意数量的频道。
- 缺点:消息的发布是无状态的,无法保证可达,如一台机器下线后,上线数据会丢失。
- 如何实现分布式锁?
- SETNX key value:如果不存在,则创建并赋值,存在未0,不存在为1(通过设置expire key second 设置过期时间)
- SET KEY VALUE [EX Second] 直接设置key value 过期时间。
- Redis的主从复制机制?
答:当项目比较大时,可以使用主从架构 Master/Slave机制,Master以写为主,Slave以读为主,Master主节点更新后根据配置,自动同步到从机Slave节点。
主从复制的原理包括旧版同步
和命令传播
,主从复制的代价就是系统复制较重的时候会导致主从延迟,并且根据CAP理论,无法同时保证服务可用性和数据一致性。
- C(Consistency)一致性
- A(Availability) 可用性
- P(Partition tolerance) 分区容错性
- Redis对事务的支持?
答:Redis对事务的支持可以概括如下:
- 隔离性:redis是单进程的程序,保证在执行事务时,不会对事务进行中断。事务可以运行直到执行完所有事务队列中的命令为止。所以Redis的事务支持隔离性。
- Redis会将一个事务中的所有命令序列化,然后按照顺序执行。Redis不可能在一个事务的执行过程中插入执行另一个客户端发出的请求,这个样可以保证Redis将这些命令作为一个单独的隔离操作执行。
- 需要注意的是Redis的事务不支持回滚操作。只有当redis命令有语法错误或者对某个键执行不符合其数据类型的操作,但是在将命令入队列的时候就应该能够发现这些问题。所以Redis的事务并不支持进行回滚操作。
来源:oschina
链接:https://my.oschina.net/u/4283481/blog/4133364