在電商場景下,工作流程為:
讀取商品資訊,包括庫存數量
使用者下單購買
更新商品資訊,將庫存數減一
如果是多執行緒操作,就可能有多個執行緒併發的去執行上述的3步驟流程,假如此時有兩個人都來讀取商
品資料,兩個執行緒併發的服務於兩個人,同時在進行商品庫存資料的修改。假設庫存為100件 正確的情
況:執行緒a將庫存-1,設定為99件,執行緒b接著讀取99件,再-1,變為98件。如果a,b執行緒都讀取的為
100件,a處理完之後修改為99件,b處理完之後再次修改為99件,此時結果就出錯了
put
/test_index/_doc/
4
模擬兩個客戶端,都獲取到了同一條資料
get
/test_index/_doc/
4# 返回
}
put
/test_index/_doc/
4
返回
,"_seq_no":1
,"_primary_term":1
}
put
/test_index/_doc/
4?if_seq_no=
0&if_primary_term=
1
會出錯
樂觀鎖就成功阻止併發問題],「type」: 「version_conflict_engine_exception」,
「reason」: 「[4]: version conflict, required seqno [0], primary term [1]. current document has seqno [1] and primary term [1]」,
「index_uuid」: 「qm83o5m4tzi5qci8v1lcyq」,
「shard」: 「0」,
「index」: 「test_index」
},「status」: 409
}
在樂觀鎖成功阻止併發問題之後,嘗試正確的完成更新
重新進行get請求,得到 version
基於最新的資料和版本號(以前是version 現在是if_seq_no和if_primary_term ),去進行修改,修
改後,帶上最新的版本號,可能這個步驟會需要反覆執行好幾次,才能成功,特別是在多執行緒併發
更新同一條資料很頻繁的情況下
put
/test_index/_doc/
4?if_seq_no=
1&if_primary_term=
1
es提供了乙個feature,就是說,你可以不用它提供的內部_version版本號來進行併發控制,可以基於你
自己維護的乙個版本號來進行併發控制。
?version=1&version_type=external
區別在於,version方式,只有當你提供的version與es中的version一模一樣的時候,才可以進行修改,只要不一樣,就報錯;當version_type=external的時候,只有當你提供的version比es中的_version大的時候,才能完成修改
es,if_seq_no=0&if_primary_term=1和 文件中的值相等 才能更新成功
es,_version=1,?version>1&version_type=external,才能成功,比如說?
version=2&version_type=external
put
/test_index/_doc/
5
put
/test_index/_doc/
5?version=
2&version_type=external
p
ut/test_index/_doc/
5?version=
3&version_type=external
ElasticSearch 併發操作問題
解決併發問題 問題的原因是 elasticsearch 不支援 acid 事務。對單個檔案的變更是 acidic 的,但包含多個文件的變更不支援。如果你的主要資料儲存是關聯式資料庫,並且 elasticsearch 僅僅作為乙個搜尋引擎 或一種提公升效能的方法,可以首先在資料庫中執行變更動作,然後在...
Elasticsearch 併發修改樂觀鎖
來自 1 elasticsearch 的樂觀鎖,可以使用外部系統提供的版本號 這時elasticsearch將只檢查提供的版本是否比當前儲存在索引中的版本大 大多少不重要 如果是成功,否則失敗。在elasticsearch中,更新請求實際上是分為兩個階段,獲取文件,修改文件,然後儲存文件。那麼當兩個...
elasticsearch配置詳解
elasticsearch的config資料夾裡面有兩個配置檔案 elasticsearch.yml和logging.yml,第乙個是es的基本配置檔案,第二個是日誌配置檔案,es也是使用log4j來記錄日誌的,所以logging.yml裡的設定按普通log4j配置檔案來設定就行了。下面主要講解下e...