ElasticSearch-文檔元數據樂觀并發控制

文章目錄

  • 什么是文檔?
  • 文檔元數據
  • 文檔的部分更新
  • Update 樂觀并發控制

最近日常工作開發過程中使用到了 ES,最近在檢索資料的時候翻閱到了 ES 的官方文檔,里面對 ES 的基礎與案例進行了通俗易懂的解釋,讀下來也有不少收獲,所以打算記錄一下。果真官方文檔才是最好的“菜鳥教程”。

貼上官方文檔:

Elasticsearch:權威指南-基礎入門

什么是文檔?

Elasticsearch 中,術語 文檔 有著特定的含義。它是指最頂層或者根對象, 這個根對象被序列化成 JSON 并存儲到 Elasticsearch 中,指定了唯一 ID。可以簡單理解為我們平時操作存儲的對象在 ES 中通過 JSON 序列化存儲的內容,是 ES 中操作的最小單位。

{"name":         "John Smith","age":          42,"confirmed":    true,"join_date":    "2014-06-01","home": {"lat":      51.5,"lon":      0.1},"accounts": [{"type": "facebook","id":   "johnsmith"},{"type": "twitter","id":   "johnsmith"}]
}

文檔元數據

一個文檔不僅包含著其本身的數據,也包含文檔有關的信息,可以稱之為 「元數據」。

三個必須的元數據元素如下:

  • _index

    文檔在哪存放,就是我們平時建立的索引

  • _type

    文檔表示的對象類別,這個平時用的比較少,算是同一索引下的一個更細的類別劃分

  • _id

    文檔唯一標識,可以通過它檢索唯一的文檔。當創建一個新文檔的時候,要么自己提供 _id,要么讓 ES 自動生成

文檔的部分更新

ES update API 似乎對文檔直接進行了修改,但是實際上 ES 中文檔是「不能被修改,只能被替換」,詳細的過程如下:

  1. 從舊文檔構建 JSON
  2. 更改該 JSON
  3. 刪除舊文檔
  4. 索引一個新文檔

注意:其中操作“刪除文檔”也并不會立即將文檔從磁盤中刪除,只是將文檔標記為已刪除狀態,即軟刪。隨著我們不斷索引更多的數據,ES 才會在后臺線程中清理標記為已刪除的文檔。

Update API 整體遵循 檢索-修改-重建索引 的處理過程,并且這三步都是發生在 ES 節點內部的,避免了客戶端和 ES 集群的多次網絡交互開銷。通過減少檢索和重建索引步驟之間的事件,也減少了其他進程的變更帶來沖突的可能性。但是這不能完全消除沖突的可能性,可能還是會有某個進程在 update 設法重建索引前,另一進程請求修改了文檔。

Update 樂觀并發控制

ES 是分布式的,當文檔創建、更新或刪除的時候,新版本的文檔必須復制到集群中的其他節點。ES 也是異步和并發的,這意味著這些復制請求被并行發送,并且到達目的地時也許是「亂序」的,ES 需要一種方法確保文檔的舊版本不會覆蓋新的版本。

ES 中每個文檔都有一個 _version 號,可以當作其元數據的一部分,當文檔被修改時,版本號會遞增。ES 可以使用 _version 來確保變更以正確的順序執行,如果舊版本的文檔在新版本之后到達,可以被簡單的忽略。

并且通過 _version 版本號還可以進行更新的樂觀并發控制,這可以確保應用中相互沖突的變更不會導致數據沖突。我們可以通過指定想要修改的文檔的 _version 來達到這個目的,如果該版本不是當前版本號,我們的請求會失敗。

Update API 樂觀并發控制:

Update API 的 檢索-修改-重建索引 步驟拆解下來就是如下的 Get - Update - Put 請求,三個步驟不是原子的話就會產生沖突,像下面的示意圖所示就會產生更新數據覆蓋的問題

在這里插入圖片描述

為了避免并發更新時產生的數據丟失,Update API 在「檢索」步驟時檢索得到當前文檔的 _version 號,并傳遞版本號到 「重建索引」的請求上。如果另一個進程修改了處于「檢索」和「重建索引」步驟之間的文檔,那么 _version 號將不匹配,更新請求將會失敗。這種場景就是先到的 request1 由于執行時間過長,反倒被后到的&執行時間更短的 request2 給沖突導致失敗了。

在增量操作無關順序的場景下,兩個進程更新操作發生的順序不太重要(比方說兩個進程都對頁面訪問量進行遞增計數),那么由于沖突導致更新失敗的請求,唯一需要做的就是重試。

這可以通過設置參數 retry_on_conflict 來自動完成,這個參數規定了失敗之前 update 應該重試的次數,它的默認值是 0,也就是默認不重試。下面的例子表示失敗之前需要重試 5 次。

POST /website/pageviews/1/_update?retry_on_conflict=5 
{"script" : "ctx._source.views+=1","upsert": {"views": 0}
}

但是在其他情況下變更可能要求是「有序的」,那么在 ES update 的這個角度上來說,就不能開啟重試邏輯,比方在更新賬戶余額場景下(非遞增遞減操作),先到的 request1 被后到的 request2 沖突失敗了,此時 request2 是最新的數據,ES 也是能夠維持「最終一致性的」,但如果讓 request1 重試一次,賬戶余額就會被老的數據覆蓋了,顯然是不能接受的。

再拓展一下思路,上面僅僅是在 ES 系統內保證 update 的有序,如果放在整個分布式系統中去看,比方說消息系統生產者發送消息,消費者消費并更新 ES(canal 就有這種模式),如果要保證分布式系統的全局有序,就得額外考慮 1.生產者到 MQ 2.MQ 到消費者 3.消費者到更新ES 每個環節的「有序性」。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/67024.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/67024.shtml
英文地址,請注明出處:http://en.pswp.cn/web/67024.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實驗二 數據庫的附加/分離、導入/導出與備份/還原

實驗二 數據庫的附加/分離、導入/導出與備份/還原 一、實驗目的 1、理解備份的基本概念,掌握各種備份數據庫的方法。 2、掌握如何從備份中還原數據庫。 3、掌握數據庫中各種數據的導入/導出。 4、掌握數據庫的附加與分離,理解數據庫的附加與分離的作用。…

技術中臺與終搜——2

文章目錄 5、語言處理與自動補全技術探測5.1 自定義語料庫5.1.1 語料庫映射OpenAPI5.1.2 語料庫文檔OpenAPI 5.2 產品搜索與自動補全5.2.1 漢字補全OpenAPI5.2.2 拼音補全OpenAPI 5.3 產品搜索與語言處理5.3.1 什么是語言處理(拼寫糾錯)5.3.2 語言處理Op…

15_業務系統基類

創建腳本 SystemRoot.cs 因為 業務系統基類的子類 會涉及資源加載服務層ResSvc.cs 和 音樂播放服務層AudioSvc.cs 所以在業務系統基類 提取引用資源加載服務層ResSvc.cs 和 音樂播放服務層AudioSvc.cs 并調用單例初始化 using UnityEngine; // 功能 : 業務系統基類 public c…

k8s優雅重啟

理論上處于terminating狀態的pod,k8s 就會把它從service中移除了,只用配置一個優雅停機時長就行了。kubectl get endpoints 驗證 因此,優雅重新的核心問題,是怎么讓空閑長連接關閉,再等待處理中的請求執行完。 一些底…

【Linux】華為服務器使用U盤安裝統信操作系統

目錄 一、準備工作 1.1 下載UOS官方系統 1.2制作啟動U盤 1.3 服務器智能管理系統iBMC 二、iBMC設置U盤啟動 一、準備工作 1.1 下載UOS官方系統 服務器CPU的架構是x86-64還是aarch64),地址:統信UOS生態社區 - 打造操作系統創…

27. 【.NET 8 實戰--孢子記賬--從單體到微服務】--簡易報表--報表服務

報表是每個記賬應用所具備的功能,要實現報表功能就需要把賬本的核心功能(記賬)完成,因此報表服務作為本專欄第一部分單體應用開發中最后一個要實現的功能,這一篇文章很簡單,我們一起來實現一個簡單的報表服…

基于 Node.js 的天氣查詢系統實現(附源碼)

項目概述 這是一個基于 Node.js 的全棧應用,前端使用原生 JavaScript 和 CSS,后端使用 Express 框架,通過調用第三方天氣 API 實現天氣數據的獲取和展示。 主要功能 默認顯示多個主要城市的天氣信息 支持城市天氣搜索 響應式布局設計 深色主題界面 優雅的加載動畫 技術棧 …

cursor重構谷粒商城04——vagrant技術快速部署虛擬機

前言:這個系列將使用最前沿的cursor作為輔助編程工具,來快速開發一些基礎的編程項目。目的是為了在真實項目中,幫助初級程序員快速進階,以最快的速度,效率,快速進階到中高階程序員。 本項目將基于谷粒商城…

leetcode 面試經典 150 題:簡化路徑

鏈接簡化路徑題序號71題型字符串解法棧難度中等熟練度??? 題目 給你一個字符串 path ,表示指向某一文件或目錄的 Unix 風格 絕對路徑 (以 ‘/’ 開頭),請你將其轉化為 更加簡潔的規范路徑。 在 Unix 風格的文件系統中規則如下…

如何在gitee/github上面搭建obsidian的圖床

在搭建圖床之前我們需要知道圖床是一個什么東西,圖床顧名思義就是存放圖片的地方,那么我們為什么要搭建圖床呢?因為我們在寫博客的時候,很多同學都是在本地使用typora或者是obsidian進行markdown語法的文章的書寫,文件格式通常都是…

JVM堆空間

JVM(Java虛擬機)堆空間是Java內存管理的核心區域之一,用于存儲Java對象實例。以下是關于JVM堆空間的詳細介紹: 1. 堆空間的作用 ? 存儲對象實例:幾乎所有的Java對象實例(通過new關鍵字創建的對象&#xf…

Redis 的熱 Key(Hot Key)問題及解決方法

Redis 的熱 Key(Hot Key)問題及解決方法 1. 什么是 Redis 熱 Key? Redis 熱 Key(Hot Key)指的是訪問頻率極高的 Key,通常會造成以下問題: 單 Key 訪問量過大:熱點 Key 可能被高并…

SSM東理咨詢交流論壇

🍅點贊收藏關注 → 添加文檔最下方聯系方式咨詢本源代碼、數據庫🍅 本人在Java畢業設計領域有多年的經驗,陸續會更新更多優質的Java實戰項目希望你能有所收獲,少走一些彎路。🍅關注我不迷路🍅 項目視頻 js…

http的請求體各項解析

一、前言 做Java開發的人員都知道,其實我們很多時候不單單在寫Java程序。做的各種各樣的系統,不管是PC的 還是移動端的,還是為別的系統提供接口。其實都離不開http協議或者https 這些東西。Java作為編程語言,再做業務開發時&#…

gradle生命周期鉤子函數

文章目錄 0. 總結表格1. 構建初始階段gradle.settingsEvaluated()gradle.projectsLoaded() 2. 配置階段gradle.beforeProject()gradle.afterProject()gradle.projectEvaluated()gradle.afterEvaluate()gradle.taskGraph.whenReady 3. 執行階段gradle.taskGraph.beforeTaskgradl…

Qt Enter和HoverEnter事件

介紹 做PC開發的過程中或多或少都會接觸到鼠標的懸停事件,Qt中處理鼠標懸停有Enter和HoverEnter兩種事件 相同點 QEvent::Enter對應QEnterEvent,描述的是鼠標進入控件坐標范圍之內的行為,QEnterEvent可以抓取鼠標的位置;QEvent…

【云安全】云原生-Docker(五)容器逃逸之漏洞利用

漏洞利用逃逸 通過漏洞利用實現逃逸,主要分為以下兩種方式: 1、操作系統層面的內核漏洞 這是利用宿主機操作系統內核中的安全漏洞,直接突破容器的隔離機制,獲得宿主機的權限。 攻擊原理:容器本質上是通過 Linux 的…

如何優化深度學習模型來提高錯別字檢測準確率?

為了優化深度學習模型以提高錯別字檢測的準確率,可以從以下幾個方面入手: 1. 數據增強 數據增強是提高模型泛化能力的有效方法。通過在訓練數據中引入噪聲,模型可以學習到更多變的模式,從而提高對未見數據的識別能力。 刪除字符:以一定概率刪除文本中的一個字符。增加字…

二叉搜索樹中的搜索(力扣700)

首先介紹一下什么是二叉搜索樹。 二叉搜索樹是一個有序樹: 若它的左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;若它的右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;它的左、右子樹也分別為二叉…

pytest自動化測試 - 構造“預置條件”的幾種方式

<< 返回目錄 1 pytest自動化測試 - 構造“預置條件”的幾種方式 1.1 使用夾具構造預置條件 在夾具章節中&#xff0c;我們介紹了夾具的作用&#xff0c;其中一項就是構造預置條件。pytest.fixture裝飾器中如果測試數據使用yield返回&#xff0c;則yield前的語句為預置條…