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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

elasticsearch index、create和update的源码分析

發(fā)布時間:2025/4/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 elasticsearch index、create和update的源码分析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

https://segmentfault.com/a/1190000011272749

社區(qū)里面有人問了如下一個問題:

執(zhí)行 bulk 索引文檔的時候,用 index 或者 create 類型并且自定義 doc id 的情況下,是否會像 update 一樣每次都要去 get 一遍原始文檔? 比如下面的這條命令:

POST _bulk{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } } { "field1" : "value1" } { "create" : { "_index" : "test", "_type" : "type1", "_id" : "3" } } { "field1" : "value3" }

問題出現(xiàn)的原因是他們在 bulk 測試的時候遇到了寫性能的問題,而正巧社區(qū)里面前幾天有這么一個類似的帖子,說的是 es 5.x 版本里面做 update 操作的性能問題。雖然和這個問題不完全一致,但都涉及到 es 索引數(shù)據(jù)的部分。

侯捷老師說:“源碼面前,了無秘密”,那我們就來簡單看下 es 這部分的相關(guān)代碼,以便回答開篇提出的問題。

準(zhǔn)備工作

我是用?IntelliJ IDEA?來閱讀 elasticsearch 源碼的,操作也簡單。操作步驟如下:

  • 下載 es 源碼,由于 es 的commit信息比較多,可以增加?--depth=1?只下載最近的commit,減少下載時間。

    git?clone?https://github.com/elastic/elasticsearch.git --depth=1
  • 安裝 gradle,確保版本在 3.3 及以上,然后在源碼目錄下執(zhí)行以下命令準(zhǔn)備導(dǎo)入?IntelliJ IDEA?需要的文件

    gradle idea
  • 下載安裝?IntelliJ IDEA,確保版本為?2017.2?及以上版本。安裝完成后,將 elasticsearch 以 gradle 形式導(dǎo)入即可。
  • 大家可以參考?elasticsearch 文檔說明?和?Elasticsearch源碼分析—環(huán)境準(zhǔn)備?這兩篇文章,細(xì)節(jié)我這里就不贅述了。

    另外我是分析的 5.5.0 分支,大家記得 checkout,防止行數(shù)對應(yīng)不起來。另外由于 es 代碼結(jié)構(gòu)有些復(fù)雜,先不在這篇文章里面梳理整個流程了,直接說核心代碼。

    Index/Create 源碼分析

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

    457?public IndexResult index(Index index) throws IOException

    注意這里的 index 中包含有要寫入的 doc, 簡單畫下該方法的執(zhí)行流程圖,代碼這里就不貼了,剛興趣的自己去看。

    ?

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

    558?private IndexingStrategy planIndexingAsPrimary(Index index) throws IOException {

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

    • optimizedAppendOnly
    • skipDueToVersionConflict
    • processNormally
    • overrideExistingAsIfNotThere
    • skipAsStale

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

    ?

    這里的第一步判斷?是否是自定義 doc id?這一步就是 es 對于日志類非自定義 doc id的優(yōu)化,感興趣的可以自己去看下代碼,簡單講就是在非自定義 id 的情況下,直接將文檔 add ,否則需要 update,而 update 比 add 成本高很多。

    而第二個判斷?檢查版本號是否沖突??涉及到是如何根據(jù)文檔版本號來確認(rèn)文檔可寫入,代碼都在index.versionType().isVersionConflictForWrites方法里,邏輯也比較簡單,不展開講了,感興趣的自己去看吧。

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

    389?private VersionValue resolveDocVersion(final Operation op) throws IOException {

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

  • 嘗試從 versionMap 中讀取待寫入文檔的 version,也即從內(nèi)存中讀取。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, TTLFieldMapper.NAME, TimestampFieldMapper.NAME}, true, request.version(), request.versionType(), FetchSourceContext.FETCH_SOURCE); return prepare(indexShard.shardId(), request, getResult, nowInMillis); }

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

  • 獲取待更新文檔的數(shù)據(jù)
  • 執(zhí)行更新文檔的操作
  • 第 1 步最終會調(diào)用 InternalEngine 中的 get 方法,如下:

    350?public GetResult?get(Get?get, Function<String, Searcher> searcherFactory, LongConsumer onRefresh) throws EngineException {

    這里就接上開篇提到的社區(qū)問題中的源碼分析了。代碼就不展開講了,感興趣的自己去看吧。

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

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

    總結(jié)

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

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

    最后,記住侯捷老師的話:

    源碼面前,了無秘密!

    轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/9923885.html

    總結(jié)

    以上是生活随笔為你收集整理的elasticsearch index、create和update的源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 人妻丰满熟妇aⅴ无码 | 水牛影视av一区二区免费 | 搞黄视频在线观看 | 色婷婷久久久 | 欧美国产日韩在线观看 | 天天干夜夜爱 | 天天干天天爽天天射 | 日本伦理片在线播放 | 精品亚洲一区二区 | bt男人天堂 | 国产白丝袜美女久久久久 | 在线观看sm| 欧美在线精品一区 | 另类小说亚洲色图 | 一区不卡在线 | 超碰在线小说 | 欧美精品久久久久久久久久 | 538精品一线 | 精品一区二区三区人妻 | 台湾佬美性中文娱乐网 | 不卡黄色 | 成人免费黄色大片 | 欧美无遮挡高潮床戏 | 亚洲精品乱码久久久久久蜜桃动漫 | 正在播放欧美 | 4438x全国最大成人网 | 朝桐光在线视频 | 久久精品国内 | 欧美日韩精品一区二区 | 亚洲黄站 | 日韩3区 | 久久久久国产精品无码免费看 | 特级淫片裸体免费看 | 免费h片在线观看 | 亚洲黄页 | 精品人妻伦九区久久aaa片 | 欧美日韩色图 | 高h乱l高辣h文短篇h | 日本大尺度电影免费观看全集中文版 | 免费一区二区三区视频在线 | 天天干妹子 | 国产伦精品一区二区三区免费迷 | 激情网页 | 你懂的日韩| 性色AV无码久久一区二区三 | 成人免费精品视频 | 在线a| 国产成人精品无码高潮 | 亚洲综合一区在线 | 久久久精品中文字幕麻豆发布 | 神马午夜91 | 伦理片av| 成人写真福利网 | 毛片网 | 欧美少妇在线 | 99婷婷| 床戏高潮做进去大尺度视频 | 一区二区三区中文视频 | 亚洲人性生活视频 | 欧美女同视频 | 欧美日韩激情在线观看 | 久久er99热精品一区二区 | 欧美老熟妇喷水 | 三上悠亚久久精品 | 激情五月在线观看 | 一区二区黄色片 | 亚洲欧美成人 | 黑人精品欧美一区二区蜜桃 | 国内自拍在线观看 | 久久看片| 在线免费观看你懂的 | 久久av色 | 在线免费看毛片 | 日韩在线中文字幕视频 | 国产午夜精品理论片在线 | 国产午夜在线 | 午夜伦伦电影理论片费看 | 日日摸日日碰 | 日韩精品一区二区三区视频在线观看 | 成人国产精品入口免费视频 | 妺妺窝人体色www在线下载 | 经典三级第一页 | 青青操国产视频 | 国产精品一区二区久久久 | 亚洲无码精品在线观看 | 黄色一级视频免费看 | 韩国伦理片观看 | 国产精品va在线观看无码 | 91视频最新入口 | 美女屁股无遮挡 | 亚洲婷婷久久综合 | 毛片基地视频 | 国产精品蜜臀 | 国产在线观看无码免费视频 | 91麻豆免费视频 | 日韩夜夜高潮夜夜爽无码 | 亚洲欧美成人 | 亚洲精品国产精品国自产在线 | 日本aaa视频 |