亿级请求下多级缓存那些事

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
传统型负载均衡 CLB,每月750个小时 15LCU
云数据库 Tair(兼容Redis),内存型 2GB
简介:

什么是多级缓存

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

605c37183cd9418b123a037906d6b646e01e865b

图1 多级缓存方案


整体流程如上图所示:

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

2)接着应用Nginx读取本地缓存(本地缓存可以使用Lua Shared DictNginx 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所示:

c446ce3688fad452998c21d7cdcbafd06389a3d0

图2不过期缓存方案

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

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

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

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

1. 过期缓存机制

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

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

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

4307e4ef1879b5a612b50bef79066b68c56df86e

图3 维度化缓存方案

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

3.   大Value 缓存

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

4.   热点缓存

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


原文发布时间为:2018-01-03

本文作者:深入分布式缓存

本文来自云栖社区合作伙伴“中生代技术”,了解相关信息可以关注“中生代技术”微信公众号

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
6天前
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
12天前
|
存储 缓存 监控
多级缓存有哪些级别?
【10月更文挑战第24天】多级缓存有哪些级别?
24 1
|
12天前
|
存储 缓存 监控
多级缓存
【10月更文挑战第24天】多级缓存
23 1
|
18天前
|
缓存 监控 算法
小米面试题:多级缓存一致性问题怎么解决
【10月更文挑战第23天】在现代分布式系统中,多级缓存架构因其能够显著提高系统性能和响应速度而被广泛应用。
34 3
|
1月前
|
缓存 JavaScript CDN
一次js请求一般情况下有哪些地方会有缓存处理?
一次js请求一般情况下有哪些地方会有缓存处理?
37 4
|
2月前
|
缓存 NoSQL 应用服务中间件
SpringCloud基础8——多级缓存
JVM进程缓存、Lua语法、OpenResty、Nginx本地缓存、缓存同步、Canal
SpringCloud基础8——多级缓存
|
2月前
|
缓存 JavaScript 中间件
优化Express.js应用程序性能:缓存策略、请求压缩和路由匹配
在开发Express.js应用时,采用合理的缓存策略、请求压缩及优化路由匹配可大幅提升性能。本文介绍如何利用`express.static`实现缓存、`compression`中间件压缩响应数据,并通过精确匹配、模块化路由及参数化路由提高路由处理效率,从而打造高效应用。
138 11
|
3月前
|
存储 缓存 运维
平稳扩展:可支持RevenueCat每日12亿次API请求的缓存
平稳扩展:可支持RevenueCat每日12亿次API请求的缓存
42 1
|
3月前
|
存储 缓存 数据库
微服务+多级缓存:性能起飞的秘籍
【8月更文挑战第29天】在当今快速迭代的软件开发领域,高性能与可扩展性是企业应用不可或缺的两大支柱。微服务架构与多级缓存策略的完美结合,正是这一追求下的璀璨明珠。今天,我们将深入探讨这一组合如何助力系统性能“起飞”,并在实际工作学习中成为技术升级的关键推手。
56 0
|
3月前
|
缓存 JavaScript CDN
一次js请求一般情况下有哪些地方会有缓存处理?
一次js请求一般情况下有哪些地方会有缓存处理?
107 0