什么是多级缓存

所谓多级缓存,即在整个系统架构的不同系统层级进行数据缓存,以提升访问效率,这也是应用最广的方案之一。我们应用的整体架构如图1所示:

图1 多级缓存方案

整体流程如上图所示:

1)首先接入Nginx将请求负载均衡到应用Nginx,此处常用的负载均衡算法是轮询或者一致性哈希,轮询可以使服务器的请求更加均衡,而一致性哈希可以提升应用Nginx的缓存命中率,相对于轮询,一致性哈希会存在单机热点问题,一种解决办法是热点直接推送到接入层Nginx,一种办法是设置一个阀值,当超过阀值,改为轮询算法。

2)接着应用Nginx读取本地缓存(本地缓存可以使用Lua Shared Dict、Nginx Proxy Cache(磁盘/内存)、Local Redis实现),如果本地缓存命中则直接返回,使用应用Nginx本地缓存可以提升整体的吞吐量,降低后端的压力,尤其应对热点问题非常有效。

3)如果Nginx本地缓存没命中,则会读取相应的分布式缓存(如Redis缓存,另外可以考虑使用主从架构来提升性能和吞吐量),如果分布式缓存命中则直接返回相应数据(并回写到Nginx本地缓存)。

4)如果分布式缓存也没有命中,则会回源到Tomcat集群,在回源到Tomcat集群时也可以使用轮询和一致性哈希作为负载均衡算法。

5)在Tomcat应用中,首先读取本地堆缓存,如果有则直接返回(并会写到主Redis集群),为什么要加一层本地堆缓存将在缓存崩溃与快速修复部分细聊。

6)作为可选部分,如果步骤4没有命中可以再尝试一次读主Redis集群操作。目的是防止当从有问题时的流量冲击。

7)如果所有缓存都没有命中只能查询DB或相关服务获取相关数据并返回。

8)步骤7返回的数据异步写到主Redis集群,此处可能多个Tomcat实例同时写主Redis集群,可能造成数据错乱,如何解决该问题将在更新缓存与原子性部分细聊。

应用整体分了三部分缓存:应用Nginx本地缓存、分布式缓存、Tomcat堆缓存,每一层缓存都用来解决相关的问题,如应用Nginx本地缓存用来解决热点缓存问题,分布式缓存用来减少访问回源率、Tomcat堆缓存用于防止相关缓存失效/崩溃之后的冲击。

虽然就是加缓存,但是怎么加,怎么用细想下来还是有很多问题需要权衡和考量的,接下来部分我们就详细来讨论一些缓存相关的问题。

如何缓存数据

接下来部将从缓存过期、维度化缓存、增量缓存、大Value缓存、热点缓存几个方面来详细介绍如何缓存数据。

过期与不过期

对于缓存的数据我们可以考虑不过期缓存和带过期时间缓存,什么场景应该选择哪种模式需要根据业务和数据量等因素来决定。

不过期缓存

场景一般思路如图2所示:

图2不过期缓存方案

使用Cache-Aside模式,首先写数据库,如果成功,则写缓存。这种场景下存在事务成功、缓存写失败但无法回滚事务的情况。另外,不要把写缓存放在事务中,尤其写分布式缓存,因为网络抖动可能导致写缓存响应时间很慢,引起数据库事务阻塞。如果对缓存数据一致性要求不是那么高,数据量也不是很大,则可以考虑定期全量同步缓存。

也有提到如下思路:先删缓存,然后执行数据库事务;不过这种操作对于如商品这种查询非常频繁的业务不适用,因为在你删缓存的同时,已经有另一个系统来读缓存了,此时事务还没有提交。当然对于如用户维度的业务是可以考虑的。

不过为了更好地解决以上多个事务的问题,可以考虑使用订阅数据库日志的架构,如使用canal订阅mysql的binlog实现缓存同步。

对于长尾访问的数据、大多数数据访问频率都很高的场景、缓存空间足够都可以考虑不过期缓存,比如用户、分类、商品、价格、订单等,当缓存满了可以考虑LRU机制驱逐老的缓存数据。

1. 过期缓存机制

即采用懒加载,一般用于缓存别的系统的数据(无法订阅变更消息、或者成本很高)、缓存空间有限、低频热点缓存等场景;常见步骤是:首先读取缓存如果不命中则查询数据,然后异步写入缓存并过期缓存,设置过期时间,下次读取将命中缓存。热点数据经常使用即在应用系统上缓存比较短的时间。这种缓存可能存在一段时间的数据不一致情况,需要根据场景来决定如何设置过期时间。如库存数据可以在前端应用上缓存几秒钟,短时间的不一致时可以忍受的。

2.   维度化缓存与增量缓存

对于电商系统,一个商品可能拆成如基础属性、图片列表、上下架、规格参数、商品介绍等;如果商品变更了要把这些数据都更新一遍那么整个更新成本很高:接口调用量和带宽;因此最好将数据进行维度化并增量更新(只更新变的部分)。尤其如上下架这种只是一个状态变更,但是每天频繁调用的,维度化后能减少服务很大的压力。

图3 维度化缓存方案

按照不同维度接收MQ进行更新。

3.   大Value 缓存

要警惕缓存中的大Value,尤其是使用Redis时。遇到这种情况时可以考虑使用多线程实现的缓存,如Memcached,来缓存大Value;或者对Value进行压缩;或者将Value拆分为多个小Value,客户端再进行查询、聚合。

4.   热点缓存

对于那些访问非常频繁的热点缓存,如果每次都去远程缓存系统中获取,可能会因为访问量太大导致远程缓存系统请求过多、负载过高或者带宽过高等问题,最终可能导致缓存响应慢,使客户端请求超时。一种解决方案是通过挂更多的从缓存,客户端通过负载均衡机制读取从缓存系统数据。不过也可以在客户端所在的应用/ 代理层本地存储一份,从而避免访问远程缓存,即使像库存这种数据,在有些应用系统中也可以进行几秒钟的本地缓存,从而降低远程系统的压力。

本书节选自中生代技术社区图书《深入分布式缓存》

往期推荐欧创新:深度解析DDD中台和微服务设计领域驱动专家张逸文字脱口秀:简单工厂不简单DDD专家张逸:《解构领域驱动设计》前言Hacker News热文:请停止学习框架,学习领域驱动设计(DDD)(获500个点赞)京东平台研发朱志国:领域驱动设计(DDD)理论启示DDD专家张逸:构建领域驱动设计知识体系领域驱动设计(DDD)在美团点评业务系统的实践当DDD遇上微服务DDD战略篇:架构设计的响应力可视化与领域驱动设计领域驱动设计(DDD)前夜:面向对象思想领域驱动设计(DDD):领域和子域DDD专家张逸:复杂与架构演进的关系滕云:DDD实现之路百度十亿级流量的搜索前端,是怎么做架构升级的?Francisco: 构建前瞻性应用架构的优秀实践这 3 种 DDD 分层架构的模式,你掌握了么?END
#技术人必备#点个在看,让更多人看见

原创精华:剖析亿级请求下的多级缓存相关推荐

  1. 剖析亿级请求下的多级缓存

    什么是多级缓存 所谓多级缓存,即在整个系统架构的不同系统层级进行数据缓存,以提升访问效率,这也是应用最广的方案之一.我们应用的整体架构如图1所示: 图1 多级缓存方案 整体流程如上图所示: 1)首先接 ...

  2. 亿级访问量下的新浪微博系统架构

    亿级访问量下的新浪微博系统架构 亿级访问量下的新浪微博系统架构 亿级访问量下的新浪微博系统架构 2016-04-24 架构说 序言 新浪微博在2014年3月公布的月活跃用户(MAU)已经达到1.43亿 ...

  3. 理论+算法+实战,教你如何实现亿级流量下的分布式限流

    摘要:在互联网应用中,高并发系统会面临一个重大的挑战,那就是大量流高并发访问,比如:天猫的双十一.京东618.秒杀.抢购促销等,这些都是典型的大流量高并发场景. 本文分享自华为云社区<[高并发] ...

  4. 千亿级数量下日志分析系统的技术架构选型

     
 随着数据已经逐步成为一个公司宝贵的财富,大数据团队在公司往往会承担更加重要的角色.大数据团队往往要承担数据平台维护.数据产品开发.从数据产品中挖掘业务价值等重要的职责.所以对于很多大数据工程师 ...

  5. 【技术干货】40页PPT分享万亿级交易量下的支付平台设计

    本文主要是根据作者在2018QCon演讲内容整理而成: 苏宁金融交易量3年内从1000亿增长到万亿+,服务用户3亿+,服务场景从服务于苏宁易购内部生态,扩展到服务全渠道,全场景,多业态的线上线下智慧零 ...

  6. 万亿级调用下的优雅——微信序列号生成器架构设计及演变(上)

    版权声明:本文由曾钦松原创文章,转载请注明出处:  文章原文链接:https://www.qcloud.com/community/article/200 来源:腾云阁 https://www.qcl ...

  7. 揭秘亿级流量下系统的高性能、高并发和稳定性保障

    1.性能.并发.稳定性三者关系 高性能:高吞吐量.低延时 公式:吞吐量(并发)=单位时间/平均延时 N-th% Latency:TP99, TP999 稳定性:低延时的稳定性标准为TP99/TP999 ...

  8. 日访问量百亿级的应用如何做缓存架构设计

    作者:陈波,新浪微博技术专家,著有<深入分布式缓存> 来自:公众号-中生代技术 全文:5588字28图 阅读时间:14分钟 微博日活跃用户1.6亿+,每日访问量达百亿级,面对庞大用户群的海 ...

  9. 【转发】日访问量百亿级的微博如何做缓存架构设计

    微博日活跃用户1.6亿+,每日访问量达百亿级,面对庞大用户群的海量访问,良好架构且不断改进的缓存体系具有非常重要的支撑作用. 4月21日,中生代技术走进盒子科技的现场技术交流活动上,新浪微博技术专家陈 ...

最新文章

  1. OpenCV制作自己的线性滤镜
  2. 免费教材丨第52期:人工智能(复杂问题求解的结构和策略)、人工智能哲学
  3. 数据结构之直接插入排序图文详解及代码(C++实现)
  4. obs 推流编码在哪设置_OBS录屏软件
  5. 基于WebRTC的互动直播实践
  6. java国际化——资源包
  7. HDU 3669 Cross the Wall(斜率DP+预处理)
  8. Annotation-specified bean name ‘mapper‘ for bean class [com.thoughtworks.xstream.mapper.Mapper] conf
  9. python 字符串前面的“r“是个啥?
  10. C++ UNICODE 文件读写相关
  11. wxWindows 最简单的Hello World程序
  12. 华为hcie认证是什么?华为hcie认证前景怎么样?
  13. JAVA项目在服务器部署过程
  14. 代码查重实验(深大算法实验4)报告+代码
  15. CocoaPods禁止显示警告inhibit_all_warnings
  16. 不懂风水没关系,照做就一定没错!好玩实用的室内风水忌避图
  17. mad和php的区别,良心解析kakaKUC-MAD好用吗?怎么样呢?体验揭秘分析
  18. 云原生时代,如何保证容器镜像安全?
  19. 【ubuntu】禁用IP和端口
  20. 每日C语言代码(The third day)——斐波那契(兔子数列)

热门文章

  1. 关于脚本log返回乱码解决方法
  2. ios web页面测试方法
  3. 最小生成树Kruskal算法+并查集检查连通
  4. 3-9:C++默认成员函数练习-日期类实现
  5. 图像的通道(channels)问题
  6. LeetCode 167 两数之和 II - 输入有序数组
  7. 九章算法 | Facebook 面试题 : 岛的周长
  8. shell获取命令返回结果前多少行(n行)
  9. 西门子S7comm-plus通信过程及重放攻击分析
  10. Linux下9个有用的touch命令示例