高性能、高可用缓存架构

架构

此处架构图,后续有时间补上

方案设计要点

一、流量分发

Nginx : 分发层 + 应用层 流量分发策略
OpenResty + nginx + lua

二、多级缓存 + nginx本地渲染

Nginx 本地缓存 + Redis 缓存 + Tomcat堆缓存

三、时效性数据

  1. 针对库存此类时效性要求高的数据,采用 缓存+数据库 双写方案,实时更新缓存数据

    缓存+数据库双写 容易发生数据不一致问题,可采用内存队列来保证数据一致

  2. 商品概览数据时效性要求低,采用 商品服务+消息对列 异步更新缓存数据

    分布式缓存重建并发冲突:流量分发hash策略、消息队列kafa策略不一致,数据变更的消息所到的缓存服务实例,跟我们的应用层nginx分发到的那个缓存服务实例也许就不在一台机器上,可采用zookeeper分布式锁解决

四、缓存预热

背景:新系统第一次上线,此时在缓存里可能是没有数据的,来了大量的请求,命中到数据库

方案:

  • nginx+lua将访问流量上报到kafka中
  • storm从kafka中消费数据,实时统计出每个商品的访问次数,访问次数基于LRU内存数据结构的存储方案
  • 守护线程,每隔一段时间,比如1分钟,都将排名前3的热数据list,同步到zk中去
  • 缓存服务,基于zk分布式锁,读取热点数据,更新到缓存

五、瞬间热点/秒杀

背景:某一个或多个商品瞬间成为热点数据,瞬间来了几十万请求,nginx流量分发服务器通过hash策略将同一商品瞬间分发到后端同一nginx应用服务器上,导致nginx应用服务器宕机,前端继续分发流量,导致其他nignx应用服务器依次宕机。

方案:

  1. 在storm中,实时的计算出瞬间出现的热点
  2. storm这里,会直接发送http请求到nginx上,nginx上用lua脚本去处理这个请求
  3. storm会将热点本身对应的productId,发送到流量分发的nginx上面去,放在本地缓存中
  4. storm会将热点对应的完整的缓存数据,发送到所有的应用nginx服务器上去,直接放在本地缓存中
  5. 流量分发nginx的分发策略降级
  6. storm还需要保存下来上次识别出来的热点list,diff差异,进行热点取消

六、Hytrix :资源隔离 + 限流 + 熔断 + 降级 +运维监控

资源隔离:线程池、信号量

如何在线程池和信号量之间做选择?
默认的策略就是线程池。
线程池其实最大的好处就是对于网络访问请求,如果有超时的话,可以避免调用线程阻塞住。
而使用信号量的场景,通常是针对超大并发量的场景下,每个服务实例每秒都几百的QPS,那么此时你用线程池的话,线程一般不会太多,可能撑不住那么高的并发,如果要撑住,可能要耗费大量的线程资源,那么就是用信号量,来进行限流保护。
一般用信号量常见于那种基于纯内存的一些业务逻辑服务,而不涉及到任何网络访问请求

你可能感兴趣的:(分布式)