新聞中心
這篇“Es因scroll查詢引起的gc問(wèn)題怎么解決”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“Es因scroll查詢引起的gc問(wèn)題怎么解決”文章吧。
創(chuàng)新互聯(lián)公司長(zhǎng)期為數(shù)千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為葉城企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、做網(wǎng)站,葉城網(wǎng)站改版等技術(shù)服務(wù)。擁有十余年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
問(wèn)題:
某日下午正開(kāi)心的逛著超市,突然收到線上es機(jī)器的fgc電話告警,隨之而來(lái)的是一波es reject execution,該es機(jī)器所處集群出現(xiàn)流量抖動(dòng)。
排查:
回到家打開(kāi)監(jiān)控頁(yè)面,內(nèi)存占用率有明顯的上升,通常服務(wù)端不會(huì)無(wú)端的爆內(nèi)存,首先排查可能性最高的:讀寫流量變化。
通過(guò)監(jiān)控頁(yè)發(fā)現(xiàn)入口流量并沒(méi)有明顯抖動(dòng),考慮到集群中的不同索引以及不同查詢類型,總的入口流量可能會(huì)掩蓋一些問(wèn)題,所以繼續(xù)查看各索引的分操作流量監(jiān)控,發(fā)現(xiàn)索引 A 的scroll流量在故障發(fā)生時(shí)存在明顯的波動(dòng),從正常的 10qps 以內(nèi)漲到最高 100qps 左右,這對(duì)于普通查詢來(lái)說(shuō)并不高,看來(lái)是 scroll 查詢有些異樣。
起因1:
先說(shuō)結(jié)論:scroll 查詢相對(duì)普通查詢占用的內(nèi)存開(kāi)銷大很多,考慮到遍歷數(shù)據(jù)的場(chǎng)景,安全的量是控制在 10qps 左右。
相比于普通query,scroll 查詢需要后端保留遍歷請(qǐng)求的上下文,具體的就是當(dāng)有init scroll請(qǐng)求到達(dá)時(shí),當(dāng)時(shí)的 index searcher 會(huì)持有全部索引段的句柄直至scroll請(qǐng)求結(jié)束,如果處理不當(dāng),比如段緩存等,容易在server端占用大量?jī)?nèi)存;另外, scroll 查詢還需要在server端保存請(qǐng)求上下文,比如翻頁(yè)深度、scroll context等,也會(huì)占用內(nèi)存資源。
在后續(xù)的測(cè)試中,客戶端單線程使用scroll查詢遍歷百萬(wàn)級(jí)別的索引數(shù)據(jù),server端的CPU占用率高達(dá)70%左右,觀察進(jìn)程的CPU占用,發(fā)現(xiàn)大部分的CPU時(shí)間都耗在gc上,這使得server沒(méi)有足夠的CPU時(shí)間調(diào)度其他任務(wù),導(dǎo)致正常的讀寫請(qǐng)求不能被及時(shí)響應(yīng)。
# 壓測(cè)機(jī)器配置:1c2g x 10# 索引配置:5 number_of_shards x 1 number_of_replica,共計(jì)約180萬(wàn)數(shù)據(jù)
起因2:
繼續(xù)排查scroll執(zhí)行的查詢內(nèi)容,發(fā)現(xiàn)的主要有兩種類型。
其一:
{ "query": {"bool":{"must":[{"terms":[11,22,…2003]}]}}, "size":200}# terms子句中包含200個(gè)id
上面的示例query省略了其他一些過(guò)濾條件,白話一下這個(gè)查詢的含義:
從索引中查詢id字段值為數(shù)組所包含的200條記錄
可以看到的幾個(gè)特征是:
沒(méi)有filter子句,terms條件在must子句
這個(gè)查詢最多返回200條記錄,一次查詢就可以得到全部數(shù)據(jù)
其二:
{ "query": {"bool":{"must":[ {"range":{"create_time":{"gt":0, "lte":604800}}}, {"term":{"shop_id":1}} ]}}, "size":200}# range條件包含的數(shù)據(jù)大約為1000條# 全索引包含的數(shù)據(jù)大約1000萬(wàn)條# create_time不固定,但是區(qū)間固定在1周
這里也省略了一些其他干擾條件,只保留最重要的,白話過(guò)來(lái)的含義:
從1000萬(wàn)全量索引中查詢shop_id=1并且create_time在符合條件區(qū)間內(nèi)的數(shù)據(jù),條件區(qū)間每10秒變更一次,也就是每10秒查詢一次當(dāng)前時(shí)刻之前1周的新數(shù)據(jù).
可以得出的幾個(gè)結(jié)論:
size為200,要訪問(wèn)全部數(shù)據(jù)至少需要5次查詢
create_time的變更很小,類似于 (0, 603800] => (5, 604805],所以每次查詢?cè)撟訔l件命中的記錄數(shù)變化也都不大,都有幾百萬(wàn)條
沒(méi)有filter子句
并沒(méi)有發(fā)現(xiàn)filter或者must_not這樣在官方文檔中明確標(biāo)明的filter context條件,但是實(shí)際上的filter cache在scroll發(fā)生期間單機(jī)從 500 MB 左右逐漸升高到 6 GB(配置的filter cache最大空間),理論上說(shuō)不通,直接從代碼里找答案。
跟蹤query流程,發(fā)現(xiàn)bool子句中不論是must還是filter,最終被rewrite之后沒(méi)有本質(zhì)上的區(qū)別,判斷是否可以進(jìn)入filter cache的條件是:
段內(nèi)最大文檔數(shù)是否在閾值范圍內(nèi)(Es的filter緩存以段為單位)
查詢出現(xiàn)頻次是否超過(guò)閾值
而在出現(xiàn)頻次這個(gè)部分,Lucene緩存策略還會(huì)有isCostly這樣的判斷,目的是盡量將高消耗的查詢盡可能早的緩存起來(lái),提高查詢性能,符合isCostly判斷的查詢包括 terms 和 range 等查詢,只要重復(fù)出現(xiàn)2次即會(huì)被緩存起來(lái),結(jié)合起來(lái)分析:
terms查詢并不需要scroll查詢,使用普通查詢就能解決需求,使用scroll查詢?cè)黾恿藄erver負(fù)載
range查詢重復(fù)次數(shù)達(dá)到了isCostly閾值,也就是說(shuō)每次遍歷數(shù)據(jù)都會(huì)往filter cache中丟入幾百萬(wàn)的緩存value,而且命中率極低(下次scroll查詢的range起止條件有細(xì)微的變化),加大了server的gc負(fù)擔(dān)
解決:
通過(guò)上面的分析,我們可以看到有兩個(gè)因素的影響導(dǎo)致了server的拒絕響應(yīng):
大量的scroll并發(fā)
不當(dāng)?shù)膔ange請(qǐng)求,具體又可以拆分為:
高頻次,每10秒一次
變化快,每次查詢的起止范圍都有10秒的后延
命中數(shù)大,百萬(wàn)級(jí)別的命中數(shù)
針對(duì)上面的幾點(diǎn)各個(gè)擊破就是我們的解決方案:
scroll請(qǐng)求:
糾正不當(dāng)使用的terms+scroll查詢,使用普通查詢;
推薦使用search_after替換scroll請(qǐng)求,雖然在效率上有所降低,但是有兩個(gè)優(yōu)勢(shì):
可以重試,scroll如果重試可能會(huì)丟失部分?jǐn)?shù)據(jù)
資源占用低,在相同的測(cè)試環(huán)境下,CPU占用率只有10%左右
不當(dāng)?shù)膔ange請(qǐng)求:
高頻次:降低請(qǐng)求頻率,限制到至少1分鐘一次,當(dāng)然不是根本解決方案,推薦將類似的遍歷數(shù)據(jù)請(qǐng)求改到db或者h(yuǎn)base等介質(zhì)
變化快:粗暴點(diǎn)的解決方案是限制時(shí)間單位到小時(shí)級(jí)別,優(yōu)雅點(diǎn)的話:
將時(shí)間條件拆分為粗粒度和細(xì)粒度的組合,粗粒度以若干小時(shí)為單位,細(xì)粒度支撐到分鐘或者秒級(jí)
細(xì)粒度條件使用script方式執(zhí)行,原理是filter cache的frequency是用LinkedHashMap作為key容器的,用來(lái)累積查詢次數(shù),而key的hash計(jì)算,普通query是根據(jù)查詢的條件和值來(lái)作為hash輸入的,而script查詢是使用當(dāng)前實(shí)例的引用,這樣就能避免查詢被累積(因?yàn)槊看蔚膆ashcode都不一樣)
命中數(shù)大:通過(guò)粗細(xì)粒度劃分可以降低成本
以上就是關(guān)于“Es因scroll查詢引起的gc問(wèn)題怎么解決”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
分享題目:Es因scroll查詢引起的gc問(wèn)題怎么解決
文章來(lái)源:http://www.dlmjj.cn/article/ghhiog.html