日韩性视频-久久久蜜桃-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)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 无码人妻久久一区二区三区不卡 | 国产精品亚洲无码 | 天天综合在线视频 | 欧美一级日韩一级 | 九色首页 | 女优中文字幕 | 青青青在线视频 | 国产一二在线 | av在线小说 | 色综合久久久久 | 日日草日日干 | 亚洲久视频| 男女日日 | 传媒av在线| 超碰免费公开 | 91九色在线视频 | 一区二区三区蜜桃 | 亚洲区 欧美区 | 中文字幕 成人 | 国产白浆一区二区 | 日韩城人网站 | 国产精品成人网站 | 视频在线免费观看 | 日日干天天干 | 欧美综合社区 | 国产人妻人伦精品1国产丝袜 | 成人深夜电影 | 国产真实乱在线更新 | 91尤物在线 | 苏晴忘穿内裤坐公交车被揉到视频 | 四虎免费在线观看 | 看av网| 国产97色在线 | 日韩 | av一区二区三区免费观看 | 久久亚洲av成人无码国产电影 | 激情小说视频在线 | 裸体av淫导航 | 中国女人真人一级毛片 | 国产精品精品国产色婷婷 | 中国性猛交 | 性做爰视频免费播放大全 | 伊人久久国产精品 | 中文字幕在线观看网 | 91老师国产黑色丝袜在线 | 国精产品一区一区三区视频 | 欧美影视一区二区 | 91精品国产乱码久久久张津瑜 | 一区在线不卡 | 日韩资源网 | 国产午夜在线一区二区三区 | 亚洲午夜久久久久久久国产 | 日韩三级av在线 | 国产精品亚洲一区 | 可以在线观看的黄色 | av大全免费 | 成年人免费在线看 | av黄色免费| 久久精品天天中文字幕人妻 | 红桃视频成人 | 四虎视频在线观看 | 亚洲美女影院 | 欧美一级爆毛片 | 日本精品在线看 | 女女h百合无遮羞羞漫画软件 | 99re8在线精品视频免费播放 | 秋霞7777鲁丝伊人久久影院 | 欧美亚洲不卡 | av中文字幕网址 | 久久久777| 亚洲一区精品在线 | 河北彩花av在线播放 | 国产青青草在线 | 免费一级淫片aaa片毛片a级 | 日本欧美一级片 | 午夜激情av | 色婷av | 在线播放ww | 国产一区欧美日韩 | 亚洲成人av一区 | av不卡免费在线观看 | 美女视频黄a视频全免费观看 | 一区二区三区www污污污网站 | 日韩123| 欧美少妇色图 | 精品自拍第一页 | 日韩大片免费观看 | 在线亚洲不卡 | 99re这里只有精品66 | 久久蜜桃精品 | 久久精品久 | 在线综合av | av操操 | 日本特黄一级片 | 午夜激情视频在线 | 特级a级片| 欧美性大战xxxxx久久久 | 欧美做受xxxxxⅹ性视频 | 成人h动漫精品一区二区 | 国精品一区 |