分布式限流——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大多都是多核心…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
