Elasticsearch乾貨(一):Elasticsearch鎖機制(併發控制)

Elasticsearch和數據庫一樣,在多線程併發訪問修改的情況下,會有一個鎖機制來控制每次修改的均爲最新的文檔。大體上主要有樂觀鎖和悲觀鎖兩類。

樂觀鎖

在Elasticsearch通過_version來記錄文檔的版本,在文檔創建時會有一個初始version,默認爲1。在對文檔進行修改和刪除時,version會遞增,也可以由用戶指定。只有當版本號大於當前版本時,纔會修改刪除成功,否則失敗。當併發請求時,先修改成功的,version會增加,這個時候其他請求就會猶豫version不匹配從而修改失敗。

由於segment時不能被修改的,所以當對一個文檔執行DELETE之後,在插入相同id的文檔,version版本不會是0,而是在DELETE操作的version上遞增。

外部版本號和內部版本號區別
對於內在_version=1,只有在後續請求滿足?_version=1的時候才能夠更新成功;對於外部_version=1,只有在後續請求滿足?_version>1才能夠修改成功。

es提供了一個外部版本號的樂觀控制方案來替代內部的_version。
?version=1&version_type=external

悲觀鎖

悲觀鎖類似於數據庫中的鎖。當線程1在修改或刪除doc時,會對數據上鎖,這個時候其它線程不能對數據進行操作的。這種方式保證了只有一個線程在同時操作數據。這種方式的缺點是對系統性能有影響,會降低整個系統併發能力,因爲其他線程要等待。

悲觀鎖主要有以下幾種方式:

全局鎖

對整個index上鎖,類似數據庫的表鎖。

當對文檔進行操作時,會對整個index。
上鎖

##上鎖
PUT /fs/lock/global/_create
{}
##釋放鎖
DELETE /fs/lock/global

文檔鎖

在文檔級別上鎖,類似數據庫的行鎖。

create上鎖

PUT /fs/lock/_bulk
{ "create": { "_id": 1}} 
{ "process_id": 123    } 
{ "create": { "_id": 2}}
{ "process_id": 123    }

update上鎖,需要用腳本。

POST /fs/lock/1/_update
{
  "upsert": { "process_id": 123 },
  "script": "if ( ctx._source.process_id != process_id )
  { assert false }; ctx.op = 'noop';"
  "params": {
    "process_id": 123
  }
}

如果update文檔不存在,則走上面的create。如果文檔存在,腳本會查看文檔中的process_id是否和要修改的process_id匹配,如果匹配不會執行update,但是會返回爲成功。如果不匹配即上鎖失敗。

樹鎖

參考https://www.elastic.co/guide/cn/elasticsearch/guide/current/concurrency-solutions.html

更多:Elasticsearch深入理解專欄
——————————————————————————————————
作者:桃花惜春風
轉載請標明出處,原文地址:
https://blog.csdn.net/xiaoyu_BD/article/details/81941631
如果感覺本文對您有幫助,請留下您的贊,您的支持是我堅持寫作最大的動力,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章