亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在泄漏桶算法中,當隊列未滿時,實現固定速率的正確邏輯是什么?

在泄漏桶算法中,當隊列未滿時,實現固定速率的正確邏輯是什么?

Go
Cats萌萌 2022-09-26 20:21:57
我正在學習泄漏的桶算法,并希望通過編寫一些帶有redis和golang http的簡單代碼來弄臟我的手。當我在這里搜索關鍵字redis,泄漏,桶。[1]中有許多類似的問題,這很好。然而,我發現在瀏覽了這些線程和wiki之后,我有一個問題來理解整個邏輯[2]。我想有些東西我不明白,也沒有意識到這一點。因此,我想在這里再次改寫它。如果我弄錯了,請糾正我。偽代碼:key := "ip address, token or anything that can be the representative of a client"redis_queue_size := 5interval_between_each_request := 7request := obtain_http_request_from_somewhere()if check_current_queue_size() < redis_queue_size:    if is_queue_empty()        add_request_to_the_queue() // zadd "ip1" now() now() // now() is something like seconds, milliseconds or nanoseconds e.g. t = 1        process_request(request)    else        now := get_current_time()        // add_request_to_... retrieves the first element in the queue        // compute the expected timestamp to execute the request and its current time        // e.g. zadd "ip1" <time of the first elment in the queue + interval_between_each_request> now        add_request_to_redis_queue_with_timestamp(now, interval_between_each_request) // e.g. zadd "ip" <timestamp as score> <timestamp a request is allowed to be executed>        // Below function check_the_time_left...() will check how many time left at which the current request need to wait.         // For instance, the first request stored in the queue with the command        //    zadd "ip1" 1 1  // t = 1        // and the second request arrives at t = 4 but it is allowed t be executed at t = 8        //    zadd "ip1" 8 4 // where 4 := now, 8 := 1 + interval_between_each_request        // so the N will be 4         N := check_the_time_left_for_the_current_request_to_execute(now, interval_between_each_request)         sleep(N) // now the request wait for 4 seconds before processing the request        process_request(http_request_obj)else    return // discard request我了解隊列已滿的部分,然后以下請求將被丟棄。但是,我想我可能會誤解當隊列未滿時,如何重塑傳入的請求,以便它可以以固定的速率執行。
查看完整描述

2 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

  1. 如果這是為了簡單的速率限制,那么使用排序集的滑動窗口方法是我們看到的大多數Redis用戶實現的,https://github.com/Redislabs-Solution-Architects/RateLimitingExample/blob/sliding_window/app.py

  2. 如果您設置在泄漏的存儲桶上,則可以考慮使用每個消費者ID(api令牌/ IP地址等)的redis流,如下所示

請求進入消費者 ID

XADD 請求-[消費者 ID] MAXLEN [存儲桶大小]

生成一個 go 例程(如果該使用者 ID 需要),如果請求的 XLEN ([使用者 ID] 為 0,則獲取當前時間

XREAD 計數 [number_of_requests_per_period] 塊 [時間段 - 1 毫秒] 流請求 -[使用者 ID] 獲取當前時間并在剩余時間段內休眠

https://redis.io/commands#stream 詳細介紹了流的工作原理


查看完整回答
反對 回復 2022-09-26
?
森欄

TA貢獻1810條經驗 獲得超5個贊

有幾種方法可以實現泄漏的存儲桶,但該過程應該有兩個單獨的部分。一個將內容放入存儲桶中,另一個在有要刪除的內容時按設定的時間間隔刪除它們。

您可以使用單獨的 goroutine,該 goroutine 將按設定的時間間隔使用消息。這將簡化您的代碼,因為在一個代碼路徑上,您只需要查看隊列大小并丟棄數據包,而另一個代碼路徑將僅使用任何存在的內容。


查看完整回答
反對 回復 2022-09-26
  • 2 回答
  • 0 關注
  • 83 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號