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