elasticsearch學習筆記(十二)——Elasticsearch併發衝突問題以及鎖機制
1、Elasticsearch併發衝突問題
對於一般的ES操作流程是:
1、先get document資料,比如獲取到商品資料,將資料顯示到網頁上,同時在記憶體中快取該documentd的資料
2、當網頁發生了購買後,直接基於記憶體中的資料,進行計算和操作
3、將計算後的結果寫回ES中
下面描述一下場景
比如在電商場景下,假設說,我們有一個程式,工作流程如下:
1、讀取商品的資訊
2、使用者下單購買
3、更新商品資訊(主要是將庫存減1)
我們假設程式是多執行緒的,所以說可能有多個執行緒併發的去執行上述的3個步驟流程
將上述場景具體到某個商品的庫存修改的時候,假設一個牙膏的庫存是100件,現在同時有兩個人都過來讀取了牙膏的資料,然後下單購買了這管牙膏,此時兩個執行緒併發執行,同時在進行商品庫存的修改。
如圖所示,在正常的情況下,我們期望執行緒A將庫存-1,設定為99件;然後執行緒B接著這個99件,將庫存-1,變為98件,然後寫入到ES中。
但是總有一個執行緒是先到的,假設就是執行緒A,此時執行緒A就會先將牙膏的庫存設定為99件,然後執行緒B再次將牙膏的庫存設定為99件,結果很顯然就不是我們想要的。
上述的這個流程,其實就是ES中的併發衝突問題,會導致資料不準確。
2、悲觀鎖與樂觀鎖兩種併發控制方案
這裡先附上中華石衫老師畫的手工圖
下面簡單做一下描述和概括
悲觀鎖:所謂悲觀鎖就是在任何情況下都上鎖,上鎖之後,就只有一個執行緒可以操作這一條資料,其它執行緒只能等待,當然在不同的場景下,上的鎖會有所不同,可以是行級鎖,表級鎖,讀鎖,寫鎖。通俗的來講,加了悲觀鎖的話,對資料操作的時候就相當於是單執行緒的了。
樂觀鎖:其實所謂的樂觀鎖,根本就沒有加鎖,只是多了一標識欄位,這個欄位可以是一個整數型別的,也可以是時間型別的。主要的作用就是在每次修改資料的時候會做一層判斷,判斷資料是否已經被修改過了,如果已經被修改了,那麼就會重新獲取資料,在修改,這個過程不斷進行知道資料修改成功。
下面比較一下兩種鎖的優缺點
1、對於悲觀鎖,它使用起來很方便,直接加鎖就可以了,對於應用程式來說,它是透明的,不需要做額外的操作。但是每次都需要獲取到鎖之後才能對資料進行修改,也就是同一時間只能有一個執行緒能夠進行操作,併發能力很低
2、對於樂觀鎖,它根本就沒有加鎖,所以併發能力很高。但是每次更新資料的時候都需要對標識欄位做一個判斷,這個過程可能要重複很多遍。而且是需要應用程式做處理的。
3、Elasticseach基於_version進行樂觀鎖的併發控制
對於ES來說,它是採用樂觀鎖,對應的樂觀鎖的標識欄位是_version,是一個整數型別,一開始建立document時,_version是等於1的,之後對document每修改一次,_version版本號就會自動加1。