前言
說到秒殺業務的庫存扣減,就還是得先確認我們的扣減基本方案。
秒殺場景的庫存扣減方案
一般的做法是,先在Redis中做扣減,然后發送一個MQ消息,消費者在接到消息之后做數據庫中庫存的真正扣減及業務邏輯操作。
如何解決數據一致性問題:
Redis中庫存成功扣減了,但是后續發送MQ消息失敗,或者后面的消費過程中消息丟了或者失敗了等情況。
就會導致Redis中的庫存被扣減了,但是數據庫庫存沒扣減,業務的實際操作沒發生。這時候的結果就是Redis中發生了多扣,那么帶來的業務問題就是少賣。
對賬機制:
想要解決這類數據不一致的情況,就需要引入一些對賬的機制,做一些準實時的核對,處理這種數據不一致的情況。
常見的對賬方案有,用zset在redis中添加流水記錄,然后定時拉一段時間內的所有記錄,和數據庫比對,發現不一致,則進行補償處理。
一般在成熟的電商公司中,不管前面的方案做的多么完善,這個核對系統都是必不可少的。及時的核對出超賣、少賣等問題。
庫存扣減為什么不用分布式鎖
實現秒殺的庫存扣減,最重要的是兩個點:
- 抗更高的并發。
- 避免超賣
尤其重要的就是這個防止超賣,這也是我們加鎖的目的。
用lua腳本的優勢: - lua腳本具有原子性:可以直接用利用他的原子性特性,在一個腳本中實現庫存的檢查、扣減等動作,避免超賣!
- 效率高:所有操作可以在一次腳本執行中完成,減少了網絡傳輸時間和通信次數。
- 更加簡潔,易于維護:所有操作可以在一次腳本執行中完成并且使得應用層的代碼。
用分布式鎖的缺點:
如果用了 tryLock,不考慮 waitTime的合理性情況下,和 lua 腳本的執行也差不多,就是排隊執行。
- 效率低、增加系統復雜性:在不使用 lua 腳本的情況下,每次庫存扣減操作都需要多次與 Redis 服務器通信(例如,加鎖、讀取庫存、扣減庫存、釋放鎖等)。這不僅增加了網絡延時,還增加了系統的復雜性。
- 難管理:分布式鎖需要細致的管理,包括鎖的設置、維護鎖的存活時間、處理死鎖問題等。如果鎖沒有正確管理,可能會導致死鎖或者鎖失效,進而影響系統的穩定性和數據一致性。
總結
本片文章介紹了秒殺業務下的庫存扣減方案,以及扣減的具體方案,解釋了在扣減時為什么不用分布式鎖,而用LUA
腳本進行扣減的原因。希望這篇文章能夠幫到你。感謝各位老鐵一鍵三連。
ps: 買服務器返點;收徒中;面試全集在線文檔,需要請私信。