秒殺和限流 redis

2021-10-03 07:00:17 字數 2554 閱讀 5887

redis是單執行緒的,所以在redis中所有命令都是原子操作。而當要多條redis命令同時執行而不被打斷時,則需要使用redis的事務了。

商品放到redis上面,每一次都在redis裡面執行操作,操作之前先watch(key), watch的作用就是檢測這個key,如果這key的事務被修改則不會執行,監控一直持續到exec命令,在這兩個命令之間還有乙個命令multi 在這個命令之後對redis進行更改(事務中的命令是在exec之後才執行的,所以在multi命令後可以修改watch監控的鍵值)

multi命令

用於開啟乙個事務,它總是返回ok。multi執行之後,客戶端可以繼續向伺服器傳送任意多條命令, 這些命令不會立即被執行,而是被放到乙個佇列中,當 exec命令被呼叫時, 所有佇列中的命令才會被執行。

exec命令

負責觸發並執行事務中的所有命令:

如果客戶端成功開啟事務後執行exec,那麼事務中的所有命令都會被執行。

如果客戶端在使用multi開啟了事務後,卻因為斷線而沒有成功執行exec,那麼事務中的所有命令都不會被執行。

需要特別注意的是:即使事務中有某條/某些命令執行失敗了,事務佇列中的其他命令仍然會繼續執行——redis不會停止執行事務中的命令,而不會像我們通常使用的關係型資料庫一樣進行回滾。

discard命令

當執行 discard 命令時, 事務會被放棄, 事務佇列會被清空,並且客戶端會從事務狀態中退出。

watch 命令

可以為redis事務提供 check-and-set (cas)行為。被watch的鍵會被監視,並會發覺這些鍵是否被改動過了。 如果有至少乙個被監視的鍵在 exec 執行之前被修改了, 那麼整個事務都會被取消, exec 返回nil-reply來表示事務已經失敗。

基於jedis

jedis.watch(productkey);//保證一致性

transaction tx = jedis.multi();//開啟事務

tx.incrby(productkey, -1);//扣減庫存

listlist = tx.exec();//執行事務

mq.send(order);//發出訂單

基於redisson
rsemaphore semaphore = redissonclient.getsemaphore("sec_kill" + skuid + "");

boolean b = semaphore.tryacquire();

//setnxex(user) //控制頻率,規定時間內只能秒乙個

1.伺服器容量(伺服器能夠允許最大的連線數) -> 容量的限制只需要進行乙個session的監聽,達到了最大值之後就返回乙個通知頁面

2.伺服器流量 -> 限流就是對伺服器流量的限制 伺服器的吞吐能力,一般是指伺服器在單位時間內能夠處理的請求的數量

按秒,計算伺服器每秒的請求數量是否達到最大值(max個請求).如果超過該值,則拒絕請求->但是這樣的999ms–>1ms之間伺服器很有可能會處理到兩倍的請求,所以伺服器在這個時候會出錯,所以我們不能用時間來進行判斷

桶就一直是在接受請求,桶的眼就是伺服器處理請求,桶下面的眼多大取決於伺服器的處理能力,

long timestamp = getnowtime(); 

int capacity = 10000;// 桶的容量,即最大承載值

int rate = 1;//水漏出的速度,即伺服器的處理請求的能力

int water = 100;//當前水量,即當前的即時請求壓力

//當前請求執行緒進入漏桶方法,true則不被拒絕,false則說明當前伺服器負載水量不足,則被拒絕

令牌桶演算法的原理是系統會以乙個恆定的速度往桶裡放入令牌,而如果請求需要被處理,則需要先從桶裡獲取乙個令牌,當桶裡沒有令牌可取時,則拒絕服務。

int capacity; // 桶的容量

int rate ;//令牌放入速度

int tokens;//當前水量

借助Redis做秒殺和限流的思考

最近群裡聊起秒殺和限流,我自己沒有做過類似應用,但是工作中遇到過更大的資料和併發。於是提出了乙個簡單的模型 var count rds.inc key if count 1000 throw 已搶光!借助redis單執行緒模型,它的inc是安全的,確保每次加一,然後返回加一後的結果。如果原來是234...

Redis 簡單限流

首先我們來看乙個常見 的簡單的限流策略。系統要限定使用者的某個行為在指定的時間裡只能允許發生 n 次,如何使用 redis 的資料結構來實現這個限流的功能?這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要...

redis簡單限流

需求 如果要保證乙個使用者一分鐘內只能訪問5次介面,超過就拒絕範圍。這個限流需求中存在乙個滑動時間視窗,想想 zset 資料結構的 score 值,是不是可以通過 score 來圈出這個時間視窗來。而且我們只需要保留這個時間視窗,視窗之外的資料都可以砍掉。那這個 zset 的 value 填什麼比較...