es 在數(shù)據(jù)量很大的情況下(數(shù)十億級(jí)別)如何提高查詢效率啊哄芜?

面試題

es 在數(shù)據(jù)量很大的情況下(數(shù)十億級(jí)別)如何提高查詢效率懊餐ぁ?

面試官心理分析

這個(gè)問(wèn)題是肯定要問(wèn)的认臊,說(shuō)白了圃庭,就是看你有沒(méi)有實(shí)際干過(guò) es,因?yàn)樯妒纾科鋵?shí) es 性能并沒(méi)有你想象中那么好的剧腻。很多時(shí)候數(shù)據(jù)量大了,特別是有幾億條數(shù)據(jù)的時(shí)候涂屁,可能你會(huì)懵逼的發(fā)現(xiàn)书在,跑個(gè)搜索怎么一下 5~10s,坑爹了拆又。第一次搜索的時(shí)候儒旬,是 5~10s,后面反而就快了帖族,可能就幾百毫秒义矛。

你就很懵,每個(gè)用戶第一次訪問(wèn)都會(huì)比較慢盟萨,比較卡么?所以你要是沒(méi)玩兒過(guò) es了讨,或者就是自己玩玩兒 demo捻激,被問(wèn)到這個(gè)問(wèn)題容易懵逼制轰,顯示出你對(duì) es 確實(shí)玩兒的不怎么樣?

面試題剖析

說(shuō)實(shí)話胞谭,es 性能優(yōu)化是沒(méi)有什么銀彈的垃杖,啥意思呢?就是不要期待著隨手調(diào)一個(gè)參數(shù)丈屹,就可以萬(wàn)能的應(yīng)對(duì)所有的性能慢的場(chǎng)景调俘。也許有的場(chǎng)景是你換個(gè)參數(shù),或者調(diào)整一下語(yǔ)法旺垒,就可以搞定彩库,但是絕對(duì)不是所有場(chǎng)景都可以這樣。

性能優(yōu)化的殺手锏——filesystem cache

你往es里寫(xiě)的數(shù)據(jù)先蒋,實(shí)際上都寫(xiě)到磁盤(pán)文件里去了骇钦,查詢的時(shí)候,操作系統(tǒng)會(huì)將磁盤(pán)文件里的數(shù)據(jù)自動(dòng)緩存到 filesystem cache 里面去竞漾。

es-search-process

es 的搜索引擎嚴(yán)重依賴于底層的 filesystem cache眯搭,你如果給 filesystem cache 更多的內(nèi)存,盡量讓內(nèi)存可以容納所有的 idx segment file 索引數(shù)據(jù)文件业岁,那么你搜索的時(shí)候就基本都是走內(nèi)存的鳞仙,性能會(huì)非常高。

性能差距究竟可以有多大笔时?我們之前很多的測(cè)試和壓測(cè)棍好,如果走磁盤(pán)一般肯定上秒,搜索性能絕對(duì)是秒級(jí)別的糊闽,1秒梳玫、5秒、10秒右犹。但如果是走 filesystem cache提澎,是走純內(nèi)存的,那么一般來(lái)說(shuō)性能比走磁盤(pán)要高一個(gè)數(shù)量級(jí)念链,基本上就是毫秒級(jí)的盼忌,從幾毫秒到幾百毫秒不等。

這里有個(gè)真實(shí)的案例掂墓。某個(gè)公司 es 節(jié)點(diǎn)有 3 臺(tái)機(jī)器谦纱,每臺(tái)機(jī)器看起來(lái)內(nèi)存很多,64G君编,總內(nèi)存就是 64 * 3 = 192G跨嘉。每臺(tái)機(jī)器給 es jvm heap 是 32G,那么剩下來(lái)留給 filesystem cache 的就是每臺(tái)機(jī)器才 32G吃嘿,總共集群里給 filesystem cache 的就是 32 * 3 = 96G 內(nèi)存祠乃。而此時(shí)梦重,整個(gè)磁盤(pán)上索引數(shù)據(jù)文件,在 3 臺(tái)機(jī)器上一共占用了 1T 的磁盤(pán)容量亮瓷,es 數(shù)據(jù)量是 1T琴拧,那么每臺(tái)機(jī)器的數(shù)據(jù)量是 300G。這樣性能好嗎嘱支? filesystem cache 的內(nèi)存才 100G蚓胸,十分之一的數(shù)據(jù)可以放內(nèi)存,其他的都在磁盤(pán)除师,然后你執(zhí)行搜索操作沛膳,大部分操作都是走磁盤(pán),性能肯定差馍盟。

歸根結(jié)底于置,你要讓 es 性能要好,最佳的情況下贞岭,就是你的機(jī)器的內(nèi)存惫叛,至少可以容納你的總數(shù)據(jù)量的一半锰扶。

根據(jù)我們自己的生產(chǎn)環(huán)境實(shí)踐經(jīng)驗(yàn)鳖轰,最佳的情況下洒宝,是僅僅在 es 中就存少量的數(shù)據(jù),就是你要用來(lái)搜索的那些索引芯侥,如果內(nèi)存留給 filesystem cache 的是 100G泊交,那么你就將索引數(shù)據(jù)控制在 100G 以內(nèi),這樣的話柱查,你的數(shù)據(jù)幾乎全部走內(nèi)存來(lái)搜索廓俭,性能非常之高,一般可以在 1 秒以內(nèi)唉工。

比如說(shuō)你現(xiàn)在有一行數(shù)據(jù)研乒。id,name,age .... 30 個(gè)字段。但是你現(xiàn)在搜索淋硝,只需要根據(jù) id,name,age 三個(gè)字段來(lái)搜索雹熬。如果你傻乎乎往 es 里寫(xiě)入一行數(shù)據(jù)所有的字段,就會(huì)導(dǎo)致說(shuō) 90% 的數(shù)據(jù)是不用來(lái)搜索的谣膳,結(jié)果硬是占據(jù)了 es 機(jī)器上的 filesystem cache 的空間竿报,單條數(shù)據(jù)的數(shù)據(jù)量越大,就會(huì)導(dǎo)致 filesystem cahce 能緩存的數(shù)據(jù)就越少继谚。其實(shí)烈菌,僅僅寫(xiě)入 es 中要用來(lái)檢索的少數(shù)幾個(gè)字段就可以了,比如說(shuō)就寫(xiě)入es id,name,age 三個(gè)字段,然后你可以把其他的字段數(shù)據(jù)存在 mysql/hbase 里僧界,我們一般是建議用 es + hbase 這么一個(gè)架構(gòu)侨嘀。

hbase 的特點(diǎn)是適用于海量數(shù)據(jù)的在線存儲(chǔ),就是對(duì) hbase 可以寫(xiě)入海量數(shù)據(jù)捂襟,但是不要做復(fù)雜的搜索,做很簡(jiǎn)單的一些根據(jù) id 或者范圍進(jìn)行查詢的這么一個(gè)操作就可以了欢峰。從 es 中根據(jù) name 和 age 去搜索葬荷,拿到的結(jié)果可能就 20 個(gè) doc id,然后根據(jù) doc id 到 hbase 里去查詢每個(gè) doc id 對(duì)應(yīng)的完整的數(shù)據(jù)纽帖,給查出來(lái)宠漩,再返回給前端。

寫(xiě)入 es 的數(shù)據(jù)最好小于等于懊直,或者是略微大于 es 的 filesystem cache 的內(nèi)存容量扒吁。然后你從 es 檢索可能就花費(fèi) 20ms,然后再根據(jù) es 返回的 id 去 hbase 里查詢室囊,查 20 條數(shù)據(jù)雕崩,可能也就耗費(fèi)個(gè) 30ms,可能你原來(lái)那么玩兒融撞,1T 數(shù)據(jù)都放es盼铁,會(huì)每次查詢都是 5~10秒,現(xiàn)在可能性能就會(huì)很高尝偎,每次查詢就是 50ms饶火。

數(shù)據(jù)預(yù)熱

假如說(shuō),哪怕是你就按照上述的方案去做了致扯,es 集群中每個(gè)機(jī)器寫(xiě)入的數(shù)據(jù)量還是超過(guò)了 filesystem cache 一倍肤寝,比如說(shuō)你寫(xiě)入一臺(tái)機(jī)器 60G 數(shù)據(jù),結(jié)果 filesystem cache 就 30G抖僵,還是有 30G 數(shù)據(jù)留在了磁盤(pán)上鲤看。

其實(shí)可以做數(shù)據(jù)預(yù)熱

舉個(gè)例子裆针,拿微博來(lái)說(shuō)刨摩,你可以把一些大V,平時(shí)看的人很多的數(shù)據(jù)世吨,你自己提前后臺(tái)搞個(gè)系統(tǒng)澡刹,每隔一會(huì)兒,自己的后臺(tái)系統(tǒng)去搜索一下熱數(shù)據(jù)耘婚,刷到 filesystem cache 里去罢浇,后面用戶實(shí)際上來(lái)看這個(gè)熱數(shù)據(jù)的時(shí)候,他們就是直接從內(nèi)存里搜索了,很快嚷闭。

或者是電商攒岛,你可以將平時(shí)查看最多的一些商品,比如說(shuō) iphone 8胞锰,熱數(shù)據(jù)提前后臺(tái)搞個(gè)程序灾锯,每隔 1 分鐘自己主動(dòng)訪問(wèn)一次,刷到 filesystem cache 里去嗅榕。

對(duì)于那些你覺(jué)得比較熱的顺饮,經(jīng)常會(huì)有人訪問(wèn)的數(shù)據(jù),最好做一個(gè)專門的緩存預(yù)熱子系統(tǒng)凌那,就是對(duì)熱數(shù)據(jù)每隔一段時(shí)間兼雄,就提前訪問(wèn)一下,讓數(shù)據(jù)進(jìn)入 filesystem cache 里面去帽蝶。這樣下次別人訪問(wèn)的時(shí)候赦肋,一定性能會(huì)好一些。

冷熱分離

es 可以做類似于 mysql 的水平拆分励稳,就是說(shuō)將大量的訪問(wèn)很少佃乘、頻率很低的數(shù)據(jù),單獨(dú)寫(xiě)一個(gè)索引麦锯,然后將訪問(wèn)很頻繁的熱數(shù)據(jù)單獨(dú)寫(xiě)一個(gè)索引恕稠。最好是將冷數(shù)據(jù)寫(xiě)入一個(gè)索引中,然后熱數(shù)據(jù)寫(xiě)入另外一個(gè)索引中扶欣,這樣可以確保熱數(shù)據(jù)在被預(yù)熱之后鹅巍,盡量都讓他們留在 filesystem os cache 里,別讓冷數(shù)據(jù)給沖刷掉料祠。

你看骆捧,假設(shè)你有 6 臺(tái)機(jī)器,2 個(gè)索引髓绽,一個(gè)放冷數(shù)據(jù)敛苇,一個(gè)放熱數(shù)據(jù),每個(gè)索引 3 個(gè)shard顺呕。3 臺(tái)機(jī)器放熱數(shù)據(jù) index枫攀;另外 3 臺(tái)機(jī)器放冷數(shù)據(jù) index。然后這樣的話株茶,你大量的時(shí)候是在訪問(wèn)熱數(shù)據(jù) index来涨,熱數(shù)據(jù)可能就占總數(shù)據(jù)量的 10%,此時(shí)數(shù)據(jù)量很少启盛,幾乎全都保留在 filesystem cache 里面了蹦掐,就可以確保熱數(shù)據(jù)的訪問(wèn)性能是很高的技羔。但是對(duì)于冷數(shù)據(jù)而言,是在別的 index 里的卧抗,跟熱數(shù)據(jù) index 不在相同的機(jī)器上藤滥,大家互相之間都沒(méi)什么聯(lián)系了。如果有人訪問(wèn)冷數(shù)據(jù)社裆,可能大量數(shù)據(jù)是在磁盤(pán)上的拙绊,此時(shí)性能差點(diǎn),就 10% 的人去訪問(wèn)冷數(shù)據(jù)浦马,90% 的人在訪問(wèn)熱數(shù)據(jù)时呀,也無(wú)所謂了。

document 模型設(shè)計(jì)

對(duì)于 MySQL晶默,我們經(jīng)常有一些復(fù)雜的關(guān)聯(lián)查詢。在 es 里該怎么玩兒航攒,es 里面的復(fù)雜的關(guān)聯(lián)查詢盡量別用磺陡,一旦用了性能一般都不太好。

最好是先在 Java 系統(tǒng)里就完成關(guān)聯(lián)漠畜,將關(guān)聯(lián)好的數(shù)據(jù)直接寫(xiě)入 es 中币他。搜索的時(shí)候,就不需要利用 es 的搜索語(yǔ)法來(lái)完成 join 之類的關(guān)聯(lián)搜索了憔狞。

document 模型設(shè)計(jì)是非常重要的蝴悉,很多操作,不要在搜索的時(shí)候才想去執(zhí)行各種復(fù)雜的亂七八糟的操作瘾敢。es 能支持的操作就是那么多拍冠,不要考慮用 es 做一些它不好操作的事情。如果真的有那種操作簇抵,盡量在 document 模型設(shè)計(jì)的時(shí)候庆杜,寫(xiě)入的時(shí)候就完成。另外對(duì)于一些太復(fù)雜的操作碟摆,比如 join/nested/parent-child 搜索都要盡量避免晃财,性能都很差的。

分頁(yè)性能優(yōu)化

es 的分頁(yè)是較坑的典蜕,為啥呢断盛?舉個(gè)例子吧,假如你每頁(yè)是 10 條數(shù)據(jù)愉舔,你現(xiàn)在要查詢第 100 頁(yè)钢猛,實(shí)際上是會(huì)把每個(gè) shard 上存儲(chǔ)的前 1000 條數(shù)據(jù)都查到一個(gè)協(xié)調(diào)節(jié)點(diǎn)上,如果你有個(gè) 5 個(gè)shard屑宠,那么就有 5000 條數(shù)據(jù)厢洞,接著協(xié)調(diào)節(jié)點(diǎn)對(duì)這 5000 條數(shù)據(jù)進(jìn)行一些合并、處理,再獲取到最終第 100 頁(yè)的 10 條數(shù)據(jù)躺翻。

分布式的丧叽,你要查第100頁(yè)的10條數(shù)據(jù),不可能說(shuō)從5個(gè) shard公你,每個(gè) shard 就查 2 條數(shù)據(jù)踊淳?最后到協(xié)調(diào)節(jié)點(diǎn)合并成 10 條數(shù)據(jù)?你必須得從每個(gè) shard 都查 1000 條數(shù)據(jù)過(guò)來(lái)陕靠,然后根據(jù)你的需求進(jìn)行排序迂尝、篩選等等操作,最后再次分頁(yè)剪芥,拿到里面第 100 頁(yè)的數(shù)據(jù)垄开。你翻頁(yè)的時(shí)候,翻的越深税肪,每個(gè) shard 返回的數(shù)據(jù)就越多溉躲,而且協(xié)調(diào)節(jié)點(diǎn)處理的時(shí)間越長(zhǎng)。非骋嫘郑坑爹锻梳。所以用 es 做分頁(yè)的時(shí)候,你會(huì)發(fā)現(xiàn)越翻到后面净捅,就越是慢疑枯。

我們之前也是遇到過(guò)這個(gè)問(wèn)題,用 es 作分頁(yè)蛔六,前幾頁(yè)就幾十毫秒荆永,翻到 10 頁(yè) or 幾十頁(yè)的時(shí)候,基本上就要 5~10秒 才能查出來(lái)一頁(yè)數(shù)據(jù)了古今。

有什么解決方案嗎屁魏?

不允許深度分頁(yè)/默認(rèn)深度分頁(yè)性能很慘

你系統(tǒng)不允許翻那么深的頁(yè),跟產(chǎn)品經(jīng)理說(shuō)捉腥,默認(rèn)翻的越深氓拼,性能就越差。

類似于 app 里的推薦商品不斷下拉出來(lái)一頁(yè)一頁(yè)的

類似于微博中抵碟,下拉刷微博桃漾,刷出來(lái)一頁(yè)一頁(yè)的,你可以用 scroll api拟逮,關(guān)于如何使用撬统,自行上網(wǎng)搜索。

scroll 會(huì)一次性給你生成所有數(shù)據(jù)的一個(gè)快照敦迄,然后每次翻頁(yè)就是通過(guò)游標(biāo)移動(dòng)恋追,獲取下一頁(yè)下一頁(yè)這樣子凭迹,性能會(huì)比上面說(shuō)的那種分頁(yè)性能也高很多很多,基本上都是毫秒級(jí)的苦囱。

但是 唯一的一點(diǎn)就是嗅绸,這個(gè)適合于那種類似微博下拉翻頁(yè)的,不能隨意跳到任何一頁(yè)的場(chǎng)景撕彤。也就是說(shuō)鱼鸠,你不能先進(jìn)入第 10 頁(yè),然后去 120 頁(yè)羹铅,然后又回到 58 頁(yè)蚀狰,不能隨意亂跳頁(yè)。所以現(xiàn)在很多產(chǎn)品职员,都是不允許你隨意翻頁(yè)的麻蹋,app,也有一些網(wǎng)站焊切,做的就是你只能往下拉哥蔚,一頁(yè)一頁(yè)的翻。

另外蛛蒙,這個(gè) scroll 是要保留一段時(shí)間內(nèi)的數(shù)據(jù)快照的,你需要確保用戶不會(huì)持續(xù)不斷翻頁(yè)翻幾個(gè)小時(shí)渤愁。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末牵祟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抖格,更是在濱河造成了極大的恐慌诺苹,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雹拄,死亡現(xiàn)場(chǎng)離奇詭異收奔,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)滓玖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門坪哄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人势篡,你說(shuō)我怎么就攤上這事翩肌。” “怎么了禁悠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵念祭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我碍侦,道長(zhǎng)粱坤,這世上最難降的妖魔是什么隶糕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮站玄,結(jié)果婚禮上枚驻,老公的妹妹穿的比我還像新娘。我一直安慰自己蜒什,他們只是感情好测秸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著灾常,像睡著了一般霎冯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钞瀑,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天沈撞,我揣著相機(jī)與錄音,去河邊找鬼雕什。 笑死缠俺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贷岸。 我是一名探鬼主播壹士,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼偿警!你這毒婦竟也來(lái)了躏救?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤螟蒸,失蹤者是張志新(化名)和其女友劉穎盒使,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體七嫌,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡少办,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诵原。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片英妓。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖皮假,靈堂內(nèi)的尸體忽然破棺而出鞋拟,到底是詐尸還是另有隱情,我是刑警寧澤惹资,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布贺纲,位于F島的核電站,受9級(jí)特大地震影響褪测,放射性物質(zhì)發(fā)生泄漏猴誊。R本人自食惡果不足惜潦刃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望懈叹。 院中可真熱鬧乖杠,春花似錦、人聲如沸澄成。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)墨状。三九已至卫漫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間肾砂,已是汗流浹背列赎。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留镐确,地道東北人包吝。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像源葫,于是被迫代替她去往敵國(guó)和親诗越。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容