国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Redis--Zset使用場景舉例(滑動窗口實現(xiàn)限流)

這篇具有很好參考價值的文章主要介紹了Redis--Zset使用場景舉例(滑動窗口實現(xiàn)限流)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

  • 在Redis–Zset的語法和使用場景舉例(朋友圈點贊,排行榜)一文中,提及了redis數(shù)據(jù)結(jié)構(gòu)zset的指令語法和一些使用場景,今天我們使用zset來實現(xiàn)滑動窗口限流,詳見下文。

什么是滑動窗口

  • 滑動窗口是一種流量控制策略,用于控制一定時間內(nèi)請求的訪問數(shù)量。

  • 其原理是:將時間劃分成規(guī)定的時間片段,每個片段有固定的時間間隔,如1s,1min,1h,然后定義一個時間窗口,比如5s,5min等,該窗口會隨著時間向右移動。此外還需要計數(shù)器計算窗口內(nèi)的請求數(shù)。當窗口移動時,會把已經(jīng)走過的時間片段的請求數(shù)刪掉。每當請求進入系統(tǒng)時,會檢查計數(shù)器中的請求數(shù)是否已經(jīng)滿了,如果計數(shù)未滿,則請求允許被執(zhí)行;否則執(zhí)行相應的拒絕方法。

    Redis--Zset使用場景舉例(滑動窗口實現(xiàn)限流),Redis,redis,數(shù)據(jù)庫

  • 滑動窗口在時間內(nèi)平滑地控制流量,而非簡單地固定請求數(shù)與速率,可以更加靈活地突發(fā)流量和峰值流量。

zset實現(xiàn)滑動窗口

  • 在redis中可以使用zset實現(xiàn)滑動窗口作為限流方案,假如接口A每一分鐘只能訪問100次,那么我們可以將這個需要限流的接口名作為key,value采用zset數(shù)據(jù)結(jié)構(gòu),zset的score設(shè)置為當前請求的時間戳,zset的member只需要保證唯一性即可。

  • 涉及到的zset指令

    向zset添加數(shù)據(jù):zadd key score member
    刪除zset某個score范圍內(nèi)的數(shù)據(jù): zremrangebyscore key min max
    統(tǒng)計zset中數(shù)據(jù)的數(shù)量:zcard key

  • 代碼實現(xiàn):在代碼中定義滑動窗口大小為"windowSize",收到請求后,在redis生成zset,用zremrangebyscore刪除score小于當前時間戳減去"windowSize"的數(shù)據(jù),使用zcard查詢當前zset中的數(shù)據(jù)量,即請求量判斷是否超出限制值,若超出則不加入zset。

    public class RedisRateLimiter {
        private Jedis jedis;
        private String key;
        //窗口大小
        private int windowsize;
        //限制訪問的請求數(shù)
        private Integer limitValue;
    
        public RedisRateLimiter(Jedis jedis, String key, int windowsize, Integer limitValue) {
            this.jedis = jedis;
            this.key = key;
            this.windowsize = windowsize;
            this.limitValue = limitValue;
        }
    
        public boolean allowVisit() {
            //獲取當前時間戳
            long nowTimeStamp = System.currentTimeMillis();
            //窗口開始時間為當前時間戳減去60s
            long windowStartTime = nowTimeStamp - windowsize * 1000;
            //刪除score小于窗口開始時間的數(shù)據(jù)
            jedis.zremrangeByScore(key, "-inf", String.valueOf(windowStartTime));
            if (jedis.zcard(key) < limitValue) {
                jedis.zadd(key, nowTimeStamp, String.valueOf(nowTimeStamp));
                return true;
            }
            //超過limieValue 返回false
            return false;
        }
    
        /**
         * 上面的方法可以改寫為使用lua腳本,以避免高并發(fā)情況下的原子性問題
         */
        public boolean allowVIsitUseLua() {
            //獲取當前時間戳
            long nowTimeStamp = System.currentTimeMillis();
            String luaScript = """
                        local window_start_time = ARGV[1] -ARGV[3]*1000
                        redis.call('ZREMRANGEBYSCORE',KEYS[1],'-inf',window_start_time)
                        local now_request = redis.call('ZCARD',KEYS[1])
                        if now_request < tonumber(ARGV[2]) then
                             redis.call('ZADD',KEYS[1],ARGV[1],ARGV[1])
                             return 1
                        else
                             return 0
                        end
                    """;
            Object result = jedis.eval(luaScript, 1, key, String.valueOf(nowTimeStamp), String.valueOf(limitValue), String.valueOf(windowsize));
            return (long) result == 1;
        }
    
        public static void main(String[] args) throws InterruptedException {
            Jedis jedis = new Jedis("127.0.0.1");
            String key = "interfaceA";
            jedis.del(key);
            RedisRateLimiter interfaceA = new RedisRateLimiter(jedis, key, 60, 10);
            //調(diào)用20次接口觀察結(jié)果
            for (int i = 0; i < 20; i++) {
                System.out.println("當前時間:"+ DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss:SSS").format(LocalDateTime.now())+
               "接口訪問情況: "+(interfaceA.allowVIsitUseLua()?"成功":"失敗"));
                Thread.sleep(1000);
            }
        }
    }
    
  • 測試結(jié)果:我們在mian方法中,調(diào)用20次接口A,設(shè)置滑動窗口為60秒內(nèi)只可以訪問10次,觀察接口A的訪問情況:
    Redis--Zset使用場景舉例(滑動窗口實現(xiàn)限流),Redis,redis,數(shù)據(jù)庫

  • 觀察運行結(jié)果,因為60秒內(nèi)該接口只能調(diào)用10次,所以調(diào)用20次接口A,只有前10次成功了,與我們的期望相同。到此我們通過zset實現(xiàn)了滑動窗口限流的功能。

小結(jié)

本文通過Redis的有序集合Zset實現(xiàn)了滑動窗口限流的功能。然而這個方案也存在著缺點,因為zset要記錄滑動窗口內(nèi)的所有接口記錄,當我們的要求是某接口在60秒內(nèi)只能訪問100萬次,那么我們就可能得存入100萬條記錄,這種情況下,采用這種方案會消耗很大的存儲空間,明顯不適用。文章來源地址http://www.zghlxwxcb.cn/news/detail-804360.html

附錄

  • 在window系統(tǒng)快速使用Redis服務(wù),只需要下載該壓縮包 redis壓縮包:redis.7z,解壓后,找到redis-server.exe即可啟動redis服務(wù)。

到了這里,關(guān)于Redis--Zset使用場景舉例(滑動窗口實現(xiàn)限流)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Redis--Geo指令的語法和使用場景舉例(附近的人功能)

    Redis--Geo指令的語法和使用場景舉例(附近的人功能)

    前言 Redis除了常見的五種數(shù)據(jù)類型之外,其實還有一些少見的數(shù)據(jù)結(jié)構(gòu),如Geo,HyperLogLog等。雖然它們少見,但是作用卻不容小覷。本文將介紹Geo指令的語法和使用場景。 Geo介紹 Geo是\\\"geolocation\\\"的縮寫,即地理定位器,顧名思義就是記錄地理位置信息,用來進行地址位置排序

    2024年01月20日
    瀏覽(35)
  • 使用Redis的zset集合實現(xiàn)小程序的滾動分頁

    使用Redis的zset集合實現(xiàn)小程序的滾動分頁

    將每個文檔的 score 值設(shè)置為時間戳(或根據(jù)其他規(guī)則計算的分數(shù)),將文檔的 ID 作為 value,然后將其添加到有序集合中。 獲取當前時間戳,作為查詢時間點。 使用 ZRANGEBYSCORE 命令根據(jù) score 值范圍查詢出 score 值在當前時間戳之前的所有文檔 ID。 返回查詢結(jié)果作為當前頁的結(jié)

    2024年02月03日
    瀏覽(17)
  • 微服務(wù)—Redis實用篇-黑馬頭條項目-達人探店功能(使用set與zset實現(xiàn))

    微服務(wù)—Redis實用篇-黑馬頭條項目-達人探店功能(使用set與zset實現(xiàn))

    1.1、達人探店-發(fā)布探店筆記 發(fā)布探店筆記 探店筆記類似點評網(wǎng)站的評價,往往是圖文結(jié)合。對應的表有兩個: tb_blog:探店筆記表,包含筆記中的標題、文字、圖片等 tb_blog_comments:其他用戶對探店筆記的評價 具體發(fā)布流程 上傳接口 注意:同學們在操作時,需要修改Syste

    2024年02月05日
    瀏覽(23)
  • 使用 redis 實現(xiàn)分布式接口限流注解 RedisLimit

    使用 redis 實現(xiàn)分布式接口限流注解 RedisLimit

    前言 很多時候,由于種種不可描述的原因,我們需要針對單個接口實現(xiàn)接口限流,防止訪問次數(shù)過于頻繁。這里就用 redis+aop 實現(xiàn)一個限流接口注解 @RedisLimit 代碼 點擊查看RedisLimit注解代碼 AOP代碼 點擊查看aop代碼 lua腳本代碼 注意:腳本代碼是放在 resources 文件下的,它的類型是

    2024年02月08日
    瀏覽(23)
  • [Redis] 數(shù)據(jù)結(jié)構(gòu)zset壓縮列表實現(xiàn)和跳表實現(xiàn)講解

    [Redis] 數(shù)據(jù)結(jié)構(gòu)zset壓縮列表實現(xiàn)和跳表實現(xiàn)講解

    ??一個不甘平凡的普通人,致力于為Golang社區(qū)和算法學習做出貢獻,期待您的關(guān)注和認可,陪您一起學習打卡?。。?????? ??專欄:算法學習 ??專欄:Go實戰(zhàn) ??個人主頁:個人主頁 跳表問題 redis 有五種數(shù)據(jù)結(jié)構(gòu):string,hash,list,set,zset 壓縮列表 或者 跳表 實現(xiàn) 壓縮

    2024年02月05日
    瀏覽(36)
  • 風控系統(tǒng)指標計算/特征提取分析與實現(xiàn)01,Redis、Zset、模版方法

    風控系統(tǒng)指標計算/特征提取分析與實現(xiàn)01,Redis、Zset、模版方法

    個人博客:無奈何楊(wnhyang) 個人語雀:wnhyang 共享語雀:在線知識共享 Github:wnhyang - Overview 引用 AI 對于風控系統(tǒng)的介紹 風控系統(tǒng)是一種用于在線業(yè)務(wù)的安全管理系統(tǒng),它幫助企業(yè)和平臺防范潛在的欺詐、信用風險以及不合規(guī)行為。簡單來說,它的核心作用就是“保安全

    2024年03月14日
    瀏覽(60)
  • 在Spring Boot微服務(wù)使用ZSetOperations操作Redis集群Zset(有序集合)

    記錄 :447 場景 :在Spring Boot微服務(wù)使用RedisTemplate的ZSetOperations操作Redis集群的Zset(有序集合)數(shù)據(jù)類型。 版本 :JDK 1.8,Spring?Boot 2.6.3,redis-6.2.5。 1.微服務(wù)中 配置Redis信息 1.1在pom.xml添加依賴 pom.xml文件: 解析:spring-boot-starter-data-redis和spring-boot版本保持一致。 1.2在application.ym

    2024年02月08日
    瀏覽(18)
  • lua腳本獲取table類型-Java使用lua腳本操作redis獲取zset元素的集合

    lua腳本獲取table類型-Java使用lua腳本操作redis獲取zset元素的集合 7.0點贊功能-定時持久化到數(shù)據(jù)庫-lua腳本的編寫_嗶哩嗶哩_bilibili https://www.bilibili.com/video/BV1bu411j75u 這個腳本主要是放到Springboot工程里的, 這里如果是向放到字段控制臺執(zhí)行,那就要加入 eval 以及其他參數(shù):

    2024年02月13日
    瀏覽(17)
  • sentinel---滑動窗口的實現(xiàn)原理

    sentinel---滑動窗口的實現(xiàn)原理

    sentinel有多種規(guī)則,包括:降級、限流、熱點等等規(guī)則,這些規(guī)則均會涉及到時間因素,既在單位時間內(nèi)的請求量滿足各種條件之后的各種動作。 這里我們一起來探針一下sentinel中滑動窗口的實現(xiàn) ?如上是一個滑動窗口的示意圖。 這里先不說sentinel中滑動窗口的實現(xiàn)代碼,咱

    2024年02月14日
    瀏覽(37)
  • redis+lua實現(xiàn)限流

    2024年02月07日
    瀏覽(16)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包