最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis限流算法解析與實(shí)戰(zhàn)教程

 更新時(shí)間:2026年04月15日 10:03:15   作者:濤聲依舊-底層原理研究所  
文章對(duì)比了多種限流算法(如固定窗口、滑動(dòng)窗口、令牌桶、漏桶,并詳細(xì)介紹了RedisCell的使用方式和使用建議,在工程優(yōu)化方面,文章提供了多個(gè)建議,如使用清理、保持一致性、增強(qiáng)可觀測(cè)性等等等,同時(shí)也給出了一些實(shí)戰(zhàn)場(chǎng)景和限流策略的黃金法則

一、經(jīng)典限流算法的深度對(duì)比與選型建議

算法核心思想適用場(chǎng)景推薦使用場(chǎng)景
固定窗口時(shí)間分段統(tǒng)計(jì),每段獨(dú)立計(jì)數(shù)對(duì)性能要求極高、允許短時(shí)突增的簡(jiǎn)單限流日志上報(bào)、非核心接口限流
滑動(dòng)窗口連續(xù)時(shí)間區(qū)間內(nèi)動(dòng)態(tài)統(tǒng)計(jì)請(qǐng)求需要平滑流量控制、避免“窗口邊界突增”問(wèn)題用戶行為監(jiān)控、支付/下單類高敏感接口
令牌桶以恒定速率生成令牌,請(qǐng)求消耗令牌支持突發(fā)流量、靈活控制峰值API 網(wǎng)關(guān)、微服務(wù)入口、消息推送
漏桶請(qǐng)求進(jìn)入后按固定速率輸出,超出則排隊(duì)或丟棄下游系統(tǒng)處理能力有限,需絕對(duì)平滑數(shù)據(jù)庫(kù)寫入、文件上傳、第三方調(diào)用

關(guān)鍵差異總結(jié)

維度固定窗口滑動(dòng)窗口令牌桶漏桶
是否允許突發(fā)? 否? 是(部分)? 完全支持?? 可容忍但延遲增加
流量平滑性差(邊界突增)極好中等(有突發(fā))最好
內(nèi)存占用極低(單個(gè) key)高(Zset 存 timestamp)中等(Hash)高(List 隊(duì)列長(zhǎng)度不確定)
實(shí)現(xiàn)復(fù)雜度高(需 Lua 腳本)中(需定時(shí)任務(wù)/異步消費(fèi))
原子性要求一般高(范圍查詢+更新)極高(讀-算-寫閉環(huán))高(隊(duì)列操作)

選型建議:

  • 若追求極致性能且可接受“59秒+1秒”突發(fā) → 用 固定窗口;
  • 若業(yè)務(wù)對(duì)流量平滑性要求嚴(yán)格,如防止刷 單、搶購(gòu) → 用 滑動(dòng)窗口令牌桶;
  • 若希望在突發(fā)情況下仍能放行一定數(shù)量請(qǐng)求,同時(shí)長(zhǎng)期速率受控 → 優(yōu)先選擇 令牌桶;
  • 若下游是數(shù)據(jù)庫(kù)/文件系統(tǒng)等慢速資源,必須保證輸入速率穩(wěn)定 → 選 漏桶

二、RedisCell 模塊詳解:官方推薦的“開箱即用”限流利器

為什么推薦使用 RedisCell?

特性說(shuō)明
? 原生支持4.0+ 版本內(nèi)置模塊,無(wú)需額外依賴
? 高性能使用 C 編寫,減少網(wǎng)絡(luò)往返和解釋成本
? 原子性保障CL.THROTTLE 是原子命令,無(wú)需手動(dòng)封裝 Lua
? 突發(fā)容忍支持 max_burst,允許短時(shí)間內(nèi)批量通過(guò)
? 返回信息豐富返回 [status, remaining_tokens, delay],便于前端/中間件決策

命令詳解(結(jié)合實(shí)例)

# 示例:用戶 user123 每分鐘最多 15 次請(qǐng)求,突發(fā)容量 15,正常速率 1次/秒
CL.THROTTLE user123 15 60 1

返回值解析:

[1, 14, 0]   # 允許,剩余令牌 14,無(wú)需等待
[0, 15, 2]   # 拒絕,剩余令牌 15,需等待 2 秒后再試
  • 1: 允許請(qǐng)求
  • 0: 拒絕請(qǐng)求
  • remaining_tokens: 當(dāng)前可用令牌數(shù)(可用于降級(jí)提示)
  • delay: 如果拒絕,建議等待多少秒再嘗試(單位:秒)

注意:CL.THROTTLEperiod 是以秒為單位,但內(nèi)部是以毫秒精度計(jì)算的,因此即使周期較短(如 1 秒),也能做到精確控制。

如何啟用 RedisCell?

確保 Redis 版本 ≥ 4.0;

修改 redis.conf 啟用模塊:

loadmodule /path/to/redis-cell.so

通常安裝 Redis 時(shí)會(huì)自帶該模塊(路徑可能為 /usr/lib/redis/modules/redis-cell.so);

啟動(dòng)后可通過(guò) MODULE LIST 查看是否加載成功。

使用建議:

  • 不要濫用 max_burst:雖然它提升了用戶體驗(yàn),但可能導(dǎo)致下游瞬間壓力激增。
  • 配合熔斷機(jī)制使用:當(dāng) delay 大于閾值(如 >3 秒),應(yīng)觸發(fā)熔斷或降級(jí)策略。
  • 日志埋點(diǎn):記錄被限流的請(qǐng)求,用于分析異常流量來(lái)源。

三、工程優(yōu)化與避坑指南(進(jìn)階篇)

1.原子性:必須用 Lua 腳本!

? 錯(cuò)誤做法(易出并發(fā)問(wèn)題):

GET counter
IF count > limit: RETURN reject
INCR counter

→ 存在“競(jìng)態(tài)條件”,多個(gè)請(qǐng)求可能同時(shí)讀到 count=14,導(dǎo)致超限。

? 正確做法(使用 Lua 腳本):

-- 令牌桶邏輯(簡(jiǎn)化版)
local key = KEYS[1]
local capacity = tonumber(ARGV[1])
local rate = tonumber(ARGV[2]) -- 令牌生成速度(個(gè)/秒)
local now = tonumber(ARGV[3])

local bucket = redis.call('HMGET', key, 'last_time', 'tokens')
local last_time = tonumber(bucket[1]) or 0
local tokens = tonumber(bucket[2]) or capacity

local delta = math.max(0, now - last_time)
local add_tokens = delta * rate
tokens = math.min(capacity, tokens + add_tokens)

if tokens >= 1 then
    tokens = tokens - 1
    redis.call('HMSET', key, 'last_time', now, 'tokens', tokens)
    return 1
else
    return 0
end

使用方式:

EVAL "lua_script" 1 user123 10 1 1700000000

優(yōu)勢(shì):所有操作在一個(gè)事務(wù)中完成,無(wú)中間狀態(tài)暴露。

2.內(nèi)存治理:防止“數(shù)據(jù)堆積”

常見(jiàn)陷阱:

  • 滑動(dòng)窗口使用 Zset:若不清理過(guò)期數(shù)據(jù),會(huì)導(dǎo)致內(nèi)存持續(xù)增長(zhǎng);
  • 令牌桶使用 Hash:若用戶過(guò)多,且未設(shè)置合理過(guò)期時(shí)間,也會(huì)造成內(nèi)存泄漏;
  • 漏桶使用 List:如果消費(fèi)者處理慢,隊(duì)列無(wú)限增長(zhǎng)。

解決方案:

結(jié)構(gòu)清理策略
滑動(dòng)窗口(Zset)定期執(zhí)行 ZREMRANGEBYSCORE key -inf <now - window_size;
或利用 EXPIRE 設(shè)置自動(dòng)過(guò)期(注意:只對(duì) key 有效,不能清除舊元素)
令牌桶(Hash)給每個(gè) key 設(shè)置合理的過(guò)期時(shí)間(如 1 小時(shí)),或使用 LRU 策略淘汰不活躍用戶
漏桶(List)消費(fèi)端通過(guò)定時(shí)任務(wù)定期清理空桶或超時(shí)桶;也可設(shè)置最大長(zhǎng)度,超過(guò)則丟棄新請(qǐng)求

最佳實(shí)踐

# 滑動(dòng)窗口:每分鐘清理一次過(guò)期時(shí)間戳
SCHEDULED JOB:
    ZREMRANGEBYSCORE window_key -inf < (now - 60)

 強(qiáng)烈建議:將限流數(shù)據(jù)的 TTL 控制在合理范圍內(nèi)(如 1~2 小時(shí)),避免內(nèi)存爆炸。

3.分布式環(huán)境下的限流一致性

問(wèn)題:多個(gè)服務(wù)節(jié)點(diǎn)共享同一份 Redis,但各自緩存本地計(jì)數(shù) → 不一致!

? 解決方案:

方案說(shuō)明
? 所有計(jì)數(shù)統(tǒng)一由 Redis 統(tǒng)一維護(hù)所有請(qǐng)求都走 Redis,避免本地緩存干擾
? 使用 Redis Cluster 保證數(shù)據(jù)分布一致性確保 key 落在同一個(gè) shard,避免跨節(jié)點(diǎn)同步延遲
? 限流 key 命名規(guī)范統(tǒng)一如 rate_limit:user:123, rate_limit:api:/order/create

切忌:在本地內(nèi)存做限流計(jì)數(shù),除非配合 Redis 作為主源同步。

4.限流策略的可觀測(cè)性 & 監(jiān)控

限流不是“黑盒”,必須具備可觀測(cè)性:

必須采集的關(guān)鍵指標(biāo):

指標(biāo)用途
request_count_per_second整體流量趨勢(shì)
throttle_rate被限流比例(= 被拒請(qǐng)求數(shù) / 總請(qǐng)求數(shù))
average_delay拒絕后平均等待時(shí)間
burst_hit_ratio突發(fā)請(qǐng)求占比
top_blocked_keys哪些接口/用戶最常被限流

推薦監(jiān)控方式:

  • 將限流返回結(jié)果寫入日志(如 OpenTelemetry Trace);
  • 使用 Prometheus + Grafana 可視化限流率;
  • 在網(wǎng)關(guān)層集成限流統(tǒng)計(jì)器,發(fā)送至 Metrics Server。

四、實(shí)戰(zhàn)場(chǎng)景推薦組合

場(chǎng)景推薦算法實(shí)現(xiàn)方式
微服務(wù)入口限流(如網(wǎng)關(guān))令牌桶RedisCell + CL.THROTTLE
搶購(gòu)活動(dòng)防刷滑動(dòng)窗口ZREVRANGEBYSCORE + Lua 腳本
第三方服務(wù)調(diào)用保護(hù)漏桶List + BRPOP + 定時(shí)任務(wù)消費(fèi)
用戶行為分析(防爬蟲)固定窗口SETNX + EXPIRE
高頻日志上報(bào)令牌桶自定義腳本,支持突發(fā)容忍

五、總結(jié):構(gòu)建健壯限流系統(tǒng)的黃金法則

法則說(shuō)明
?? 原子性第一任何涉及“查-判-改”的操作,必須用 Lua 腳本
?? 內(nèi)存要可控定期清理過(guò)期數(shù)據(jù),合理設(shè)置 TTL
?? 一致性優(yōu)先分布式下統(tǒng)一依賴 Redis,禁止本地緩存
?? 可觀測(cè)性強(qiáng)限流行為必須可監(jiān)控、可告警、可回溯
??? 善用官方工具優(yōu)先使用 RedisCell,降低出錯(cuò)概率
?? 按需選型不是越復(fù)雜越好,根據(jù)業(yè)務(wù)特性選擇最適合的算法

附錄:常用限流命令速查表

功能命令
固定窗口計(jì)數(shù)SET key value NX EX seconds
滑動(dòng)窗口統(tǒng)計(jì)ZREVRANGEBYSCORE key -inf <timestamp
令牌桶判斷EVAL "lua_script"
RedisCell 限流CL.THROTTLE key max_burst count period
刪除過(guò)期數(shù)據(jù)ZREMRANGEBYSCORE key -inf <now - window

最終建議:

在生產(chǎn)環(huán)境中,優(yōu)先使用 RedisCell,除非有特殊定制需求;

對(duì)于復(fù)雜場(chǎng)景,基于 Lua 腳本實(shí)現(xiàn)令牌桶/滑動(dòng)窗口,并加入監(jiān)控與自動(dòng)化清理機(jī)制;

所有策略都應(yīng)可配置、可觀察、可降級(jí)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Redis通過(guò)scan查找不過(guò)期的 key(方法詳解)

    Redis通過(guò)scan查找不過(guò)期的 key(方法詳解)

    SCAN 命令是一個(gè)基于游標(biāo)的迭代器,每次被調(diào)用之后, 都會(huì)向用戶返回一個(gè)新的游標(biāo), 用戶在下次迭代時(shí)需要使用這個(gè)新游標(biāo)作為 SCAN 命令的游標(biāo)參數(shù), 以此來(lái)延續(xù)之前的迭代過(guò)程,對(duì)Redis scan 查找 key相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-08-08
  • Redis三種常用的緩存讀寫策略步驟詳解

    Redis三種常用的緩存讀寫策略步驟詳解

    Redis有三種讀寫策略分別是:旁路緩存模式策略、讀寫穿透策略、異步緩存寫入策略,接下來(lái)通過(guò)本文給大家詳細(xì)介紹下Redis三種常用的緩存讀寫策略,感興趣的朋友一起看看吧
    2022-05-05
  • Redis 事務(wù)知識(shí)點(diǎn)相關(guān)總結(jié)

    Redis 事務(wù)知識(shí)點(diǎn)相關(guān)總結(jié)

    這篇文章主要介紹了Redis 事務(wù)相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Redis,感興趣的朋友可以了解下
    2021-03-03
  • redis中刪除操作命令

    redis中刪除操作命令

    這篇文章主要介紹了redis中刪除操作命令,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Redis 旁路緩存深度解析

    Redis 旁路緩存深度解析

    旁路緩存是 Redis 最常用的緩存策略,本文主要介紹了Redis旁路緩存深度解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-04-04
  • Redis中的數(shù)據(jù)一致性問(wèn)題以及解決方案

    Redis中的數(shù)據(jù)一致性問(wèn)題以及解決方案

    這篇文章主要介紹了Redis中的數(shù)據(jù)一致性問(wèn)題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Redis結(jié)合 Docker 搭建集群并整合SpringBoot的詳細(xì)過(guò)程

    Redis結(jié)合 Docker 搭建集群并整合SpringBoot的詳細(xì)過(guò)程

    這篇文章主要介紹了Redis結(jié)合Docker搭建集群并整合SpringBoot的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Redis服務(wù)之高可用組件sentinel詳解

    Redis服務(wù)之高可用組件sentinel詳解

    這篇文章主要介紹了Redis服務(wù)之高可用組件sentinel,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Redis主從架構(gòu)和高可用性實(shí)現(xiàn)過(guò)程

    Redis主從架構(gòu)和高可用性實(shí)現(xiàn)過(guò)程

    本文詳細(xì)介紹了使用Redis主從架構(gòu)和Linux虛擬服務(wù)器(LVS)實(shí)現(xiàn)高可用性的方法,并回顧了最近完成的Redis集群遷移部署過(guò)程,主從架構(gòu)通過(guò)復(fù)制數(shù)據(jù)來(lái)提高性能和數(shù)據(jù)冗余,而LVS用于實(shí)現(xiàn)負(fù)載均衡和故障切換,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • Redis實(shí)現(xiàn)IP限流的2種方式舉例詳解

    Redis實(shí)現(xiàn)IP限流的2種方式舉例詳解

    通俗的說(shuō)限流就是限制一段時(shí)間內(nèi)用戶訪問(wèn)資源的次數(shù),減輕服務(wù)器壓力,這篇文章主要給大家介紹了關(guān)于Redis實(shí)現(xiàn)IP限流的2種方式,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08

最新評(píng)論

临猗县| 永嘉县| 汝南县| 中宁县| 同仁县| 晴隆县| 灌云县| 方正县| 和田县| 东台市| 治多县| 岳阳县| 原平市| 金山区| 澄迈县| 泸州市| 二连浩特市| 普宁市| 张家川| 海晏县| 景洪市| 中方县| 兴海县| 盘山县| 额敏县| 延安市| 绥阳县| 中山市| 普兰店市| 信宜市| 海盐县| 文安县| 搜索| 遂平县| 依安县| 马龙县| 阳东县| 松江区| 华安县| 玉溪市| 黑水县|