前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Redis缓存穿透、缓存击穿、热key问题优化 + 内存缓存

Redis缓存穿透、缓存击穿、热key问题优化 + 内存缓存

原创
作者头像
garyhwang
发布于 2020-06-25 00:59:42
发布于 2020-06-25 00:59:42
2.3K0
举报
文章被收录于专栏:潇洒哥写字潇洒哥写字

Redis缓存穿透、缓存击穿问题优化 + 内存缓存

1 背景

广交会线上举办,在第三方服务不能保证稳定性的情况下,为保证官网稳定性,新增数据聚合服务,用于缓存数据,并保护第三方服务,且在第三方服务失败的情况下,能够返回缓存的数据,保证前台能够拿到返回数据。

数据聚合服务使用Redis集群来做数据缓存服务,但是用户可以通过恶意构造数据的方式,让请求越过Redis层,每次都打到第三方请求(缓存穿透);同时缓存的数据有生存期,在数据失效的那一刻,可能有大量请求打到第三方服务(缓存击穿)。

2 实例

品牌橱窗、CF奖展品 这两个接口,其中品牌橱窗是个性化数据,当用户未登录时(游客),看到的是相同的数据,用户登录之后,看到的是个性化的数据(每个人看到的不同);CF奖展品无论是否登录,每个人看到的都是相同的。

2.1 接口协议
2.1.1 品牌橱窗推荐

接口名:DescribeBrandGoodList

请求参数

参数名称

必选

类型

描述

eventId

int64

请求id

interfaceName

string

接口名

para

struct

accessToken, page, size, lang

accessToken

string

用户信息

uid

string

用户id

pageIndex

int64

页号(第0页开始)

pageSize

int64

页容量

lang

string

语言(可选zh和en,默认为zh)

2.1.2 CF奖产品推荐

接口名:DescribeCfGoodList

请求参数

参数名称

必选

类型

描述

eventId

int64

请求id

interfaceName

string

接口名

para

struct

access_token, page, size, lang

pageIndex

int64

页号(第0页开始)

pageSize

int64

页容量

lang

string

语言(可选zh和en,默认为zh)

2.2 分析

数据请求过程是,前端发起请求到数据聚合服务,处理的流程图如下:

Redis key的设计为:

  • 未登录 apiName_page_size_language
  • 登录 uid_apiName_page_size_language

未登录的场景:

  1. 前台正常请求的page是规律的,size是固定的,language只会传入zh或en,但是如果用户恶意改变这三个值来请求,每次就无法在打到redis的key,请求会到第三方服务,这样会造成缓存穿透。
  2. 当请求到第三方服务失败之后,没有数据写入redis,这样大量请求时也会出现缓存穿透
  3. 这两个接口的数据,每五分钟会改变一次,所以redis中缓存的数据需要设置(逻辑)生存期(5min),以免用户永远拿到相同的数据;当数据失效的那一刻,如果大量的请求打过来,会全部请求第三方服务,造成缓存击穿。
  4. 接口请求首页时,所有的请求都是同一个redis key,当有大量的请求时,会全部命中到同一个key,热key的问题会影响redis的性能。

用户登录场景:

用户登录后会有一个uid,这个uid可以认为是无法伪造的,所以可以等同于未登录的场景来考虑。但是带uid的redis key需要设置真实的过期时间(可以较长,如6小时),避免百万用户请求数据始终缓存。

3 解决方案

3.1 缓存穿透问题

针对pageSize和language的问题,可以和前台约定好,后端固定pageSize,不依赖前端传入;language固定两种入参校验。pageNum这个字段不太好控制,理论上我们不应该限制用户选择查看的页数,但是针对当前场景,用户无法直接选择查看的页号,每次"换一批"只能向前翻动一页,在合理的情况的下,我们限制最大的查看页号为500,如果超过500,认为为非法请求,返回第1页内容。

如果第三方服务请求失败,要在redis中set一个空值,如"null",并设置一个较短的生存期(2秒),防止短期内大量请求打到服务端,设置较短的生存期避免请求长时间拿不到数据。这里还要考虑缓存击穿的问题。

3.2 缓存击穿问题

每个redisKey的逻辑过期时间为5min,针对redisKey失效,大量请求同时并发打到后台服务的问题,这里使用redis实现一个分布式锁来解决。

采用setnx命令来实现redis分布式锁,若setnx成功,表示获取到了锁,则请求第三方服务,并将数据更新到redis,释放锁;没有获取到锁的进程,可以直接返回默认数据。这样可以保证当redisKey失效的那一刻,只有一个进程请求第三方服务并更新redis。

3.3 redis热key问题

redis中的数据是一个定时任务(3min执行一次,缓存前20页)异步请求第三方服务,更新到redis的,未登录的情况下,理论上请求不会到第三方服务,都会命中redis且没有逻辑过期。我们对redis热key拼接上0~19的数字,将一个热key转化为20个key,每次请求的时候,生成一个0~19的随机数,这样就能将热key打散,避免redis热key的问题。定时更新redis的时候,更新20个key,请求时redisKey重新设计为apiName_page_size_language_randomNum

4 内存缓存

虽然redis的性能已经比较优秀了,但是为了保证在大规模并发请求时(压测)服务稳定性,我们考虑在redis缓存之前,加上一层内存缓存,将前20页的数据缓存在本地内存,请求若命中内存则直接返回,这样使得请求响应更快更稳定。

image.png
image.png

使用ristretto来做内存缓存,可以控制缓存的时间、数量、大小、淘汰策略等。

经过内存缓存的优化之后,压测接口的响应时间从ms级提升到了µs级,且压测锯齿明显减少。

下表是一轮压测的情况:

处理耗时

数量

占比

< 1ms

7236615

99.972%

< 5ms

1141

< 10ms

301

< 15ms

106

< 30ms

151

< 50ms

183

< 100ms

128

> 100ms

0

总计

7238625

这里有一个现象是,虽然请求都是命中内存就直接返回了,但是在并发请求量太大的情况下,仍然会存在100ms左右的响应时间。

5 结束

本文介绍了广交会项目后台用到的两种缓存和相关的优化方法。使用两级缓存还有一个问题就是缓存数据的实时性的问题,这里缓存的过期时间和更新时间需要设置好,不然会出现一致性的问题。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
《重塑认知:Django MVT架构的多维剖析与实践》
MVT,即Model - View - Template,是Django框架独特的架构模式。它看似简单的三个字母,实则蕴含着深刻的设计哲学,如同古老智慧的密码,解开了Web应用开发的复杂谜题。
程序员阿伟
2025/05/27
890
《重塑认知:Django MVT架构的多维剖析与实践》
Django框架:优缺点、实用场景及与Flask、FastAPI的对比
Django是一个使用Python语言编写的高级Web框架,它提供了快速开发、可重用和可维护的Web应用程序所需的一切组件。在本文中,我们将探讨Django的get和post请求、优缺点、实用场景以及与Flask、FastAPI的对比。
江一铭
2023/06/04
2.6K0
Django框架完全指南:从入门到高级应用
Django是一个高效、功能强大的Python Web框架,它被广泛用于构建各种规模的Web应用程序。无论是初学者还是有经验的开发人员,都可以从入门到掌握Django的高级技巧。在本指南中,我们将带你逐步了解Django的核心概念和高级功能,通过代码实例和解析来详细说明。
一键难忘
2024/03/14
4.3K0
框架介绍
  此外,Django还有一个URL分发器。它的作用是将一个个URL的页面请求分别发给不同的Views处理,Views再调用相应的Model和Template。
全栈程序员站长
2022/07/21
6250
框架介绍
认识Flask框架
Python Web框架里比较有名当属Django,Django功能全面,它提供一站式解决方案,集成了MVT(Model-View-Template)和ORM,以及后台管理。但是缺点也很明显,它偏重。就像是一个装潢好的房子,它提供好了你要用的东西,直接拿来用就可以。
Devops海洋的渔夫
2019/10/24
9420
认识Flask框架
2020最值得学习的12款python-web开发框架大盘点
最近JETBRAINS发布了目前最受欢迎的python-web开发框架,可以看到最受欢迎的还是Django和Flask,那么本文就对上榜的12个框架进行分类整理,一起来看看吧!
刘早起
2020/04/22
2.3K0
2020最值得学习的12款python-web开发框架大盘点
Django简单博客系统项目开发总结
Django注重组件的重用性和可插拔性,敏捷开发和DRY法则(Don't Repeat Yourself)
好派笔记
2021/09/13
7420
后端框架有哪些?8个流行的后端框架推荐
在选择要使用的后端框架时,有许多选项可用。虽然每个后端框架都有自己的优点和缺点,但在做出最终决定之前,还有一些其他因素需要考虑。在本指南中,我们将仔细研究经过尝试的框架,以确定哪个是最适合您的后端框架。
全栈程序员站长
2022/06/28
8.5K0
后端框架有哪些?8个流行的后端框架推荐
Python测试开发django1.简介
Django是一种基于Python开发的开源的高级Web应用框架,使用Django,使你能够以最小的代价构建和维护高质量的Web应用。Django 本身基于 MVC 模型,即 Model(模型)+ View(视图)+ Controller(控制器)设计模式,MVC 模式使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能,Python 加 Django 是快速开发、设计、部署网站的最佳组合。
王大力测试进阶之路
2020/09/07
1.3K0
Python测试开发django1.简介
Django如何开发网页
Django作为一款广泛应用于Web开发的框架,其在实际项目中的表现至关重要。掌握Django的开发技巧和最佳实践,不仅可以提高开发者的编程水平,还可以为企业节省开发成本,提高项目竞争力。此外,Django框架在我国的应用也日益广泛,对我国互联网产业的发展产生了积极推动作用。因此,对Django进行深入研究具有重要的实践意义和理论价值。
七条猫
2024/09/21
2540
Django如何开发网页
使用 Django 构建简单 Web 应用
当我们在使用Django构建Web应用时,通常将会涉及到多个步骤,从创建项目到编写视图、模板、模型,再到配置URL路由和静态文件,最后部署到服务器上。所以说如果有一个环节出了问题,都是非常棘手的,下面就是我们经常遇到的问题可以看看。
华科云商小徐
2024/04/01
1790
Django:用于轻松安全 Web 开发的高级 Python Web 框架
Django是一种高级 Python Web 框架,近年来在开发人员中广受欢迎。Django 专注于简单性、安全性和可扩展性,使开发人员可以轻松构建和部署强大的 Web 应用程序。在这份综合指南中,我们将仔细研究是什么让 Django 成为 Web 开发的绝佳选择,并详细探讨其主要特性和功能。
海拥
2023/02/27
6500
二挡起步——pythonweb开发Django框架,前端原生+Django后端框架002(附带小案例)
Django是一个开放源代码的Web应用框架,由Python写成。采用了MTV的框架模式,即模型M,视图V和模版T。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛手Django Reinhardt来命名的。Django是高水准的Python编程语言驱动的一个开源模型.视图,控制器风格的Web应用程序框架,它起源于开源社区。使用这种架构,程序员可以方便、快捷地创建高品质、易维护、数据库驱动的应用程序。这也正是OpenStack的Horizon组件采用这种架构进行设计的主要原因。另外,在Dj ango框架中,还包含许多功能强大的第三方插件,使得Django具有较强的可扩展性 [2] 。Django 项目源自一个在线新闻 Web 站点,于 2005 年以开源的形式被释放出来。
淼学派对
2023/10/14
4210
二挡起步——pythonweb开发Django框架,前端原生+Django后端框架002(附带小案例)
【玩转全栈】----Django基本配置和介绍
Django是一个开源的、基于Python的高级Web框架,旨在以快速、简洁的方式构建高质量的Web应用程序。它由经验丰富的开发者设计,遵循“Don’t Repeat Yourself”(不要重复自己)和“Convention over Configuration”(约定优于配置)的原则,大大提高了开发效率和代码可维护性。Django内置了强大的功能,例如URL路由、ORM(对象关系映射)、模板引擎、表单处理和用户认证等,帮助开发者轻松实现从简单的网站到复杂的企业级应用。它还提供了一个直观的管理后台,让开发者可以快速管理数据模型和内容。此外,Django具有高度的安全性,内置防护如SQL注入、跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。凭借其丰富的文档和强大的社区支持,Django成为开发者快速构建Web应用的首选框架之一,非常适合注重开发速度、代码质量和安全性的项目。
用户11404404
2025/01/02
2340
【玩转全栈】----Django基本配置和介绍
解锁Python Django框架的无限可能:构建现代化、高效的Web应用
在当今数字化时代,Web应用的需求不断增长,而Python的Django框架已经成为许多开发者的首选工具之一。Django以其简洁、高效、可扩展的特性,为开发者提供了强大的工具,帮助他们构建现代化、功能丰富的Web应用程序。
海拥
2023/12/13
3200
众多Python Web框架比较,哪个适合你,你就用哪个!
Python程序员有很多很好的选择来创建Web应用程序和API;Django,Weppy,Bottle和Flask引领潮流。
一墨编程学习
2018/12/06
5.1K0
Python: 10大Web框架简介
在这篇文章中了解一些可供您使用的最佳 Python Web 框架,您可以考虑将它们用于创建 Web 应用程序。Python 是可用于 Web 应用程序开发的最佳框架之一。尽管存在其他框架,但Python是最有前途的,它提供了开发超现代 Web 应用程序所需的各种功能。如果您正在寻找一个框架来启动一个专业的基于 Web 的应用程序,那么 Python 将是正确的选择。本文专门介绍 Python Web 框架,在这里我们试图涵盖所有相关方面。Web 开发过程中最重要和必要的部分是开发最终用户将用于实现其目的的实际网站或 Web 应用程序。什么样的平台都没有关系。无论是使用 Android 还是 iOS、Windows 还是 Mac OS X 等。它应该以最适合最终用户要求的方式进行开发,并且应该为他们提供他们在其网站/Web 应用程序上寻找的所有功能。Python Web 框架用于开发超现代的 Web 应用程序,这已成为任何企业或组织通过向全球客户和客户提供最佳服务来扩展业务的首要要求。
Freedom123
2024/03/29
2K0
Python: 10大Web框架简介
Python四大主流网络编程框架,你知道么?
Tornado 是使用 Python 编写的一个强大的可扩展的 Web 服务器。它在处理高网络流量时表现得足够强健,却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中。Tornado 作为 FriendFeed 网站的基础框架,于2009年9月10日发布,目前已经获得了很多社区的支持,并且在一系列不同的场合中得到应用。除 FriendFeed 和 Facebook 外,还有很多公司在生产上转向Tornado,包括 Quora、Turntable.fm、Bit.ly、Hipmunk 及 MyYearbook 等。
小小科
2020/05/27
2.5K0
Python 四大主流 Web 编程框架
本文内容摘录自《Python高效开发实战——Django、Tornado、Flask、Twisted》一书。
程序员小猿
2021/01/19
1.9K0
Python 四大主流 Web 编程框架
django或flask:哪一个是最好的python web框架?
Web框架使Web开发人员的开发尽可能简单。然而,Python是最流行的编程语言之一,它在后端开发中的应用得到了许多贡献。
gglx
2021/09/17
2.4K0
推荐阅读
相关推荐
《重塑认知:Django MVT架构的多维剖析与实践》
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档