日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ElasticStack系列之十六 ElasticSearch5.x index/create 和 update 源码分析

發布時間:2025/4/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ElasticStack系列之十六 ElasticSearch5.x index/create 和 update 源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開篇

  在ElasticSearch 系列十四中提到的問題即 ElasticStack系列之十四 & ElasticSearch5.x bulk update 中重復 id 性能驟降,繼續這個問題再繼續查看更加多的源代碼,看看底層在執行 index、create 和 update 操作到底有什么不同,有什么可以使得我們使用性能更加好的。

準備

  使用 Intellij IDEA 來閱讀 ElasticSearch 源碼,操作相對來說比較簡單。具體操作步驟如下:

1. 下載 ElasticSearch 源碼

git clone https://github.com/elastic/elasticsearch.git

2. 下載安裝 gradle,確保版本在 3.3 及以上,我電腦是 macOS,自動下載最新版本為:4.2.1

brew update && brew install gradle

  在 mac 上按照上面的命令執行完畢之后它會自動安裝到 /usr/local/bin/gradle , 源文件目錄我到現在都沒有找到,最后一怒之下直接下載對應最新版本的 zip 包,放到指定目錄自己執行安裝

  首先,先download最新版本的gradle,網址:http://www.gradle.org/get-started
  然后將下載下來的zip包放在你要安裝的路徑上,我安裝在 /usr/myname/
  然后打開電腦上的.bash_profile文件,輸入以下命令:

  export GRADLE_HOME=/Users/myname/gradle-4.2.1export PATH=$PATH:$GRADLE_HOME/bin

  然后執行命令:source ~/.bash_profile 使剛才配置生效。

3. 進入到 ElasticSearch 源碼目錄,在該目錄下執行以下命令準備導入 IntelliJ IDEA 需要的文件

gradle idea

  以上命令執行完畢之后,打開 IntelliJ IDEA 工具它會自己進行編譯,需要你配置對應的 gradle home 目錄,即上面指定的 /Usrs/myname/gradle-4.2.1 ,配置完畢之后項目就算導入成功了。

  注意:

  1. 運行這個命令需要下載很多東西,有時候可能因為某一個包卡住,不要緊張,退出重新運行該命令,多嘗試幾次就好了。

  2. 各個版本代碼上有一定的差別,但是核心代碼整體是不會有大改動的,我查看的源碼版本為當前最新版本:5.6.3

Index/Create 源碼分析

  es index 和 create 最終都會調用 org/elasticsearch/index/engine/InternalEngine.java 中下面的方法:

  public IndexResult index(Index index) throws IOException

  注意這里的 index 中包含有要寫入的 doc, 簡單畫下該方法的執行流程圖,代碼這里就不貼了

  

  請結合上面的流程圖來看相應的代碼,整個邏輯應該還是很清晰的,接下來我們看 planIndexingAsPrimary 的邏輯。

  private IndexingStrategy planIndexingAsPrimary(Index index) throws IOException

? 這個方法最終返回一個 IndexingStrategy,即一個索引的策略,總共有如下幾個策略:

  • optimizedAppendOnly
  • skipDueToVersionConflict
  • processNormally
  • overrideExistingAsIfNotThere
  • skipAsStale

  不同的策略對應了不同的處理邏輯,前面3個是常用的,我們來看下流程圖。

?  

  這里的第一步判斷:是否是自定義 doc id? 這一步就是 es 對于日志類非自定義 doc id 的優化,感興趣的可以自己去看下代碼,簡單講就是在非自定義 id 的情況下,直接將文檔 add ,否則需要 update,而 update 比 add 成本高很多。
  而第二個判斷:檢查版本號是否沖突? 涉及到是如何根據 文檔版本號(doc version) 來確認文檔可寫入,代碼都在 index.versionType().isVersionConflictForWrites 方法里,邏輯也比較簡單,不展開講了,感興趣的自己去看吧。

  上面的流程圖也比較清晰地列出了策略選擇的邏輯,除去 optimizedAppendOnly 策略,其他都需要根據待寫入文檔的版本號來做出決策。接下來我們就看下獲取文檔版本號的方法。

  private VersionValue resolveDocVersion(final Operation op) throws IOException

?該方法邏輯比較簡單,主要分為2步:

  • 嘗試從 versionMap 中讀取待寫入文檔的 version,也即從內存中讀取。versionMap 會暫存還沒有 commit 到磁盤的文檔版本信息。
  • 如果第 1 步中沒有讀到,則從 index 中讀取,也即從文件中讀取。
  •   看到這里,開篇問題便有了答案。es 在 index 或者 create 的時候并不會 get 整個文檔,而是只會獲取文檔的版本號做對比,而這個開銷不會很大。

    ?Update 源碼分析

      es update 的核心代碼在 org/elasticsearch/action/update/UpdateHelper.java 中,具體方法如下:

    public Result prepare(UpdateRequest request, IndexShard indexShard, LongSupplier nowInMillis) {final GetResult getResult = indexShard.getService().get(request.type(), request.id(),new String[]{RoutingFieldMapper.NAME, ParentFieldMapper.NAME},true, request.version(), request.versionType(), FetchSourceContext.FETCH_SOURCE);return prepare(indexShard.shardId(), request, getResult, nowInMillis); }

     代碼邏輯很清晰,分兩步走:

  • 獲取待更新文檔的數據
  • 執行更新文檔的操作
  •   第 1 步最終會調用 InternalEngine 中的 get 方法,如下:

      public GetResult get(Get get, Function<String, Searcher> searcherFactory, LongConsumer onRefresh) throws EngineExceptio

      update 操作需要先獲取原始文檔的原因也很簡單,因為這里是允許用戶做部分更新的,而 es 底層每次更新時要求必須是完整的文檔(因為 lucene 的更新實際是刪除老文檔,新增新文檔),如果不拿到原始數據的話,就不能組裝出更新后的完整文檔了。

      因此,比較看重效率的業務,最好還是不要用 update 這種操作,直接用上面的 index 會更好一些。

    總結

      本文通過源碼分析的方式解決了開篇提到的問題,答案簡單總結在下面。

      es 在 index 和 create 操作的時候,如果沒有自定義 doc id,那么會使用 append 優化模式,否則會獲取待寫入文檔的版本號(doc version),進行版本檢查后再決定是否寫入 lucene。所以這里不會去做一個 get 操作,即獲取完整的文檔信息。

    ?

    轉載于:https://www.cnblogs.com/liang1101/p/7661810.html

    總結

    以上是生活随笔為你收集整理的ElasticStack系列之十六 ElasticSearch5.x index/create 和 update 源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。