redis限速器設計(不使用lua指令碼及事物),redislua

來源:互聯網
上載者:User

redis限速器設計(不使用lua指令碼及事物),redislua
公司有一個需求,需要叢集中的機器每分鐘發送固定個數請求到區域網路以外的一台伺服器,固定個數,是指叢集中的所有機器發送的所有的請求加起來是一個固定的個數,這就需要一個分布式的限速器。首先想到的就是使用redis中的incr方法,在redis的官方文檔中尋找到了一個樣本

FUNCTION LIMIT_API_CALL(ip)ts = CURRENT_UNIX_TIME()keyname = ip+":"+tscurrent = GET(keyname)IF current != NULL AND current > 10 THEN    ERROR "too many requests per second"ENDIF current == NULL THEN    MULTI        INCR(keyname, 1)        EXPIRE(keyname, 1)    EXECELSE    INCR(keyname, 1)ENDPERFORM_API_CALL()
但這個指令碼對我來說有兩個缺點1 我的限速器並不是限制一台機器的速度,而是限制整個叢集的速度,所以在判斷了限速的key的長度之後,會有很多的機器執行incr動作2 公司DBA不支援使用事物
看了文檔中後面限速器的實現,要麼使用事物,要麼使用lua指令碼(公司也不支援lua,因為lua也是事務性的,而公司是sharding的redis叢集),全部被否定
看來只能多檢測一會了程式流程圖,假設我們1s中之內只能請求20次



步驟1 使用incr命令得到一個值2 判斷值是否為1,為1則說明此次獲得是key值失效之後第一次進行incr操作,這次操作需要將key設定逾時時間。但是我們這裡並沒有使用事務支援,當程式運行到檢測value是1,還沒有進行expire操作的時候,機器down機了,那麼程式就只能請求20次了,所以在每次得到value值之後,與10進行取餘操作,若是10的倍數,則進行檢測,如果沒有設定逾時時間,則進行設定3 判斷value值是否是小於20,如果小於等於20,我們認為在規定的時間內,這個線程獲得了鎖,如果大於20,我們認為沒有獲得鎖,sleep一段時間後繼續請求鎖。
這樣,我們就實現了一個沒有使用事物,lua指令碼的限速器
如果此方案有什麼錯誤,或者有更加優雅的方案,還請各位多多指教。
注意流程圖中值為1和為10的倍數都需要檢測ttl key,這裡可以做個最佳化,只有10的倍數的值的進行ttl key 檢測操作,1的話直接expire key。








用lua 給redis 中塞值要怎設定有效時間

不存在現成的方法

如果要實現你說的功能
一般來說 還是按照正常的方法通過insert 或remove對錶進行值的增減
然後再額外的對錶進行一個監聽 當達到規定時間的時候,remove掉相關的值
 
易語言掛用的什指令碼,不像是lua

易語言現在大部分指令碼都是記憶體 CALL這種的。。。視圖的,按鍵的基本看不到咯

 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.