您好,登錄后才能下訂單哦!
怎樣進(jìn)行Elasticsearch 7.7 的異步搜索原理解析,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個(gè)問題。
Elasticsearch 7.7 版本帶來一個(gè)新的特性,search 過程允許異步執(zhí)行,客戶端發(fā)送完 search 請求后,Elasticsearch 服務(wù)端給客戶端返回一個(gè) id,以后客戶端拿這個(gè) id 來獲取 search進(jìn)度,并且支持返回“部分”結(jié)果,這對于 UI 交互相關(guān)的查詢請求非常友好,例如繪圖過程可以逐步的顯示出來。
異步搜索使用起來非常簡單,使用新的 API 即可,其余都和 _search 請求相同:
POST /_async_search
返回結(jié)果中會有幾個(gè)新的字段:
id:根據(jù)這個(gè) id 獲取后續(xù)的 query 進(jìn)度。
is_partial:當(dāng) query 運(yùn)行完畢后,該字段指示 query 在所有分片上全部執(zhí)行成功,還是有失敗的情況。
is_running:表示搜索過程是否還在運(yùn)行中。
如果搜索很快就運(yùn)行完,_async_search 的Response 會包含完整的搜索結(jié)果,這里默認(rèn)會等待1秒鐘的時(shí)間,由參數(shù) wait_for_completion_timeout 控制,超過這個(gè)時(shí)間的話,后續(xù)根據(jù) id 獲取搜索進(jìn)度(或結(jié)果):
GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
這里考慮的很周到,在開啟了用戶認(rèn)證的情況下,每個(gè)人只能 GET 到自己提交的異步搜索結(jié)果,不會被其他人看到。搜索結(jié)果默認(rèn)保存5天,通過 keep_alive 參數(shù)控制.
同樣,你也可以手工 DELETE 這個(gè)異步搜索請求,如果搜索還在執(zhí)行過程中,則會被取消。
DELETE /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
異步搜索的實(shí)現(xiàn)原理和同步搜索其實(shí)沒有太大差別,數(shù)據(jù)節(jié)點(diǎn)執(zhí)行搜索的過程是相同的,區(qū)別只是協(xié)調(diào)節(jié)點(diǎn)原本要等整個(gè)過程處理完畢后才返回給客戶端,現(xiàn)在只等1秒(由wait_for_completion_timeout參數(shù)控制)。如果整個(gè)過程在1秒內(nèi)完成,就給客戶端返回最終結(jié)果,超過1秒后,就生成一個(gè) id 返回給客戶端。
數(shù)據(jù)節(jié)點(diǎn)像往常一樣,對于某個(gè)分片的查詢執(zhí)行完之后返回一個(gè)分片級別完整的 Response,并不會計(jì)算一點(diǎn)返回一點(diǎn),所以 Response 的單位還是分片級別的。不過 batched_reduce_size默認(rèn)被設(shè)置為5,這在同步搜索中默認(rèn)為512,小一點(diǎn)的值可以給客戶端盡早返回部分結(jié)果。
為了把查詢結(jié)果保存5天,es 會建立一個(gè)名為 .async-search的系統(tǒng)索引,將查詢結(jié)果保存到其中,但是如果搜索過程在 wait_for_completion_timeout 超時(shí)時(shí)間內(nèi)結(jié)束,所有的結(jié)果集會在當(dāng)前請求中返回,不會保存到 .async-search索引。
異步搜索返回一個(gè) id,后續(xù)按照這個(gè) id 獲取進(jìn)度,這個(gè)任務(wù)信息如何獲取到?進(jìn)度和結(jié)果集需要保存在哪個(gè)地方,是一個(gè)需要思考的問題,es 里會把他放到兩個(gè)地方:
如果搜索過程還沒有執(zhí)行完,進(jìn)度信息從協(xié)調(diào)節(jié)點(diǎn)的 taskmanager 里獲取
如果搜索執(zhí)行結(jié)束了,進(jìn)度和結(jié)果集會保存到名為 .async-search 的索引里。
在第一種情況下,相當(dāng)于進(jìn)度信息保存在協(xié)調(diào)節(jié)點(diǎn)的內(nèi)存里,這個(gè)信息只存在于整個(gè)集群的單個(gè)節(jié)點(diǎn)上,因此,當(dāng)你異步搜索的請求發(fā)送到了 node1,而獲取進(jìn)度的請求發(fā)送到 node2(例如經(jīng)過負(fù)載均衡器轉(zhuǎn)發(fā)或客戶端自己輪詢),在 node2 如何獲取到進(jìn)度信息?答案是 node2 收到獲取進(jìn)度的 GET 請求后,會將請求 轉(zhuǎn)發(fā)到 node1。那么 node2 怎么知道異步搜索請求發(fā)送到了 node1?實(shí)際上這些信息都保存在異步搜索請求返回的 id中,所以你現(xiàn)在知道了為什么他會這么長:
"id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc="
這個(gè) id 是一段 base64編碼,他包含了以下信息:
docId 當(dāng)搜索結(jié)果保存 .async-search 中時(shí),該異步搜索任務(wù)結(jié)果在 .async-search 中的 docId
nodeId 接收 asyncsearch 搜索請求的節(jié)點(diǎn)的 nodeId
id 在 taskManager 中的任務(wù) id
有了這些信息之后,GET 搜索進(jìn)度的流程就比較清楚了:
協(xié)調(diào)節(jié)點(diǎn)收到 GET /_async_search/id 請求后,根據(jù) id解碼出上述三個(gè)信息,先判斷執(zhí)行_async_search的節(jié)點(diǎn)是否本節(jié)點(diǎn),如果不是本節(jié)點(diǎn)就直接根據(jù)解碼出的nodeId給目標(biāo)節(jié)點(diǎn)發(fā)送RPC 請求來獲取這個(gè)信息;如果是本節(jié)點(diǎn),就根據(jù)任務(wù) id從自己的 taskManager 中獲取,或者根據(jù)docId執(zhí)行一個(gè)普通的 GET doc請求,從 .async-search 索引中獲取。
索引 .async-search中的數(shù)據(jù)默認(rèn)保存5天,不過大家都知道 es 里沒有 TTL 的概念,那么數(shù)據(jù)的過期刪除如何實(shí)現(xiàn)?實(shí)際上 es 內(nèi)部會定期對該索引執(zhí)行 DeleteByQuery:
DeleteByQueryRequest toDelete = new DeleteByQueryRequest(INDEX)
.setQuery(QueryBuilders.rangeQuery(EXPIRATION_TIME_FIELD).lte(nowInMillis));
當(dāng)節(jié)點(diǎn)收到集群狀態(tài)時(shí),在 clusterChanged 中驅(qū)動周期線程執(zhí)行清理,默認(rèn)1小時(shí)執(zhí)行一次,由參數(shù) async_search.index_cleanup_interval 控制,該清理操作由 GENERIC 線程池執(zhí)行,并且只會在 .async-search 索引的0號主分片所在的節(jié)點(diǎn)執(zhí)行,不會在所有節(jié)點(diǎn)都執(zhí)行清理工作。
看完上述內(nèi)容,你們掌握怎樣進(jìn)行Elasticsearch 7.7 的異步搜索原理解析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。