当前位置:首页 > 常见问题 » 正文

Redis高并发处理常见问题及解决方案

1. 大型电商系统高流量系统设计
  场景:
    大量电商系统每天要处理上亿请求,其中大量请求来自商品访问、下单。商品的详情是时刻变化,由于请求量过大,不会频繁去服务端获取商品信息,导致服务器压力极大。需要用到多级缓存、异步处理、负载均衡等方式来实现
  解决:
    评估哪些页面是活跃的,即用户查看使用较多的页面。页面里面包括静态资源和数据、动态数据等,划分层次,把静态资源存放到负载均衡服务器中缓存,如Nginx本地缓存。页面中的动态数据分为热点数据、非热点数据、实时数据、非实时数据等。把非热点数据、热点数据、非实时数据存放到Varnish缓冲中,Varnish擅长存储不变或变动较少的数据,通过Varnish的缓存策略,减少请求后端服务器的频率
    Redis缓存存储热点数据、实时数据,Redis擅长存储需要原子操作计算、全局主键生成、订单号生成、排序相关数据。高并发情况下实时的数据处理讲究快速响应,为了提高效率可以采用异步消息队列处理。
    系统架构采用了Nginx本地缓存、Http加速Varnish缓存、后端Redis缓存、消息队列等。注意:Nginx缓存静态资源、Varnish缓存不变或变动较少的数据、Redis缓存原子操作计算数据,异步队列主要处理非实时的业务或数据。

2. Redis支撑百万QPS高并发、高可用架构
  场景:
    大型电商系统每天有上亿请求,会用到多级缓存,此时Redis单体无法承载需求量,需要使用Redis集体模式,由多态Redis共同承载并供外界使用
  解决:
    Redis单体处理并发能力达到10多万,分析Redis的瓶颈在于确定是读还是写方面。如果在读取数据方面在瓶颈时,可以采用读写分离、主从方式,通过哨兵监控服务正常性。主节点用于写入数据,并同步数据至从节点,从节点可以部署多台,整体提高Redis的读取数据能力
    Redis主从模式:Redis集群主从部署,一台主节点写入,多台从节点读取,主节点数据同步到从节点,数据延迟毫秒级别,同时引入哨兵模式监控,当主节点宕机后,进行选主操作,到从节点选举一台升级为主节点,履行主节点的使命,当之前宕机的主节点恢复后,会加入到节点继续服务
如果在写方面存在瓶颈,可以采用Redis集群化,由多台Redis共同成立的虚拟组织机构共同提供外界写入、读取操作。Redis设置了合理的备份方案,防止数据丢失。集群化后的Redis可以提供上百万甚至上千万的QPS并发处理,集群部署。

3. Redis雪崩后,备用方案
  场景:
    Redis集群模式中,由于网络、带宽等其他异常情况导致Redis雪崩后,如何提供网站正常服务并处理大量请求?设计时需要考虑到容灾,当Redis宕机后,监测到状态,启动其他缓存技术,如enCache、MemCache。注意,Redis和其他缓存之间需要定期同步数据,当Redis恢复后,切换到Redis
  解决:
    由于用户量、请求量都较多,设计时需考虑到极端情况,即要考虑替代方案。当Redis异常情况雪崩,系统监控到Redis心跳停止后,切换到备用缓存,如Memcache、Encache等,崩溃的Redis由于备份恰当,以尽快恢复使用,恢复期间可以用其他缓存,Redis使用期间的数据需要和崩溃后的数据进行同步,保证数据最终一致性,可以采用消息队列、备份文件对比复制等操作实现   

  > Web应用通过Lua脚本操作Redis时,发现其无心跳,会自动切换到其他缓存技术
 
4. 高并发情况下,数据库和缓存双写数据不一致问题
  场景:
    当核心业务需同时操作Redis和数据库时,由于两者之间存在非原子操作,当操作其中之一成功后出现异常、导致两者之间的数据不一致,应如何解决?可以引入异步消息队列串行化执行
  解决:
    1. 数据库先写入成功,Redis后写入失败
    2. Redis先写入成功,数据库写入失败
    3. 操作数据和Redis串行化,使用消息队列,由于其具有重试、吞吐量搞、消息持久化等特性个,可以通过消息队列来保证双写数据一致性。
    先写入Mysql,加入消息队列,消费,写入Redis缓存,一致性。消费队列执行失败后,因为数据持久化,所以可以进行失败重试处理。

5. 高并发Redis缓存中的大value存储,全量更新时效率低
  场景:
    用户量不高,可能会把商品、详情等数据完全存储在Redis中某个key对应value中,随着用户量逐渐增加,此时处理更新时,处理效率比较差,可以按照存储信息的维度进行数据拆分,如商品信息可以按照商品的类别和批次进行拆分
  解决:
    由于Redis是单线程模式进行的,一次操作大的value会对整个Redis 的响应时间造成较大影响,所以业务上将其拆分成多个小key形式。可以按照功能的类别、批次维度进行拆分,建议每个key不要超过1MB。

6. 高并发Redis防止缓存被穿透
  场景:
    当系统内使用缓存的地方的失效时间都一样时,若系统高峰期间恰好缓存失效了,大量请求至缓存中,此时都没命中,Redis的压力瞬间飙升,缓存被穿透。根据系统结构U划分,不同的操作需要设置不同的缓存失效时间,错开读取数据的时间,避免被穿透
  解决:
    高峰期间,系统受到诸多无效,如被攻击等,可在应用程序中使用Redis的常用方式来避免
    处理流程如下:
      1. 根据商品的主键goodID去缓存中查询商品,若商品存在即返回
      2. 若商品不存在,再去查询数据库
      3. 若数据库中存在,将其存储到Redis中,并设置过期时间
    被击穿的情况:若高峰期间外界频繁去请求这个接口方法,传入的goodId有各种类型,此时去缓存中查询,大部分是没有数据的,然后这些请求会流入查询db中,Redis由于高性能特性可以去处理这部分请求,但是数据库中,由于数据库的连接数存在瓶颈,大量请求去查询数据库会导致数据库的CPU瞬间飙升,严重会卡死。
查询Redis为null,查询数据库也为null,此时设置该key在缓存中,且值为null,过期时间为随机时间。random(10)。这样子能保证数据在这段时间暴力请求,也只会在这短暂的时间内获取null,而有另外的线程在读取数据库表,并缓存在Redis中

7. 高并发Redis提高命中率
  场景:
    集群部署Redis中,由于多台Redis请求访问的频率存在不一致,导致Redis没有充分被利用,为了更好地提高访问次数和命中率,可以在部署策略中通过Lua脚本实现一致性Hash流量分发
  解决:
    命中:可以直接通过缓存获取数据
    不命令:无法直接通过缓存获取数据,需要再次去数据库表中查询或者执行其他的操作。原因可能是由于缓存根本不存在或者缓存已过期
  当缓存有过期的key存在时,会导致命中率下降。Redis中提供了info函数来监控服务器的状态,通过hits和miss计算命中率,14514119/(14514119+3428654)=82%,命中率较低,而一个良好的缓存存储机制包含了失效机制、过期时间设计,命中率高达95%以上。

8. 高并发Redis防止雪崩
  当Redis中的大量数据频繁过期失效后,可能有大量请求来获取数据,面临击穿,严重导致崩掉。可以用键值对失效时间合理设置、互斥锁等方式来防止雪崩
  场景1:Redis缓存中,数据集体过期失效
    在Redis缓存中的某个时间节点,缓存的数据集中过期失效,导致缓存被击穿,流量流向数据库中,造成数据库负载过高
  场景2:Redis缓存中,Redis集群大批量机器故障
    在Redis集群中大批量的机器故障,整体的稳定性和可靠性出现严重问题,不能给外界提供良好的服务,导致流量流向数据库,造成数据库负载过高
  预防缓存雪崩解决:
    1. 设计Redis缓存架构时,尽量设计高可用,防止大批量机器故障,当个别节点、部分机器出现问题后,不影响Redis整体的可用性
    2. Redis缓存存储时,设计合理过期时间,错开业务交叉存储。合理的过期时间可以更大程度调高缓存的命中率,减少数据库的压力

9. 高并发Redis缓存预热方案   
  场景:
    当系统热点数据初始化被高频率访问时,严重会造成阻塞死锁。可以在系统启动时预加载到缓存中
  解决:
    系统启动和核心功能使用之前进行缓存加载,如省市区、热点数据,这些数据更新频率较低,数据量较大,可以提前加载到容器中,当外界需要使用时,直接从缓存中,不需要查询数据库。那么当数据更新时如何更新缓存呢?
    更新缓存有两种模式:自动和手动。手动即人工触发更新操作,把更新的数据流向缓存中。当缓存过期或失效后,可自动读取数据库数据然后加载到缓存中。为了保证缓存的充分利用,建议将更新频率较低的热点数据设置为永不过期,当数据改变时,可以用监听通知等方式自动更新缓存的数据

10. 高并发Redis缓存击穿
  场景:
    系统缓存中热点的数据某个时间点即将过期,恰好这个时间节点访问量突增,对于这个Key有大量的并发读取操作,这时候击穿了Redis,直接访问到DB中,会对DB形成巨大压力。可以设置热点数据永不过期,热点数据增加互斥锁
  解决:
    通常Redis中会优先存储热点数据,由于热点数据访问频率高,命中率会显著提高。高并发中,热点数据被频繁访问,当缓存热点数据恰好过期,大并发请求集中访问,持续的访问会直接击穿缓存,使流量直接流向数据库,给数据库造成较大压力。那么如何防止被击穿呢?简单可以设置热点数据永不过期,当热点数据发生更新时,通过监听通知等方式,自动更新缓存数据。

11. 高并发Redis缓存集中失效
  场景:
    缓存中由于存储的数据过期时间固定且一样,导致同时间数据过期,缓存被穿透甚至雪崩。可以合理设置不同类型的缓存时间,如基于随机过期的缓存失效时间
  解决:
    Redis过期时间会直接影响命中率,为了提高命中率,需要合理设置过期失效,过期时间设置需要分类,包括热点数据、冷数据、临时数据等
    1. 针对热点数据设置合理过期时间,需要从用户行为统计分析、物品模型的数据存储、物品被查看的次数等方面综合考虑,设定一个合理的数值,建议可设长点
    2. 冷数据,一般被查看的次数、使用的频率较低,为了提高Redis整体的空间存储,通常冷数据设置的过期时间较短
    3. 临时数据,即无效或者临时使用的数据,为了避免缓存被穿透,通常设置一个临时数据,过期时间设置较短

12. Redis高效拆分数据过程
  场景:
    系统构建初期使用单台Redis提供服务,发展过快,用户数量随之增加,此时单台Redis数据量过大,效率低下,会涉及Redis数据拆分迁移
  解决:
    以Redis数据拆分为例,RedisA存在用户、产品、订单数据,可拆分成RedisA、RedisB、RedisC,分别存放用户、产品、订单数据。针对RedisA 、RedisB、RedisC还可以进行父子Master-Slave方式进行扩展,假如其配置是32G,按照5K条数据1MB,保守可以存储2~3亿数据
未经允许不得转载:伊犁速帮网络科技有限公司 » Redis高并发处理常见问题及解决方案
分享到

相关推荐

评论 ()

分类栏目

联系我们

D17809992000

D17809996661

客服微信

网站客服

客户服务专属联系微信

客服QQ
1620369666

客户服务专属联系QQ

联系我们