【redis】redis应用场景,缓存的各种问题

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: redis有一个重要的应用领域——缓存引用来自网友的图解释缓存在架构中的位置默认情况下,我们的服务架构如下图,客户端请求service,然后service去读取mysql数据库问题存在于,数据库性能不够用,数据库是整个架构中最重要的一个环节,它在高并发,高写入频次的时候非常容易崩掉,这是一般的数据库本身的特性所决定的,它们的架构模式注定了不可以承受较大的并发量,所以就有了缓存:service与高速的缓存进行交互,如果缓存中有数据直接返回客户端,如果没有才会从MySql中去查询。

redis有一个重要的应用领域——缓存

引用来自网友的图解释缓存在架构中的位置

默认情况下,我们的服务架构如下图,客户端请求service,然后service去读取mysql数据库

问题存在于,数据库性能不够用,数据库是整个架构中最重要的一个环节,它在高并发,高写入频次的时候非常容易崩掉,这是一般的数据库本身的特性所决定的,它们的架构模式注定了不可以承受较大的并发量,所以就有了缓存:

service与高速的缓存进行交互,如果缓存中有数据直接返回客户端,如果没有才会从MySql中去查询。减小数据库的压力,提升效率,避免宕机。

例如上面章节提到的,超卖问题,有可能瞬间的流量高达上万,我们不可能把这些请求都响应到数据库上,这样速度慢不说,还随时可能宕机。

提到缓存,就不得不说下面的四大缓存名场面,几乎是做缓存必须面对的问题。

缓存击穿
想象一个场景,现在在一个xx办事大厅

张三、李四、王五、赵六、钱钱、刘八、陈九 七个人正在排队

办事处有一个窗口,有一些自动业务机,窗口里面的同志一下子只能接待一个人,而自动业务机因为速度很快可以很快接待很多人。

现在,突然、自动业务机都坏了... 所有人都排到了窗口,这下忙死了窗口里面的同志,直接撂挑子不干了!

这个例子中,自动业务机就像是缓存,起了一个缓冲的作用,业务员就像是数据库,处理能力比自动机器慢,而且很容易炸毛。

缓存击穿就是这样,当某个缓存故障、或者在高峰期缓存突然无效了,就会导致所有请求都跑到数据库去排队,就造成了缓存击穿。

缓存相当于给数据库加了一层保护能量罩,敌人进来的时候如果某个地方没有能量,那么如果这个地方的敌人特别多,就会导致缓存击穿。当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,或者高峰流量,频繁去访问缓存中没有的数据,那么缓存就失去了存在的意义,瞬间所有请求的压力都落在了数据库上,这样会导致数据库连接异常。

解决方案:

后台设置定时任务,主动的去更新缓存数据。这种方案容易理解,就是在自动业务机旁边加了一个维护员,坏了赶紧修好,但是机器多了就比较复杂,维护员不一定能搞得定,当key比较分散的时候,操作起来还是比较复杂的

分级缓存。什么意思呢,就是放两台业务机器,平时用第一台,第一台坏了马上用第二台,用第二台的时候修第一台,设置两层缓存保护层,1级缓存失效时间短,2级缓存失效时间长。有请求过来优先从1级缓存中去查找,如果在1级缓存中没有找到相应数据,则对该线程进行加锁,这个线程再从数据库中取到数据,更新至1级和2级缓存。其他线程则直接从2级线程中获取

缓存穿透
缓存穿透本质上和缓存击穿所面临的问题一样,大量请求落到数据库中。

但是出发点略有不用,缓存穿透的问题是,在高并发下,查询一个不存在的值时,缓存不会被命中,导致大量请求直接落到数据库上,如活动系统里面查询一个不存在的活动。

也就是说,缓存击穿是当数据是存在的,但没有被缓存到,而缓存穿透是去访问根本不存在的值。想象一个场景,黑客截取了一个已经过期的活动的数据接口,然后不断的去请求它,这时候有可能因为这个活动本身已经过期了,缓存不会命中,请求就全部落地到数据库了,这时候就造成了缓存穿透。

缓存穿透的问题解决方案也有很多

直接缓存NULL值

这个比较容易理解,就算是没数据我也缓存一下,你下次过来命中的是空数据。

这种方法需要特别注意,为空的值不能缓存的太久,否则有可能在真的有数据的时候影响了业务正常流程。

布隆过滤器

什么是布隆过滤器

布隆过滤器判断一个值不存在,那么这个值100%不存在

布隆过滤器判断一个值存在,这个值90%是存在的

布隆过滤器本质是一个位数组,位数组就是数组的每个元素都只占用 1 bit 。每个元素只能是 0 或者 1。这样申请一个 10000 个元素的位数组只占用 10000 / 8 = 1250 B 的空间。布隆过滤器除了一个位数组,还有 K 个哈希函数。

等一下,是不是有点绕,不太好理解。

我们知道hash函数可以根据一个值生成一个对应的数字,然后与一个长度可以取模可以得到一个下标值 (你不知道?看看HashMap的实现吧)

或者你根本不知道hash是怎么实现的,没关系,也可以先理解下面的,我们先把这个函数假设为 int getIndex (String value), 根据值获取到一个下标

假设我们现在有一个数组,长度是5,每个元素的值都是0

0 , 0 , 0 , 0 , 0

现在我们数据库中一共有五个id

a , b , c , d , e

现在我们对id们执行getIndex函数可以得到

getIndex(a) = 0

getIndex(b) = 1

getIndex(c) = 1 // 假设函数有一些误差

getIndex(d) = 2

getIndex(e) = 3

想一想,现在来了一个新元素,f 怎么样判断在id里面存在不存在呢?

我们把开始的数组和getIndex关联起来, 将getindex的值作为下标,设置值为1,数组就会变成

1 , 1 , 1 , 1 , 0

然后我们再来判断f是否存在,假设 getIndex(f) = 4

ok了,我们只需要判断数组里的下标4是否是1,是1就存在,0就不存在了嘛

那如果 getIndex(f) = 2 呢? 我们开了上帝视角,很明显f不存在呀。

布隆过滤器不能100%判断一个元素是否真的存在数组中,但能100%判断它不存在与数组中,这取决于hash函数的算法程度

布隆过滤器防止缓存穿透

通过对布隆过滤器的理解,我们能就过滤掉大部分的无效请求了,把数据库中所有的id都getindex解析一次放到布隆过滤器中,请求过来的时候判断,如果不存在就直接返回空就行了

缓存雪崩
如果缓存集中在一段时间内失效,发生大量的缓存穿透,所有的查询都落在数据库上,造成了缓存雪崩。

其实与缓存击穿的理论差不多,都是突然失效导致的击穿数据库。

雪崩与击穿的不同点在于雪崩强调集中失效两个字

想象~ 我现在有三个缓存key存在redis中,过期时间是一天

一天后,由于key有可能是同时设置的缓存,导致这三个key同时失效了,即使我的缓存击穿问题已经解决,这时候因为集中的key失效,也会造成击穿!,这是量级发生了改变,就像x和y的关系, x表示key的多少,y表示请求的多少。。。

解决方案

设置不同的过期时间
热度数据
你永远不可能每个缓存都能命中的。什么是好的缓存策略,好的缓存策略是能够识别热点数据,并在热点被读取的时候能够保证命中,这是一个好的缓存策略所必须的条件之一。

缓存一致性

数据库的数据和缓存的数据是不可能一致的,数据分为最终一致和强一致两类。

强一致 不可以使用缓存

缓存能做的只能保证数据的最终一致性。

我们能做的只能是尽可能的保证数据的一致性。

不管是先删库再删缓存 还是 先删缓存再删库,都可能出现数据不一致的情况,因为读和写操作是并发的,我们没办法保证他们的先后顺序。

具体应对策略根据业务需求来制订。

缓存过期和淘汰

Redis设置的过期时间。这个key过期时是怎么删除的?

Redis采用的是定期删除,注意不是定时删除,不可能为每一个key做一个定时任务去监控删除,这样会耗尽服务器资源。

默认是每100ms检测一次,遇到过期的key则进行删除,这里的检测也不是顺序检测,而是随机检测。

另外为了防止有漏网之鱼,例如在100ms检查的中间间隙,某个key过期,但同时key访问又进来了,这时触发 惰性删除策略 redis会在读取时判断是否已经过期,过期则直接删除。

内存淘汰是指一部分key在内存不够用的情况下会被Redis自动删除,从而会出现从缓存中查不到数据的情况。

例如我们的服务器内存为2G、但是随着业务的发展缓存的数据已经超过2G了。但是这并不能影响我们程序的运行。所以redis会从key列表中抽取一定的热度低的数据进行淘汰策略,腾出空间存储新的key

...持续更新

github: https://github.com/294678380/redis-lerning

原文地址https://www.cnblogs.com/ztfjs/p/redis-cache.html

相关实践学习
基于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
相关文章
|
1天前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
9天前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
66 22
|
8天前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
68 7
|
13天前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
46 10
|
1月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(一)
数据的存储--Redis缓存存储(一)
|
存储 缓存 NoSQL
DB,Cache和Redis应用场景分析
最近做一产品,微博方面的。数据存储同时用到了DB(mysql),Cache(memcache),Redis。其实最开始架构设计的时候是准备用MongoDB的,由于学习成本太高,最终选择放弃了,采用了比较保守的方案。
1163 0
|
1月前
|
存储 缓存 NoSQL
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
数据的存储--Redis缓存存储(二)
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
68 6
|
1月前
|
缓存 NoSQL 关系型数据库
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
本文深入探讨了Redis缓存的相关知识,包括缓存的概念、使用场景、可能出现的问题(缓存预热、缓存穿透、缓存雪崩、缓存击穿)及其解决方案。
162 0
redis和缓存及相关问题和解决办法 什么是缓存预热、缓存穿透、缓存雪崩、缓存击穿
|
13天前
|
缓存 监控 NoSQL
Redis 缓存穿透的检测方法与分析
【10月更文挑战第23天】通过以上对 Redis 缓存穿透检测方法的深入探讨,我们对如何及时发现和处理这一问题有了更全面的认识。在实际应用中,我们需要综合运用多种检测手段,并结合业务场景和实际情况进行分析,以确保能够准确、及时地检测到缓存穿透现象,并采取有效的措施加以解决。同时,要不断优化和改进检测方法,提高检测的准确性和效率,为系统的稳定运行提供有力保障。
44 5
下一篇
无影云桌面