ElasticSearch 并发的处理方式:锁和版本控制_07
文章目錄
- 現象
- 鎖
- 版本控制
- 最新方案
現象
當我們使用 es 的 API 去進行文檔更新時,它首先讀取原文檔出來,然后對原文檔進行更新,更新完成后再重新索引整個文檔。不論你執行多少次更新,最終保存在 es 中的是最后一次更新的文檔。但是如果有兩個線程同時去更新,就有可能出問題。
要解決問題,就是鎖。
鎖
- 悲觀鎖
很悲觀,每一次去讀取數據的時候,都認為別人可能會修改數據,所以屏蔽一切可能破壞數據完整性的操作。關系型數據庫中,悲觀鎖使用較多,例如行鎖、表鎖等等。
- 樂觀鎖
很樂觀,每次讀取數據時,都認為別人不會修改數據,因此也不鎖定數據,只有在提交數據時,才會檢查數據完整性。這種方式可以省去鎖的開銷,進而提高吞吐量。
在 es 中,實際上使用的就是樂觀鎖。
版本控制
es6.7之前
在 es6.7 之前,使用 version+version_type 來進行樂觀并發控制。根據前面的介紹,文檔每被修改一個,version 就會自增一次,es 通過 version 字段來確保所有的操作都有序進行。
version 分為內部版本控制和外部版本控制。
- 內部版本
es 自己維護的就是內部版本,當創建一個文檔時,es 會給文檔的版本賦值為 1。
每當用戶修改一次文檔,版本號就回自增 1。
如果使用內部版本,es 要求 version 參數的值必須和 es 文檔中 version 的值相當,才能操作成功。
- 外部版本
也可以維護外部版本。
在添加文檔時,就指定版本號:
PUT blog/_doc/1?version=200&version_type=external {"title":"2222" }以后更新的時候,版本要大于已有的版本號。
vertion_type=external 或者 vertion_type=external_gt 表示以后更新的時候,版本要大于已有的版本號。
vertion_type=external_gte 表示以后更新的時候,版本要大于等于已有的版本號。
最新方案
(Es6.7 之后)
現在使用 if_seq_no 和 if_primary_term 兩個參數來做并發控制。
seq_no 不屬于某一個文檔,它是屬于整個索引的(version 則是屬于某一個文檔的,每個文檔的 version 互不影響)。現在更新文檔時,使用 seq_no 來做并發。由于 seq_no 是屬于整個 index 的,所以任何文檔的修改或者新增,seq_no 都會自增。
現在就可以通過 seq_no 和 primary_term 來做樂觀并發控制。
PUT blog/_doc/2?if_seq_no=5&if_primary_term=1 {"title":"6666" } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的ElasticSearch 并发的处理方式:锁和版本控制_07的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Attribute “singleton
- 下一篇: 一分钟解决 Github 访问慢