一个 Redis 的雪崩和穿透问题,小学妹画了个图,结果入职了(下)

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Redis 版,经济版 1GB 1个月
简介: 阿粉的一个小学妹最近刚从某个小互联网公司跳槽,然后最近面试的挺多的,一个不善言语的小姑娘,技术还是 OK 的,本来之前是做 UI 的,但是时间长了,感觉没太大意思,所以就开始学了后端,然后从原有公司慢慢的转为了后端开发人,也就是我们所说的 “程序猿”,最近面试给阿粉谈了谈她的面试经验。阿粉比较印象深刻的一句话就是,我给你画个图,你看一下,这是对面试官说的,事情是什么样子的呢?

那么怎么实现限流呢?

说到限流降级了,那就不能单纯的去针对 Redis 出现的问题而进行处理了,而实际上是为了保证用户保护服务的稳定性来进行的。

那么为什么要去限流呢?你要单纯的说是为了保证系统的稳定性,那面试官估计得崩溃,这和没说有啥区别,你得举个简单的例子才能正儿八经的忽悠住面试官,比如:

假设,我们当前的程序能够处理10个请求,结果第二天,忽然有200多请求一起过来,整整翻了20倍,这时候,程序就凉了,但是如果第一天晚上的时候,领导给你说,明天你写的那个程序大约会有200多个请求要处理,你这时候是不是得想办法,比如说,能不能再写出另外的一段程序来进行分担请求,这时候其实就相当于需要我们去限流了。

限流算法之漏桶算法

同样的,我们整个图来理解一下这个算法到底是怎么实现的。66.jpg

67.jpg

如果一桶有一个细眼,我们往里面装水,可以看到水是一滴一滴匀速的下落的,如果桶满了就拒绝水滴继续滴入,没满的话就继续装水,实际上就是这样的水滴实际上就相当于是请求,如果水桶没满的时候,还能继续处理我们进来的请求,当水桶满了的时候,就拒绝处理,让他溢出。

前提是我们的这个桶是个固定的容器,不能随着水的增多桶会变大,要不然那还用什么限流算法。

简单的漏桶算法的实现:

public class LeakyBucket {
        public long timeStamp = System.currentTimeMillis();  // 当前时间
        public long capacity; // 桶的容量
        public long rate; // 水漏出的速度
        public long water; // 当前水量(当前累积请求数)
        public boolean grant() {
            long now = System.currentTimeMillis();
            // 先执行漏水,计算剩余水量
            water = Math.max(0, water - (now - timeStamp) * rate); 
            timeStamp = now;
            if ((water + 1) < capacity) {
                // 尝试加水,并且水还未满
                water += 1;
                return true;
            } else {
                // 水满,拒绝加水
                return false;
        }
    }
}

上面的代码是来自悟空,不得不说,这个简单的例子虽然简单,但是把这个漏桶算法的简单原理描述的还是差不多的,而在这里最需要注意的,就是桶的容量,还有就是水桶漏洞的出水的速度。

既然我们了解了漏桶算法是如何实现限流的,那么必然也会有他处理不来的情况,因为我们已经定义了水漏出的速度,而这时候如果应对突发的流量忽然涌进来,他处理起来效率就不够高了,因为水桶满了之后,请求都拒绝了,都不处理了。

其实我们所说的漏桶算法还可以看作是一个带有常量服务时间的单服务器队列,如果漏桶(包缓存)溢出,那么数据包会被丢弃。

而我们的漏桶算法主要是能够强行限制数据的传输速率。

那么又有什么算法能够不进行强制限制传输速率,并且实现限流呢?

令牌桶算法

68.jpg

我们感谢百度,我从百度图片中找了个一个比较给力的图来描述令牌桶的算法。

令牌桶算法的基本过程是这个样子的:

  1. 用户配置的平均发送速率为r,则每隔1/r秒一个令牌被加入到桶中
  2. 假设桶最多可以存发b个令牌。如果令牌到达时令牌桶已经满了,那么这个令牌会被丢弃
  3. 当一个n个字节的数据包到达时,就从令牌桶中删除n个令牌,并且数据包被发送到网络
  4. 如果令牌桶中少于n个令牌,那么不会删除令牌,并且认为这个数据包在流量限制之外

乍一看,怎么感觉这个令牌桶和漏桶这么像,一个是水滴,一个是令牌,实际上不是。

令牌桶这种控制机制基于令牌桶中是否存在令牌来指示什么时候可以发送流量。令牌桶中的每一个令牌都代表一个字节。如果令牌桶中存在令牌,则允许发送流量;而如果令牌桶中不存在令牌,则不允许发送流量。

而且他是能够应对突发限制的,虽然传输的速率受到了限制.所以它适合于具有突发特性的流量的一种算法。

而在 Google 开源工具包中的限流工具类RateLimiter ,这个类就是根据令牌桶算法来完成限流。大家有兴趣的可以去看看呀。

漏桶算法和令牌桶算法的区别

漏桶算法与令牌桶算法实际上看起来有点相似,但是不能混淆哈,这就是阿粉在上面说的:

  • 漏桶算法能够强行限制数据的传输速率。
  • 令牌桶算法能够在限制数据的平均传输速率的同时还允许某种程度的突发传输

关于阿粉今天说的这些你学会了么?

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
存储 缓存 NoSQL
redis缓存雪崩、穿透、击穿
redis缓存雪崩、穿透、击穿
|
1月前
|
缓存 NoSQL 安全
【Redis】缓存穿透
【Redis】缓存穿透
41 0
|
1月前
|
缓存 NoSQL 数据库
探秘Redis读写策略:CacheAside、读写穿透、异步写入
本文介绍了 Redis 的三种高可用性读写模式:CacheAside、Read/Write Through 和 Write Behind Caching。CacheAside 简单易用,但可能引发数据不一致;Read/Write Through 保证数据一致性,但性能可能受限于数据库;Write Behind Caching 提高写入性能,但有数据丢失风险。开发者应根据业务需求选择合适模式。
292 2
探秘Redis读写策略:CacheAside、读写穿透、异步写入
|
1月前
|
存储 缓存 NoSQL
redis之缓存穿透,击透,雪崩~
redis之缓存穿透,击透,雪崩~
|
30天前
|
缓存 监控 NoSQL
redis 缓存穿透 击穿 雪崩 的原因及解决方法
redis 缓存穿透 击穿 雪崩 的原因及解决方法
|
12天前
|
缓存 NoSQL Redis
蓝易云 - 如何使用Redis来防止穿透、击穿和雪崩问题
1. 缓存雪崩:缓存雪崩是指缓存中的大部分数据同时失效,导致短时间内大量的请求直接打到数据库上。防止缓存雪崩的方法是,给每一个key设置一个随机的过期时间,这样可以保证不会有大量的key同时失效。
12 1
|
2天前
|
缓存 NoSQL Java
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
Redis系列学习文章分享---第四篇(Redis快速入门之Java客户端--商户查询缓存+更新+双写一致+穿透+雪崩+击穿+工具封装)
6 0
|
1月前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
138 3
|
1月前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
1月前
|
缓存 NoSQL 算法
Redis 解决缓存雪崩 缓存穿透 缓存击穿(Redis使用必看)
Redis 解决缓存雪崩 缓存穿透 缓存击穿(Redis使用必看)
35 1