現在redis真的非常流行,曾經有朋友跟我吐槽招人好難,他本身是從大廠出來的,問得太細的幾乎沒人知道,問得太淺又不知道這個人的真實水平。我跟他說,沒事,一般問一下會寫JAVA會使用Redis,就能拉出來干活了,掌握了這兩個技能,一般都不會太差。
今天我們來談一談Redis的隊列的應用,如何2個小時,搭建一個數十萬并發的電商優惠券領券系統。這是一個真實的故事,當年我們還是一個非常小的創業電商團隊,有一天,老板過來說今天下午中國移動會在多個渠道推廣我們的App,具體的形式就是領優惠券。預計的QPS有好幾萬。
我們的優惠券是屬于一卡一碼型的,就是一張優惠券都有一個優惠碼,用戶可以用該優惠碼到我們的APP上面進行激活。用戶領券的時候,我們需要去數據庫里面拉一個還未被使用的優惠碼,如果撈到的二維碼被別人使用了,那么就需要重試,性能比較差。
看起來有兩個比較明確的優化方向,一是采用一定策略從數據庫里面撈數據,減少不同機器不同線程撈到同一個券碼的可能,避免沖突,二是在內存里面維護一個隊列,減少訪問數據庫的次數。
當時距離活動開始已經不到5個小時,按照上面的方向去優化,開發、測試、壓測的時間已經是非常緊張了,風險相當大。我們迫切需要一種更簡單的方案來解決。
這個時候,萬金油Redis又出馬了。Redis提供一種實用的數據結構,叫雙端隊列。在日常開發中,我們常常可以把它當成分布式隊列來用。Redis隊列提供lpush,lpop,rpush,rpop等基本的操作,可以從隊列中取出對應的元素。這里可能有人會問,需要加鎖么?會不會兩個進程取到同一個元素,并不會,因為Redis是單線程的,所以很安全。
在上述場景下,我們先把全量的優惠券券碼從數據庫里面加載到Redis里面,為了避免Redis的單點故障,我們可以分批放到2個實例,每次用戶調用領券接口的時候,先從Redis的隊列中取一個券碼出來,然后再Update到數據庫即可,如果擔心數據庫扛不住,可以先寫到Redis中。這個開發起來非常簡單,在原來的接口上面改改半個小時就能擼完代碼上線了。
今天的介紹我們就講到這里,有沒有學習到Redis新的姿勢呢,后面我們再繼續將Redis的一些命令與應用。如果你有興趣,歡迎關注我,主講算法相關的,近期還準備了一些AI相關的知識,整理后會和大家繼續分享。大家的支持是我繼續嘮嗑的動力。