偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

面試陷阱:數(shù)十億級(jí)別數(shù)據(jù)下,如何提高ES查詢效率?

新聞
如果面試的時(shí)候碰到這樣一個(gè)面試題:ES在數(shù)據(jù)量很大的情況下(數(shù)十億級(jí)別)如何提高查詢效率?這個(gè)問(wèn)題是肯定要問(wèn)的,說(shuō)白了,就是看你有沒有實(shí)際干過(guò)ES,因?yàn)樯?

如果面試的時(shí)候碰到這樣一個(gè)面試題:ES在數(shù)據(jù)量很大的情況下(數(shù)十億級(jí)別)如何提高查詢效率?

面試官心理分析

這個(gè)問(wèn)題是肯定要問(wèn)的,說(shuō)白了,就是看你有沒有實(shí)際干過(guò)ES,因?yàn)樯?

其實(shí)ES性能并沒有你想象中那么好的。很多時(shí)候數(shù)據(jù)量大了,特別是有幾億條數(shù)據(jù)的時(shí)候,可能你會(huì)懵逼的發(fā)現(xiàn),跑個(gè)搜索怎么一下 5~10s,坑爹了。

***次搜索的時(shí)候,是5~10s,后面反而就快了,可能就幾百毫秒。

你就很懵,每個(gè)用戶***次訪問(wèn)都會(huì)比較慢,比較卡么?所以你要是沒玩兒過(guò)ES,或者就是自己玩玩兒demo,被問(wèn)到這個(gè)問(wèn)題容易懵逼,顯示出你對(duì)ES確實(shí)玩兒的不怎么樣?

面試題剖析

說(shuō)實(shí)話,ES性能優(yōu)化是沒有什么銀彈的。

啥意思呢?

就是不要期待著隨手調(diào)一個(gè)參數(shù),就可以***的應(yīng)對(duì)所有的性能慢的場(chǎng)景。也許有的場(chǎng)景是你換個(gè)參數(shù),或者調(diào)整一下語(yǔ)法,就可以搞定,但是絕對(duì)不是所有場(chǎng)景都可以這樣。

一、性能優(yōu)化的殺手锏:filesystem cache

你往ES里寫的數(shù)據(jù),實(shí)際上都寫到磁盤文件里去了,查詢的時(shí)候,操作系統(tǒng)會(huì)將磁盤文件里的數(shù)據(jù)自動(dòng)緩存到filesystem cache里面去。

面試陷阱:數(shù)十億級(jí)別數(shù)據(jù)下,如何提高ES查詢效率?

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

性能差距究竟可以有多大?

我們之前很多的測(cè)試和壓測(cè),如果走磁盤一般肯定上秒,搜索性能絕對(duì)是秒級(jí)別的,1秒、5秒、10秒。但如果是走filesystem cache,是走純內(nèi)存的,那么一般來(lái)說(shuō)性能比走磁盤要高一個(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è)磁盤上索引數(shù)據(jù)文件,在3臺(tái)機(jī)器上一共占用了1T的磁盤容量,ES數(shù)據(jù)量是1T,那么每臺(tái)機(jī)器的數(shù)據(jù)量是300G。這樣性能好嗎?

filesystem cache的內(nèi)存才100G,十分之一的數(shù)據(jù)可以放內(nèi)存,其他的都在磁盤,然后你執(zhí)行搜索操作,大部分操作都是走磁盤,性能肯定差。

歸根結(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里寫入一行數(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í),僅僅寫入ES中要用來(lái)檢索的少數(shù)幾個(gè)字段就可以了,比如說(shuō)就寫入es id,name,age三個(gè)字段,然后你可以把其他的字段數(shù)據(jù)存在MySQL/HBase里,我們一般是建議用ES + HBase這么一個(gè)架構(gòu)。

HBase的特點(diǎn)是適用于海量數(shù)據(jù)的在線存儲(chǔ),就是對(duì)HBase可以寫入海量數(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),再返回給前端。

寫入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~10s,現(xiàn)在可能性能就會(huì)很高,每次查詢就是50ms。

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

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

其實(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ì)于那些你覺得比較熱的、經(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ú)寫一個(gè)索引,然后將訪問(wèn)很頻繁的熱數(shù)據(jù)單獨(dú)寫一個(gè)索引。***是將冷數(shù)據(jù)寫入一個(gè)索引中,然后熱數(shù)據(jù)寫入另外一個(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ī)器上,大家互相之間都沒什么聯(lián)系了。

如果有人訪問(wèn)冷數(shù)據(jù),可能大量數(shù)據(jù)是在磁盤上的,此時(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ù)直接寫入ES中。搜索的時(shí)候,就不需要利用ES的搜索語(yǔ)法來(lái)完成join之類的關(guān)聯(lián)搜索了。

document模型設(shè)計(jì)是非常重要的,很多操作,不要在搜索的時(shí)候才想去執(zhí)行各種復(fù)雜的亂七八糟的操作。

ES能支持的操作就那么多,不要考慮用ES做一些它不好操作的事情。如果真的有那種操作,盡量在document模型設(shè)計(jì)的時(shí)候,寫入的時(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)上,如果你有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),非??拥K杂肊S做分頁(yè)的時(shí)候,你會(huì)發(fā)現(xiàn)越翻到后面,就越是慢。

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

有什么解決方案嗎?

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

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

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

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

scroll會(huì)一次性給你生成所有數(shù)據(jù)的一個(gè)快照,然后每次滑動(dòng)向后翻頁(yè)就是通過(guò)游標(biāo)scroll_id移動(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è)的翻。

初始化時(shí)必須指定scroll參數(shù),告訴ES要保存此次搜索的上下文多長(zhǎng)時(shí)間。你需要確保用戶不會(huì)持續(xù)不斷翻頁(yè)翻幾個(gè)小時(shí),否則可能因?yàn)槌瑫r(shí)而失敗。

除了用scroll api,你也可以用search_after來(lái)做。search_after的思想是使用前一頁(yè)的結(jié)果來(lái)幫助檢索下一頁(yè)的數(shù)據(jù),顯然,這種方式也不允許你隨意翻頁(yè),你只能一頁(yè)頁(yè)往后翻。初始化時(shí),需要使用一個(gè)唯一值的字段作為sort 字段。

責(zé)任編輯:未麗燕 來(lái)源: 知乎專欄
相關(guān)推薦

2019-05-28 09:31:05

Elasticsear億級(jí)數(shù)據(jù)ES

2022-09-30 19:32:36

ES面試查詢

2013-01-22 17:33:30

2020-02-14 09:40:14

人工智能機(jī)器學(xué)習(xí)技術(shù)

2022-11-23 14:08:49

2024-01-18 17:39:00

數(shù)據(jù)庫(kù)存儲(chǔ)索引

2010-04-07 17:45:22

Oracle位圖索引

2020-09-17 11:02:40

BLESA藍(lán)牙攻擊漏洞

2020-09-01 17:19:36

數(shù)據(jù)監(jiān)控建模

2021-12-17 11:29:03

WiFi漏洞芯片

2020-05-20 12:52:03

漏洞攻擊藍(lán)牙

2020-06-22 10:06:15

數(shù)據(jù)網(wǎng)絡(luò)泄露

2014-10-09 10:07:26

Tmux終端效率

2022-03-30 18:39:51

TiDBHTAPCDP

2019-11-27 09:48:04

數(shù)據(jù)ESHBase

2010-11-15 16:46:49

Oracle查詢效率

2023-12-07 07:46:21

MySQL寫入點(diǎn)LSN

2020-09-09 11:23:22

數(shù)據(jù)科學(xué)與分析

2014-02-26 09:11:00

IBM云計(jì)算BlueMix Paa

2015-11-04 12:23:56

ICT服務(wù)華為
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)