分布式限流——Redis实现令牌桶算法
令牌桶算法
令牌桶算法(Token Bucket Algorithm)是一种广泛使用的流量控制(流量整形)和速率限制算法。这个算法能够控制网络数据的传输速率,确保数据传输的平滑性,防止网络拥堵,同时也被应用于软件系统中限制请求的速率,如API限流等场景。
工作原理
-
令牌的生成:系统以固定的速率向令牌桶中添加令牌(token),直到桶满为止。桶的容量(即最大令牌数)限制了短时间内可以发送的最大数据量。
-
请求的处理:每个传入的请求需要从桶中取出一定数量的令牌。如果桶中有足够的令牌,请求就被处理,消耗掉相应数量的令牌;如果桶中令牌不足,请求则根据策略(如排队、丢弃或延迟处理)来处理。
-
灵活控制:通过调整令牌的生成速率和桶的容量,可以灵活地控制数据传输的平均速率和允许的突发速率。
漏桶算法
漏桶算法(Leaky Bucket Algorithm)是另一种流量控制算法,用于确保数据传输以稳定的速率进行,减少或消除突发流量。与令牌桶算法相比,漏桶算法提供了一种更为严格的速率限制方式。
漏桶算法的工作原理
- 数据流入:数据(如网络包、API请求等)以任意速率流入漏桶。
- 恒定速率流出:数据以恒定的速率从桶中“漏出”(被处理)。如果桶满了(达到其容量),则新进入的数据会被丢弃或排队等待。
- 稳定输出:无论输入数据的速率如何变化,输出数据的速率保持不变,由漏桶的“漏洞”大小决定。
令牌桶算法与漏桶算法的主要区别
- 速率控制灵活性:令牌桶算法允许一定程度的突发流量,因为如果桶中有足够的令牌,突发的请求可以立即被处理。而漏桶算法则以恒定的速率处理请求,输入速率超过这个恒定值的部分将被限制或丢弃,因此不允许突发流量。
- 应对突发流量:令牌桶算法能够更好地应对突发流量。当桶中有足够令牌时,可以一次性处理较多的请求。漏桶算法则始终以固定的速率处理流入的请求,突发流量只能在桶内等待,直到它们逐渐被处理。
- 应用场景:漏桶算法适用于需要严格控制数据传输速率的场景,确保数据处理的平稳性;令牌桶算法则更适用于需要一定程度突发性处理能力的场景,例如网络带宽控制和API限流。
总结
- 漏桶算法通过以固定的速率“漏出”数据来控制数据的传输速率,适用于对输出速率有严格要求的场景。
- 令牌桶算法允许在桶中累积令牌,从而应对突发流量,适用于需要较大灵活性的速率限制场景。
Redis实现令牌桶算法限流
Redis 实现令牌桶算法限流是一种非常有效的限流策略,适用于分布式系统中的接口限流。令牌桶算法的核心思想是以恒定的速率向桶中添加令牌,每个请求需要消耗一定数量的令牌才能被执行。如果桶中令牌不足,则拒绝服务。
在 Redis 中实现令牌桶算法通常可以通过 Lua 脚本来保证操作的原子性,以下是一个基于 Redis 的令牌桶限流实现示例:
-- Lua 脚本实现令牌桶算法
-- key 为 Redis 中用于存储桶的键
-- rate 为令牌填充速率(每秒填充的令牌数)
-- capacity 为桶的容量
-- now 为当前时间戳
-- permits 为本次请求需要的令牌数local key = KEYS[1]
local rate = tonumber(ARGV[1])
local capacity = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local permits = tonumber(ARGV[4])local bucket = redis.call('hmget', key, 'lastRefillTime', 'tokens')
local lastRefillTime = tonumber(bucket[1])
local tokens = tonumber(bucket[2])if lastRefillTime == nil thenlastRefillTime = nowtokens = capacity
end-- 计算自上次填充以来经过的时间
local delta = math.max(0, now - lastRefillTime)
-- 计算应该填充的令牌数
local refillTokens = math.floor(delta * rate)
tokens = math.min(capacity, tokens + refillTokens)
lastRefillTime = nowlocal enoughTokens = false
if tokens >= permits thenenoughTokens = truetokens = tokens - permits
end-- 更新桶的状态
redis.call('hmset', key, 'lastRefillTime', lastRefillTime, 'tokens', tokens)-- 设置过期时间防止无限增长
redis.call('expire', key, math.ceil(capacity/rate)*2)if enoughTokens thenreturn 1
elsereturn 0
end
具体的 key-value 结构
在这个场景中,hash
的键(key)是用来唯一标识一个令牌桶的,而这个 hash
包含了两个字段(field),分别存储了令牌桶的两个重要属性:
- lastRefillTime:最后一次填充令牌的时间戳。
- tokens:当前桶中的令牌数量。
具体的 key-value
结构如下所示:
- Key:令牌桶的唯一标识符,例如
"my_bucket_key",根据具体业务标识有所不同
。 - Value:是一个
hash
结构,包含以下字段:- lastRefillTime:桶最后一次填充令牌的时间戳,用来计算距离上次填充令牌过去了多少时间,以及这段时间内应该填充多少新的令牌。
- tokens:表示当前桶内剩余的令牌数量。
为什么用Hash
在 Redis 中使用 hash
数据结构来实现令牌桶算法的原因主要包括以下几点:
-
空间效率:使用
hash
可以将与令牌桶相关的多个属性(如lastRefillTime
和tokens
)存储在同一个键下。这比为每个属性分别使用一个键要节省空间,因为 Redis 的每个键都会有额外的内存开销。 -
原子操作:Redis 提供了对
hash
类型的一系列原子操作命令,如HSET
,HGET
,HMSET
,HMGET
等。这意味着可以在一个命令中更新令牌桶的多个属性,而无需担心并发访问导致的数据不一致问题。 -
性能优势:相对于单独存储每个属性,
hash
数据结构减少了存储开销和访问时间。对于频繁更新和查询的令牌桶状态信息,这种优势尤为重要。 -
方便管理:使用
hash
数据结构可以将所有与令牌桶相关的信息组织在一起,这使得管理(如查看、更新和删除等操作)更为方便。 -
扩展性:如果将来需要在令牌桶中添加更多的属性(例如,添加一个
rate
字段来存储令牌填充速率),使用hash
结构可以很容易地进行扩展,而无需改变现有的数据结构或逻辑。 -
利用 Lua 脚本进行复杂操作:通过在 Redis 上运行 Lua 脚本,可以在服务器端直接执行复杂的逻辑(如计算新的令牌数量和更新最后填充时间),而不需要在客户端和服务器之间进行多次通信。
hash
数据结构支持通过一个命令对多个字段进行操作,这与 Lua 脚本的使用非常契合。
相关文章:

分布式限流——Redis实现令牌桶算法
令牌桶算法 令牌桶算法(Token Bucket Algorithm)是一种广泛使用的流量控制(流量整形)和速率限制算法。这个算法能够控制网络数据的传输速率,确保数据传输的平滑性,防止网络拥堵,同时也被应用于…...

鸿蒙原生应用已超4000个!
鸿蒙原生应用已超4000个! 来自 HarmonyOS 微博近期消息,#鸿蒙千帆起# 重大里程碑!目前已有超4000个应用加入鸿蒙生态。从今年1月18日华为宣布首批200多家应用厂商正在加速开发鸿蒙原生应用,到3月底超4000个应用,短短…...

manga-ocr漫画日文ocr
github 下载 解压 anaconda新建环境 conda create -n manga_ocr python3.8 激活环境 conda activate manga_ocr cd到解压目录 cd /d manga-ocr-master 安装依赖包 pip install -r requirements.txt pip3 install manga-ocr 下载离线model huggingface 123云盘 解压到一个目录…...

STL、Vector和Set的讲解和例题分析
STL STL(Standard Template Library,标准模板库)是C标准库的一部分,它提供了一系列通用的编程组件,包括容器、迭代器、算法和函数对象等。STL是C中实现泛型编程的核心,它允许程序员使用模板编写与数…...

Android 13 aosp hiddenapi config
Android 11 hiddenapi路径 frameworks/base/config/hiddenapi-greylist-packages.txtAndroid 13 hiddenapi路径 frameworks/base/boot/hiddenapi/hiddenapi-unsupported-packages.txt...

数据仓库面试总结
文章目录 1.什么是数据仓库?2.ETL是什么?3.数据仓库和数据库的区别(OLTP和OLAP的区别)4.数据仓库和数据集市的区别5.维度分析5.1 什么是维度?5.2什么是指标? 6.什么是数仓建模?7.事实表7.维度表…...

git Failed to connect to 你的网址 port 8282: Timed out
git Failed to connect to 你的网址 port 8282: Timed out 出现这个问题的原因是:原来的仓库换了网址,原版网址不可用了。 解决方法如下: 方法一:查看git用户配置是否有如下配置 http.proxyhttp://xxx https.proxyhttp://xxx如果…...
[C++][算法基础]堆排序(堆)
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。 输入格式 第一行包含整数 n 和 m。 第二行包含 n 个整数,表示整数数列。 输出格式 共一行,包含 m 个整数,表示整数数列中前 m 小的数。 数据范围 1≤m≤n≤&#x…...

备考ICA----Istio实验15---开启 mTLS 自动双向认证实验
备考ICA----Istio实验15—开启mTLS自动双向认证实验 在某些生成环境下,我们希望微服务和微服务之间使用加密通讯方式来确保不被中间人代理. 默认情况下Istio 使用 PERMISSIVE模式配置目标工作负载,PERMISSIVE模式时,服务可以使用明文通讯.为了只允许双向 TLS 流量,…...

Hive SchemaTool 命令详解
Hive schematool 是 hive 自带的管理 schema 的相关工具。 列出详细说明 schematool -help直接输入 schematool 或者schematool -help 输出结果如下: usage: schemaTool-alterCatalog <arg> Alter a catalog, requires--catalogLocation an…...

51单片机入门_江协科技_17~18_OB记录的笔记
17. 定时器 17.1. 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成,无需占用CPU外围IO接口; 定时器作用: (1)用于计时系统,可实现软件计时&…...

xss.pwnfunction-Ah That‘s Hawt
<svg/onloadalert%26%2340%3B1%26%2341%3B> <svg/>是一个自闭合形式 ,当页面或元素加载完成时,onload 事件会被触发,从而可以执行相应的 JavaScript 函数...

Python学习从0开始——005数据结构
Python学习从0开始——005数据结构 一、列表list二、元组和序列三、集合四、字典五、循环技巧六、条件控制七、序列和其它类型的比较 一、列表list 不是所有数据都可以排序或比较。例如,[None, ‘hello’, 10] 就不可排序,因为整数不能与字符串对比&…...

力扣每日一题:LCR112--矩阵中的最长递增路径
题目 给定一个 m x n 整数矩阵 matrix ,找出其中 最长递增路径 的长度。 对于每个单元格,你可以往上,下,左,右四个方向移动。 不能 在 对角线 方向上移动或移动到 边界外(即不允许环绕)。 示例…...

树莓派部署yolov5实现目标检测(ubuntu22.04.3)
最近两天搞了一下树莓派部署yolov5,有点难搞(这个东西有点老,版本冲突有些包废弃了等等) 最后换到ubuntu系统弄了,下面是我的整体步骤(建议先使能一下ssh(最下面有),结合…...

2024 年最新使用 Wechaty 开源框架搭建部署微信机器人(微信群智能客服案例)
读取联系人信息 获取当前机器人账号全部联系人信息 bot.on(ready, async () > {console.log("机器人准备完毕!!!")let contactList await bot.Contact.findAll()for (let index 0; index < contactList.length; index) {…...

Redis从入门到精通(九)Redis实战(六)基于Redis队列实现异步秒杀下单
↑↑↑请在文章开头处下载测试项目源代码↑↑↑ 文章目录 前言4.5 分布式锁-Redisson4.5.4 Redission锁重试4.5.5 WatchDog机制4.5.5 MutiLock原理 4.6 秒杀优化4.6.1 优化方案4.6.2 完成秒杀优化 4.7 Redis消息队列4.7.1 基于List实现消息队列4.7.2 基于PubSub的消息队列4.7.…...

什么是多路复用器滤波器
本章将更深入地介绍多路复用器滤波器,以及它们如何用于各种应用中。您将了解到多路复用器如何帮助设计人员创造出更复杂的无线产品。 了解多路复用器 多路复用器是一组射频(RF)滤波器,它们组合在一起,但不会彼此加载,可以在输出之…...

Severt和tomcat的使用(补充)
打包程序 在pom.xml中添加上述代码之后打包时会生成war包并且包的名称是test 默认情况打的是jar包.jar里量但是tomcat要求的是war包. war包Tomcat专属的压缩包. war里面不光有.class还有一些tomcat要求的配置文件(web.xml等)还有前端的一些代码(html, css, js) 点击其右边的m…...

JavaEE初阶——多线程(一)
T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 小比特 大梦想 此篇文章与大家分享多线程的第一部分:引入线程以及创建多线程的几种方式 此文章是建立在前一篇文章进程的基础上的 如果有不足的或者错误的请您指出! 1.认识线程 我们知道现代的cpu大多都是多核心…...

MongoDB主从复制模式基于银河麒麟V10系统
MongoDB主从复制模式基于银河麒麟V10系统 背景介绍 MongoDB自4.0版本开始已经不再建议使用传统的master/slave复制架构,而是全面采用了复制集(Replica Sets)作为标准的复制和高可用性解决方案。 复制集是MongoDB的一种数据复制和高可用性机制,通过异步同步数据至多个服务…...

Vue使用高德地图
1.在高德平台注册账号 2.我的 > 管理管理中添加Key 3.安装依赖 npm i amap/amap-jsapi-loader --save 或 yarn add amap/amap-jsapi-loader --save 4.导入 AMapLoade import AMapLoader from amap/amap-jsapi-loader; 5.直接上代码,做好了注释(初始化…...

2024-04-07(复盘前端)
---HTML 1.HTMl骨架 html:整个网页 head:网页头部,用来存放给浏览器看的信息,如css body:网页主体,用来存放给用户看的信息,例如图片和文字 2.标题标签中h1标签只能使用一次,其…...

SpringCloud学习(10)-SpringCloudAlibaba-Nacos服务注册、配置中心
Spring Cloud Alibaba 参考文档 Spring Cloud Alibaba 参考文档 nacos下载Nacos 快速开始 直接进入bin包 运行cmd命令:startup.cmd -m standalone 运行成功后通过http://localhost:8848/nacos进入nacos可视化页面,账号密码默认都是nacos Nacos服务注…...

OKCC外呼中心配置的电话系统规则
OKCC外呼中心配置电话系统规则可能涉及多个方面,包括呼叫路由、自动化流程、电话接听策略等。以下是一般步骤及注意事项: 呼叫路由配置: 确定呼叫中心的呼叫路由策略,包括如何分配呼叫给不同的坐席或部门。设置呼叫路由规则&#…...

AI推介-大语言模型LLMs论文速览(arXiv方向):2024.03.31-2024.04.05
文章目录~ 1.AutoWebGLM: Bootstrap And Reinforce A Large Language Model-based Web Navigating Agent2.Training LLMs over Neurally Compressed Text3.Unveiling LLMs: The Evolution of Latent Representations in a Temporal Knowledge Graph4.Visualization-of-Thought …...

性能测试工具 ab(Apache Bench)使用详解
Apache Bench (ab) 是一个由 Apache 提供的非常流行的、简单的性能测试工具,用于对 HTTP 服务器进行压力测试。下面是 ab 工具的一些基本使用方法。 安装 在大多数 Unix 系统中,ab 通常作为 Apache HTTP 服务器的一部分预装在系统中。你可以通过在终端…...

智能网联汽车自动驾驶数据记录系统DSSAD数据元素
目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…...

Ubuntu 20.04.06 PCL C++学习记录(十八)
[TOC]PCL中点云分割模块的学习 学习背景 参考书籍:《点云库PCL从入门到精通》以及官方代码PCL官方代码链接,,PCL版本为1.10.0,CMake版本为3.16 学习内容 PCL中实现欧式聚类提取。在点云处理中,聚类是一种常见的任务,它将点云数据划分为多…...

细雨踏春日,新会公安护平安
春雨起,清明至。又是一年春草绿,又是一年清明时。细雨踏春日,思怀故人时,是哀思,亦是相聚。新会公安一抹抹葵乡春日“警”色坚守岗位,确保清明祭扫平稳有序,为人民群众的平安保驾护航。 为确保2…...