讀庫存扣減系列文章有感

微信公衆號架構師之路最近發了一篇關於庫存扣減文章引發了你們的普遍轉發,做爲一個小菜鳥,也發表點本身的菜鳥想法吧redis

 

這篇文章原文是庫存扣多了,到底怎麼整 ,後面還有一篇對網友回覆的解答庫存扣減還有這麼多方案?微信

 

第一篇文章中着重描述了扣減庫存的併發問題如何解決,如何保證冪等。架構

 

文章首先解決的是如何作到冪等,由於「扣減」庫存必定是一個非冪等的操做,那麼能夠經過「設置」庫存來解決,由於設置庫存是一個冪等操做。併發

第二個解決的是冪等以後的併發問題,由於「設置」庫存雖然作到了冪等可是並無解決併發時帶來的一致性問題,當兩個用戶同時「設置」庫存是會形成數據的不一致。異步

緊接着就引出了CSA(「Compare And Set」),CSA本質上就是一種樂觀鎖方式---先比較再設置。每次扣減庫存時都作比較,若是「當前庫存」總數和「原庫存」總數一致時才執行「扣減」,不然「扣減執行失敗」,那麼失敗後只有兩種辦法,要麼事務回滾,要麼自動重試,若是重試後發現扣減後總數小於0那麼就須要返回給用戶錯誤了。分佈式

 

這兩個思路很是的nice,分別解決了「冪等」和「一致」,可是沒有引出「高併發」這個話題,由於高併發下這種方法失敗的機率很大,會頻繁失敗給用戶很差的體驗。高併發

後來不少網友就在後面引出了另外的一些觀點,例如redis,利用了redis的「快」,redis的快有幾個緣由,第一是內存讀取,第二是非阻塞IO,第三是單線程loop,避免了物理鎖,減小線程上下文切換時間,第四是hash結構存儲。所以雖然是單線程,可是redis帶來很是高效率的讀取,而且自然支持「高併發」,由於單線程操做不加任何鎖。可是redis的另一個風險就是數據存儲在內存中,有丟失的風險。所以,使用時還需結合業務場景來看。oop

 

第一篇文章後面還有網友提到了使用隊列來異步「扣減」,這實際上就和redis單線程同樣了,這種方法思路挺好的,可是本菜鳥以爲會損失掉不少性能,是一種時間換空間的方案,可能會帶來用戶體驗問題。性能

 

着重要提到的是後面一篇文章有一個答覆思路很是新穎,由於這個問題的併發點實際上就是「庫存」,全部的請求都在這個單點上操做,所以採用分佈式的思路就是把這個「單點」均衡開,若是庫存總數是m,那麼將同一個key下的庫存分紅n組,k1...kn,每組的庫存數爲m/n,扣減時能夠將請求均分到k1到kn上,這樣就減小了衝突的概率,又是一種空間換時間的好方法!spa

 

最後本菜鳥想說的是,庫存扣減這個問題往深了說在每一層可能都有不一樣的解決方案,在應用場景中應該按照具體的場景來看,是多讀場景仍是多寫場景,用戶的要求也不必定相同,所以業務場景決定了技術選型。這個話題仍是很是值得探討的,各類思路產生了火花,但願博主從此能多發些這種好文^_^

相關文章
相關標籤/搜索