当前位置: 首页 > news >正文

基于Redis实现令牌桶算法

基于Redis实现令牌桶算法

  • 令牌桶算法
      • 算法流程图
      • 优点
      • 缺点
    • 实现
    • 其它限流算法

令牌桶算法

令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制(流量不均匀或变化的衡量标准)。它还可以用作调度算法来确定符合带宽和突发性限制设置的传输时序。

算法流程图

如图所示,令牌桶算法可以描述为:

  • 令牌桶初始大小和容量为X
  • 以一定速率Y向令牌桶中添加令牌,如果令牌桶满了,忽略多余令牌
  • 每次请求令牌桶拿Z个令牌,如果当前令牌桶不足,则拒绝当前请求

令牌桶图示

优点

  • 平滑流量:
    令牌桶可以通过控制令牌放入速率(Y)平滑流量,防止过高负载导致系统崩溃
  • 可以处理突发流量
    令牌桶可以积累一定量的令牌以应对突发流量
  • 灵活
    通过调整令牌桶的容量和令牌放入速率,可以灵活地控制突发容量和请求的平均处理速率。这种灵活性使得令牌桶算法能够适应不同应用场景。

缺点

  • 资源占用
    令牌桶算法需要维护当前令牌数和上次放入时间, 这会耗费较高的计算资源。
  • 参数调整复杂
    令牌桶算法需要调整容量(X)、速率(Y)和每次请求令牌数量(Z),不合适的参数有可能导致请求分配不公平乃至饥饿请求(长时间无法获取到令牌的请求)。
  • 依赖系统时间
    令牌桶算法在计算令牌数量时依赖于系统时间。如果系统时间发生异常(如时间回拨),则可能会导致算法失效或产生不可预测的结果。

实现

本文是使用Redis的Lua脚本来实现的

--- 实现令牌桶算法
-- 以一定的频率向令牌桶中放入令牌, 其它人使用时获取令牌, 如果能够获取成功
local expire_time = 3600 -- 1个小时失效
local bucket_size = 20 -- 一个桶最多有20张令牌
local bucket_speed = 3.5 -- 每秒增加令牌的个数
local requests_token = 1 -- 请求一次耗费的令牌数local time = redis.call('TIME')
local current_time = time[1] * 1000 + time[2] / 1000 -- TIME返回的是 秒,纳秒.  这里转换成微秒
local token = KEYS[1]-- 获取当前剩余令牌数
local bucket = redis.call('HGETALL', token)
local ret = 0
if table.maxn(bucket) == 0 then-- 令牌桶已失效或者还没有设置redis.call('HSET', token, 'lastRefillTime', current_time)redis.call('HSET', token, 'tokensRemain', bucket_size - requests_token)redis.call('PEXPIRE', token, expire_time * 1500)ret = 1
else-- 上次填充时间local lastRefillTime = tonumber(bucket[2])-- 剩余令牌数local tokensRemain = tonumber(bucket[4])-- 距离上次调用时间local cost_time = current_time - lastRefillTimeif cost_time < 0 then-- 发生了时间回拨, 令牌不再增加current_time = lastRefillTimeif tokensRemain >= requests_token thentokensRemain = tokensRemain - requests_tokenret = 1endelseif tokensRemain >= 1 or cost_time * bucket_speed / 1000 >= requests_token thentokensRemain = math.min(tokensRemain + (cost_time * bucket_speed / 1000) - requests_token, bucket_size - requests_token)ret = 1elsetokensRemain = tokensRemain + (cost_time * bucket_speed / 1000)ret = 0endredis.call('HSET', token, 'lastRefillTime', current_time)redis.call('HSET', token, 'tokensRemain', tokensRemain)redis.call('PEXPIRE', token, expire_time * 1500)
end
return ret

其它限流算法

  • 计数器算法
  • 滑动窗口算法
  • 漏桶算法

相关文章:

基于Redis实现令牌桶算法

基于Redis实现令牌桶算法 令牌桶算法算法流程图优点缺点 实现其它限流算法 令牌桶算法 令牌桶是一种用于分组交换和电信网络的算法。它可用于检查数据包形式的数据传输是否符合定义的带宽和突发性限制&#xff08;流量不均匀或变化的衡量标准&#xff09;。它还可以用作调度算…...

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成&#xff1f;安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯&#xff0c;并且它确实相对其他的 IDE 较为轻量化…...

奇怪的知识又增加了,ESP32下的Lisp编程:ULisp--Lisp for microcontrollers

ESP32下有MicroPython&#xff0c;那么我就在想&#xff0c;有Lisp语言支持吗&#xff1f;答案是果然有&#xff01;有ULisp&#xff0c;专门为MCU设计的Lisp&#xff01; 网址&#xff1a;uLisp - Lisp for microcontrollers 介绍&#xff1a;用于微控制器的 Lisp 适用于 Ar…...

STM32标准库学习之寄存器方法点亮LED灯

STM32C8T6最小系统开发板&#xff0c;点亮PC13引脚的LED灯 1.使能PC13引脚的定时器 PC13引脚为GPIOC组的第13个端口&#xff0c;GPIO的时钟使能定时器为RCC_APB2ENR&#xff0c;这是可以从手册中得出的&#xff0c;如下图所示 从下图可以得出&#xff0c;若要使能GPIOC端口&a…...

Jenkins:持续集成与持续部署的利器

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《未来已来&#xff1a;云原生之旅》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Jenkins 2、Jenkins的起源 二、Jenkins的核心…...

概率论得学习和整理30: 用EXCEL 描述泊松分布 poisson distribution

目录 1 泊松分布的基本内容 1.1 泊松分布的关键点 1.1.1 属于离散分布 1.1.2 泊松分布的特点&#xff1a;每个子区间内概率相等 &#xff0c; λ就是平均概率 1.2 核心参数 1.3 pmf公式 1.4 期望和方差 2 例1&#xff1a;用EXCEL计算泊松分布的概率 3 比较λ不同值时…...

汽车SoC芯片及其安全岛设计与未来发展趋势(学习笔记)

SoC系列已发布多篇文章&#xff0c;之前应该发布到4.3章节&#xff0c;后续还有包含常见汽车SoC&#xff0c;SoC评价指标&#xff0c;产业链及发展趋势等&#xff0c;均见已发布完整版本付费资源&#xff0c;链接如下&#xff1a; 汽车SoC芯片及其安全岛设计与未来发展趋势&am…...

【排序算法】——选择排序

前言 排序(Sorting) 是计算机程序设计中的一种重要操作&#xff0c;它的功能是将一个数据元素&#xff08;或记录&#xff09;的任意序列&#xff0c;重新排列成一个关键字有序的序列。所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#x…...

第十五章 Linux Shell 编程

15.1 Shell 变量 了解&#xff1a;Shell的功能 了解&#xff1a;Shell的种类 了解&#xff1a;Shell的调用 了解&#xff1a;Shell变量的概念 了解&#xff1a;Shell变量的定义 了解&#xff1a;Shell数组变量 了解&#xff1a;Shell内置变量 了解&#xff1a;双引号 和…...

【c++笔试强训】(第三十八篇)

目录 不相邻取数&#xff08;动态规划-线性dp&#xff09; 题目解析 讲解算法原理 编写代码 空调遥控&#xff08;⼆分/滑动窗⼝&#xff09; 题目解析 讲解算法原理 编写代码 不相邻取数&#xff08;动态规划-线性dp&#xff09; 题目解析 1.题目链接&#xff1a;不相…...

go 自己写序列化函数不转义

以map[int32]string转化为[]byte为例 背景&#xff1a;算法传给我一个map[int32]string类型的值&#xff08;map的值本身是json转化成的string&#xff09;&#xff0c;我需要把这个值生成一个文件上传到OSS&#xff0c;但是发现通过url下载下来的文件里面有转义字符。 原因&a…...

一般行业安全管理人员考试题库分享

1.在高速运转的机械飞轮外部安装防护罩&#xff0c;属于(B)安全技术措施。 A.限制能量 B.隔离 C.故障设计 D.设置薄弱环节 2.生产经营单位的(B)是本单位安全生产的第一责任人&#xff0c;对落实本单位安全生产主体责任全面负责&#xff0c;具体履行安全生产管理职责。 A.全员 B…...

Marketo REST API 批量修改邮件内容

以下是更加细化的 使用 Marketo REST API 批量修改邮件内容 的步骤&#xff0c;详细解释每个阶段的操作&#xff0c;包括 API 的请求、数据处理及潜在问题解决。 前期准备工作 确保 Marketo API 访问权限 你需要 Marketo REST API 用户 和 API Role&#xff0c;有权限访问邮件资…...

《云原生安全攻防》-- K8s安全框架:认证、鉴权与准入控制

从本节课程开始&#xff0c;我们将来介绍K8s安全框架&#xff0c;这是保障K8s集群安全比较关键的安全机制。接下来&#xff0c;让我们一起来探索K8s安全框架的运行机制。 在这个课程中&#xff0c;我们将学习以下内容&#xff1a; K8s安全框架&#xff1a;由认证、鉴权和准入控…...

淘宝获取sku详细信息 API

淘宝获取 SKU 详细信息的 API 主要是 taobao.item_sku 接口&#xff0c;以下是详细介绍&#xff1a; 公共参数 key&#xff1a;调用 key&#xff0c;是调用接口的身份验证信息&#xff0c;必须以 GET 方式拼接在 URL 中1.secret&#xff1a;调用密钥&#xff0c;与 key 配合使…...

基于Spring Boot的体育商品推荐系统

一、系统背景与目的 随着电子商务的快速发展和人们健康意识的提高&#xff0c;体育商品市场呈现出蓬勃发展的态势。然而&#xff0c;传统的体育商品销售方式存在商品种类繁多、用户选择困难、个性化需求无法满足等问题。为了解决这些问题&#xff0c;基于Spring Boot的体育商品…...

C++小细节笔记

1、C字符串转数字 – 数字转字符串 //string > int 使用 stoi stol//int > string 使用 to_string()2、C遍历 int evalRPN(vector<string>& tokens) {stack<int> intStack;for(string &str:tokens){}bool isValid(string s) {stack<char> …...

go语言并发读写数据队列,不停写的同时,一次最多读取指定量数据(逐行注释)

1、数据队列可以存储任意类型的一个数据&#xff08;下程序是添加整数值&#xff09;。 数据队列代码点这里查看《go语言结构体实现数据结构队列&#xff08;先进先出&#xff09;存储数据&#xff08;逐行注释&#xff09;》 2、读写操作并发进行&#xff08;下程序向队列中…...

密码学——密码学概述、分类、加密技术(山东省大数据职称考试)

大数据分析应用-初级 第一部分 基础知识 一、大数据法律法规、政策文件、相关标准 二、计算机基础知识 三、信息化基础知识 四、密码学 五、大数据安全 六、数据库系统 七、数据仓库. 第二部分 专业知识 一、大数据技术与应用 二、大数据分析模型 三、数据科学 密码学 大数据…...

【数据库MySQL篇二】MySQL数据库入门基础教程:一网打尽数据库和表各种操作、命令和语法

一、MySQL创建数据库 使用Create命令创建数据库 我们可以在登陆 MySQL 服务后&#xff0c;使用 create 命令创建数据库&#xff0c;语法如下: CREATE DATABASE 数据库名; 以下命令简单的演示了创建数据库的过程&#xff0c;数据名为 RUNOOB: [roothost]# mysql -u root -p…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...

动态规划-1035.不相交的线-力扣(LeetCode)

一、题目解析 光看题目要求和例图&#xff0c;感觉这题好麻烦&#xff0c;直线不能相交啊&#xff0c;每个数字只属于一条连线啊等等&#xff0c;但我们结合题目所给的信息和例图的内容&#xff0c;这不就是最长公共子序列吗&#xff1f;&#xff0c;我们把最长公共子序列连线起…...

Android屏幕刷新率与FPS(Frames Per Second) 120hz

Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数&#xff0c;单位是赫兹&#xff08;Hz&#xff09;。 60Hz 屏幕&#xff1a;每秒刷新 60 次&#xff0c;每次刷新间隔约 16.67ms 90Hz 屏幕&#xff1a;每秒刷新 90 次&#xff0c;…...

生产管理系统开发:专业软件开发公司的实践与思考

生产管理系统开发的关键点 在当前制造业智能化升级的转型背景下&#xff0c;生产管理系统开发正逐步成为企业优化生产流程的重要技术手段。不同行业、不同规模的企业在推进生产管理数字化转型过程中&#xff0c;面临的挑战存在显著差异。本文结合具体实践案例&#xff0c;分析…...