中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Es因scroll查詢引起的gc問題怎么解決

發布時間:2022-05-07 11:11:15 來源:億速云 閱讀:558 作者:iii 欄目:大數據

這篇“Es因scroll查詢引起的gc問題怎么解決”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Es因scroll查詢引起的gc問題怎么解決”文章吧。

問題:

某日下午正開心的逛著超市,突然收到線上es機器的fgc電話告警,隨之而來的是一波es reject execution,該es機器所處集群出現流量抖動。

排查:

回到家打開監控頁面,內存占用率有明顯的上升,通常服務端不會無端的爆內存,首先排查可能性最高的:讀寫流量變化。

通過監控頁發現入口流量并沒有明顯抖動,考慮到集群中的不同索引以及不同查詢類型,總的入口流量可能會掩蓋一些問題,所以繼續查看各索引的分操作流量監控,發現索引 A 的scroll流量在故障發生時存在明顯的波動,從正常的 10qps 以內漲到最高 100qps 左右,這對于普通查詢來說并不高,看來是 scroll 查詢有些異樣。

起因1:

先說結論:scroll 查詢相對普通查詢占用的內存開銷大很多,考慮到遍歷數據的場景,安全的量是控制在 10qps 左右。

相比于普通query,scroll 查詢需要后端保留遍歷請求的上下文,具體的就是當有init scroll請求到達時,當時的 index searcher 會持有全部索引段的句柄直至scroll請求結束,如果處理不當,比如段緩存等,容易在server端占用大量內存;另外, scroll 查詢還需要在server端保存請求上下文,比如翻頁深度、scroll context等,也會占用內存資源。

在后續的測試中,客戶端單線程使用scroll查詢遍歷百萬級別的索引數據,server端的CPU占用率高達70%左右,觀察進程的CPU占用,發現大部分的CPU時間都耗在gc上,這使得server沒有足夠的CPU時間調度其他任務,導致正常的讀寫請求不能被及時響應。

# 壓測機器配置:1c2g x 10# 索引配置:5 number_of_shards x 1 number_of_replica,共計約180萬數據

起因2:

繼續排查scroll執行的查詢內容,發現的主要有兩種類型。

其一:

{    "query": {"bool":{"must":[{"terms":[11,22,…2003]}]}},    "size":200}# terms子句中包含200個id

上面的示例query省略了其他一些過濾條件,白話一下這個查詢的含義:

從索引中查詢id字段值為數組所包含的200條記錄

可以看到的幾個特征是:

  • 沒有filter子句,terms條件在must子句

  • 這個查詢最多返回200條記錄,一次查詢就可以得到全部數據

其二:

{    "query": {"bool":{"must":[        {"range":{"create_time":{"gt":0, "lte":604800}}},        {"term":{"shop_id":1}}    ]}},    "size":200}# range條件包含的數據大約為1000條# 全索引包含的數據大約1000萬條# create_time不固定,但是區間固定在1周

這里也省略了一些其他干擾條件,只保留最重要的,白話過來的含義:

從1000萬全量索引中查詢shop_id=1并且create_time在符合條件區間內的數據,條件區間每10秒變更一次,也就是每10秒查詢一次當前時刻之前1周的新數據.

可以得出的幾個結論:

  • size為200,要訪問全部數據至少需要5次查詢

  • create_time的變更很小,類似于 (0, 603800] => (5, 604805],所以每次查詢該子條件命中的記錄數變化也都不大,都有幾百萬條

  • 沒有filter子句

并沒有發現filter或者must_not這樣在官方文檔中明確標明的filter context條件,但是實際上的filter cache在scroll發生期間單機從 500 MB 左右逐漸升高到 6 GB(配置的filter cache最大空間),理論上說不通,直接從代碼里找答案。

跟蹤query流程,發現bool子句中不論是must還是filter,最終被rewrite之后沒有本質上的區別,判斷是否可以進入filter cache的條件是:

  • 段內最大文檔數是否在閾值范圍內(Es的filter緩存以段為單位)

  • 查詢出現頻次是否超過閾值

而在出現頻次這個部分,Lucene緩存策略還會有isCostly這樣的判斷,目的是盡量將高消耗的查詢盡可能早的緩存起來,提高查詢性能,符合isCostly判斷的查詢包括 terms 和 range 等查詢,只要重復出現2次即會被緩存起來,結合起來分析:

  1. terms查詢并不需要scroll查詢,使用普通查詢就能解決需求,使用scroll查詢增加了server負載

  2. range查詢重復次數達到了isCostly閾值,也就是說每次遍歷數據都會往filter cache中丟入幾百萬的緩存value,而且命中率極低(下次scroll查詢的range起止條件有細微的變化),加大了server的gc負擔

解決:

通過上面的分析,我們可以看到有兩個因素的影響導致了server的拒絕響應:

  1. 大量的scroll并發

  2. 不當的range請求,具體又可以拆分為:

    • 高頻次,每10秒一次

    • 變化快,每次查詢的起止范圍都有10秒的后延

    • 命中數大,百萬級別的命中數

針對上面的幾點各個擊破就是我們的解決方案:

scroll請求:

  • 糾正不當使用的terms+scroll查詢,使用普通查詢;

  • 推薦使用search_after替換scroll請求,雖然在效率上有所降低,但是有兩個優勢:

    • 可以重試,scroll如果重試可能會丟失部分數據

    • 資源占用低,在相同的測試環境下,CPU占用率只有10%左右

不當的range請求:

  • 高頻次:降低請求頻率,限制到至少1分鐘一次,當然不是根本解決方案,推薦將類似的遍歷數據請求改到db或者hbase等介質

  • 變化快:粗暴點的解決方案是限制時間單位到小時級別,優雅點的話:

    • 將時間條件拆分為粗粒度和細粒度的組合,粗粒度以若干小時為單位,細粒度支撐到分鐘或者秒級

    • 細粒度條件使用script方式執行,原理是filter cache的frequency是用LinkedHashMap作為key容器的,用來累積查詢次數,而key的hash計算,普通query是根據查詢的條件和值來作為hash輸入的,而script查詢是使用當前實例的引用,這樣就能避免查詢被累積(因為每次的hashcode都不一樣)

  • 命中數大:通過粗細粒度劃分可以降低成本

以上就是關于“Es因scroll查詢引起的gc問題怎么解決”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新乡市| 庆元县| 奉节县| 多伦县| 襄城县| 辽宁省| 出国| 甘孜县| 沾益县| 普定县| 盖州市| 玛纳斯县| 湖北省| 吉林市| 方城县| 澎湖县| 响水县| 汕尾市| 托里县| 锦州市| 上林县| 科尔| 徐水县| 无锡市| 日照市| 达州市| 湟中县| 金昌市| 屯留县| 罗山县| 鹰潭市| 都昌县| 宜丰县| 霍林郭勒市| 呼玛县| 贺兰县| 濮阳市| 长阳| 亳州市| 融水| 交城县|