使用Redis Lua脚本实现高级限流策略

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 使用Redis Lua脚本实现高级限流策略

引言

在现代的Web应用中,限流是一个非常重要的功能,它帮助我们控制对某些资源的访问频率,以防止系统过载和滥用。Redis是一个高性能的键值存储系统,它的原子操作和Lua脚本功能为实现复杂的限流策略提供了强大的支持。本文将详细介绍一个使用Redis Lua脚本实现的高级限流策略。

理解限流Lua脚本

Lua脚本是Redis中一种强大的功能,它可以在服务器端执行复杂的逻辑,而无需在客户端进行多次调用。这对于实现限流逻辑来说是非常有用的,因为它可以保证限流操作的原子性。

下面是一个用于限流的Lua脚本示例:

-- 获取KEY
local limitResourceKey = KEYS[1]
-- 限流时间窗口(毫秒)
local limitTimeWindowMillis = tonumber(ARGV[1])
-- 当前时间(毫秒)
local currentMillis = tonumber(ARGV[2])
-- 最大次数
local limitCount = tonumber(ARGV[3])

-- 窗口开始时间
local windowStartMs = currentMillis - limitTimeWindowMillis
-- 获取key的次数
local current = redis.call('zcount', limitResourceKey, windowStartMs, currentMillis)

-- 如果key的次数存在且大于预设值直接返回false
if current and tonumber(current) >= limitCount then
    return false
end

-- 清除所有过期成员
redis.call("ZREMRANGEBYSCORE", limitResourceKey, 0, windowStartMs)

-- 添加当前成员
math.randomseed(currentMillis)
local uniqueId = tostring(currentMillis) .. tostring(math.random(1000, 9999))
redis.call("zadd", limitResourceKey, currentMillis, uniqueId)
redis.call("expire", limitResourceKey, limitTimeWindowMillis / 1000)

-- 返回true表示操作成功,没有超出限流
return true


脚本解析

1. 获取参数

脚本首先获取三个参数:限流的键(limitResourceKey)、时间窗口大小

limitTimeWindowMillis)和当前时间(currentMillis)。此外,还有一个最大请求次数的参数(limitCount)。

2. 计算窗口开始时间

使用当前时间和时间窗口大小计算出窗口的开始时间(windowStartMs),这个时间用于确定计数的起始点。

3. 计数

使用zcount命令来获取在当前时间窗口内已经记录的请求次数。zcount是一个有序集合的命令,它可以用来获取指定分数区间的成员数量。

4. 检查是否超出限流

如果当前的请求次数加上即将到来的请求已经超过了设定的最大次数,则直接返回false,表示请求被限流。


5. 清除过期成员

使用ZREMRANGEBYSCORE命令来清除时间窗口之外的过期请求记录,确保有序集合中只包含当前时间窗口内的请求记录。

6. 添加当前请求

使用zadd命令添加当前请求的记录,同时使用math.random生成一个随机数来确保成员的唯一性。然后设置这个键的过期时间,以便自动清理。

7. 返回结果

如果脚本执行到这里,说明请求没有超出限流,返回true

使用场景

这个Lua脚本可以在多种场景中使用,例如API的限流、秒杀系统的请求控制等。通过将这个脚本集成到你的应用程序中,你可以有效地控制对关键资源的访问频率。

结语

通过使用Redis的Lua脚本功能,我们可以高效且安全地实现复杂的限流逻辑。这种方法不仅减少了网络延迟,还保证了限流操作的原子性,从而提高了系统的稳定性和可靠性。希望本文能够帮助你更好地理解和应用Redis Lua脚本来实现限流策略。


相关文章
|
13天前
|
存储 缓存 NoSQL
工作 10 年!Redis 内存淘汰策略 LRU 和传统 LRU 差异,还傻傻分不清
小富带你深入解析Redis内存淘汰机制:LRU与LFU算法原理、实现方式及核心区别。揭秘Redis为何采用“近似LRU”,LFU如何解决频率老化问题,并结合实际场景教你如何选择合适策略,提升缓存命中率。
154 3
|
2月前
|
存储 缓存 人工智能
Redis六大常见命令详解:从set/get到过期策略的全方位解析
本文将通过结构化学习路径,帮助读者实现从命令语法掌握到工程化实践落地的能力跃迁,系统性提升 Redis 技术栈的应用水平。
|
2月前
|
存储 NoSQL 算法
应对Redis中的并发冲突:有效解决策略
以上策略各有优劣:乐观锁和悲观锁控制得当时可以很好地解决并发问题;发布/订阅模式提高了实时响应能力;Lua脚本和Redis事务保证了命令序列的原子性;分布式锁适合跨节点的并发控制;限流措施和持久化配置从系统设计层面减少并发风险;数据分片通过架构上的优化减轻单个Redis节点的负担。正确选择适合自己应用场景的策略,是解决Redis并发冲突的关键。
215 0
|
4月前
|
存储 监控 NoSQL
流量洪峰应对术:Redis持久化策略与内存压测避坑指南
本文深入解析Redis持久化策略与内存优化技巧,涵盖RDB快照机制、AOF重写原理及混合持久化实践。通过实测数据揭示bgsave内存翻倍风险、Hash结构内存节省方案,并提供高并发场景下的主从复制冲突解决策略。结合压测工具链构建与故障恢复演练,总结出生产环境最佳实践清单。
121 9
|
4月前
|
缓存 NoSQL 算法
高并发秒杀系统实战(Redis+Lua分布式锁防超卖与库存扣减优化)
秒杀系统面临瞬时高并发、资源竞争和数据一致性挑战。传统方案如数据库锁或应用层锁存在性能瓶颈或分布式问题,而基于Redis的分布式锁与Lua脚本原子操作成为高效解决方案。通过Redis的`SETNX`实现分布式锁,结合Lua脚本完成库存扣减,确保操作原子性并大幅提升性能(QPS从120提升至8,200)。此外,分段库存策略、多级限流及服务降级机制进一步优化系统稳定性。最佳实践包括分层防控、黄金扣减法则与容灾设计,强调根据业务特性灵活组合技术手段以应对高并发场景。
1068 7
|
4月前
|
消息中间件 监控 NoSQL
利用RabbitMQ与Redis实现消息的延迟传递的策略
这个系统就如同一个无懈可击的邮局,无论天气如何变换,它都能确保每一封信准时送达。通过巧妙地运用RabbitMQ的DLX和Redis的Sorted Sets,我们搭建了一座桥梁,让即时和延迟消息的传递高效且无缝对接。
60 3
|
8月前
|
缓存 NoSQL 搜索推荐
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
本文介绍了如何通过Lua脚本在Redis中实现分布式锁的原子性操作,避免并发问题。首先讲解了Lua脚本的基本概念及其在Redis中的使用方法,包括通过`eval`指令执行Lua脚本和通过`script load`指令缓存脚本。接着详细展示了如何用Lua脚本实现加锁、解锁及可重入锁的功能,确保同一线程可以多次获取锁而不发生死锁。最后,通过代码示例演示了如何在实际业务中调用这些Lua脚本,确保锁操作的原子性和安全性。
418 6
【📕分布式锁通关指南 03】通过Lua脚本保证redis操作的原子性
|
7月前
|
缓存 NoSQL 测试技术
Redis压测脚本及持久化机制
Redis压测脚本及持久化机制简介: Redis性能压测通过`redis-benchmark`工具进行,可评估读写性能。持久化机制包括无持久化、RDB(定期快照)和AOF(操作日志),以及两者的结合。RDB适合快速备份与恢复,但可能丢失数据;AOF更安全,记录每次写操作,适合高数据安全性需求。两者结合能兼顾性能与安全性,建议同时开启并定期备份RDB文件以确保数据安全。
142 9
|
7月前
|
NoSQL Redis
Redis的数据淘汰策略有哪些 ?
Redis 提供 8 种数据淘汰策略: 淘汰易失数据(具有过期时间的数据) 1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰 2. volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰 3. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰 4. volatile-random:从已设置过期
|
7月前
|
NoSQL Redis
Redis的数据持久化策略有哪些 ?
Redis 提供了两种方式,实现数据的持久化到硬盘。 1. RDB 持久化(全量),是指在指定的时间间隔内将内存中的数据集快照写入磁盘。 2. AOF持久化(增量),以日志的形式记录服务器所处理的每一个写、删除操作 RDB和AOF一起使用, 在Redis4.0版本支持混合持久化方式 ( 设置 aof-use-rdb-preamble yes )