經典面試題:ES如何做到億級數據查詢毫秒級返回?

2021-02-15 小哈學Java
面試題

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

面試官心理分析

這個問題是肯定要問的,說白了,就是看你有沒有實際幹過 es,因為啥?其實 es 性能並沒有你想像中那麼好的。很多時候數據量大了,特別是有幾億條數據的時候,可能你會懵逼的發現,跑個搜索怎麼一下 5~10s,坑爹了。第一次搜索的時候,是5~10s,後面反而就快了,可能就幾百毫秒。

你就很懵,每個用戶第一次訪問都會比較慢,比較卡麼?所以你要是沒玩兒過 es,或者就是自己玩玩兒 demo,被問到這個問題容易懵逼,顯示出你對 es 確實玩兒的不怎麼樣?

面試題剖析

說實話,es 性能優化是沒有什麼銀彈的,啥意思呢?就是不要期待著隨手調一個參數,就可以萬能的應對所有的性能慢的場景。也許有的場景是你換個參數,或者調整一下語法,就可以搞定,但是絕對不是所有場景都可以這樣。

性能優化的殺手鐧——filesystem cache

你往 es 裡寫的數據,實際上都寫到磁碟文件裡去了,查詢的時候,作業系統會將磁碟文件裡的數據自動緩存到 filesystem cache 裡面去。

es 的搜尋引擎嚴重依賴於底層的 filesystem cache,你如果給 filesystem cache 更多的內存,儘量讓內存可以容納所有的 idx segment file 索引數據文件,那麼你搜索的時候就基本都是走內存的,性能會非常高。

性能差距究竟可以有多大?我們之前很多的測試和壓測,如果走磁碟一般肯定上秒,搜索性能絕對是秒級別的,1秒、5秒、10秒。但如果是走 filesystem cache,是走純內存的,那麼一般來說性能比走磁碟要高一個數量級,基本上就是毫秒級的,從幾毫秒到幾百毫秒不等。

這裡有個真實的案例。某個公司 es 節點有 3 臺機器,每臺機器看起來內存很多,64G,總內存就是 64 * 3 = 192G。每臺機器給 es jvm heap 是 32G,那麼剩下來留給 filesystem cache的就是每臺機器才 32G,總共集群裡給 filesystem cache 的就是 32 * 3 = 96G 內存。而此時,整個磁碟上索引數據文件,在 3 臺機器上一共佔用了 1T 的磁碟容量,es 數據量是 1T,那麼每臺機器的數據量是 300G。這樣性能好嗎?filesystem cache 的內存才 100G,十分之一的數據可以放內存,其他的都在磁碟,然後你執行搜索操作,大部分操作都是走磁碟,性能肯定差。

歸根結底,你要讓 es 性能要好,最佳的情況下,就是你的機器的內存,至少可以容納你的總數據量的一半。

根據我們自己的生產環境實踐經驗,最佳的情況下,是僅僅在 es 中就存少量的數據,就是你要用來搜索的那些索引,如果內存留給 filesystem cache 的是 100G,那麼你就將索引數據控制在 100G 以內,這樣的話,你的數據幾乎全部走內存來搜索,性能非常之高,一般可以在 1 秒以內。

比如說你現在有一行數據。id,name,age .... 30 個欄位。但是你現在搜索,只需要根據 id,name,age 三個欄位來搜索。如果你傻乎乎往 es 裡寫入一行數據所有的欄位,就會導致說 90% 的數據是不用來搜索的,結果硬是佔據了 es 機器上的 filesystem cache 的空間,單條數據的數據量越大,就會導致 filesystem cahce 能緩存的數據就越少。其實,僅僅寫入 es 中要用來檢索的少數幾個欄位就可以了,比如說就寫入 es id,name,age 三個欄位,然後你可以把其他的欄位數據存在 mysql/hbase 裡,我們一般是建議用 es + hbase 這麼一個架構。

hbase 的特點是適用於海量數據的在線存儲,就是對 hbase 可以寫入海量數據,但是不要做複雜的搜索,做很簡單的一些根據 id 或者範圍進行查詢的這麼一個操作就可以了。從 es 中根據 name 和 age 去搜索,拿到的結果可能就 20 個 doc id,然後根據 doc id 到 hbase 裡去查詢每個 doc id 對應的完整的數據,給查出來,再返回給前端。

寫入 es 的數據最好小於等於,或者是略微大於 es 的 filesystem cache 的內存容量。然後你從 es 檢索可能就花費 20ms,然後再根據 es 返回的 id 去 hbase 裡查詢,查 20 條數據,可能也就耗費個 30ms,可能你原來那麼玩兒,1T 數據都放 es,會每次查詢都是 5~10s,現在可能性能就會很高,每次查詢就是 50ms。

數據預熱

假如說,哪怕是你就按照上述的方案去做了,es 集群中每個機器寫入的數據量還是超過了 filesystem cache 一倍,比如說你寫入一臺機器 60G 數據,結果 filesystem cache 就 30G,還是有 30G 數據留在了磁碟上。

其實可以做數據預熱。

舉個例子,拿微博來說,你可以把一些大V,平時看的人很多的數據,你自己提前後臺搞個系統,每隔一會兒,自己的後臺系統去搜索一下熱數據,刷到 filesystem cache 裡去,後面用戶實際上來看這個熱數據的時候,他們就是直接從內存裡搜索了,很快。

或者是電商,你可以將平時查看最多的一些商品,比如說 iphone 8,熱數據提前後臺搞個程序,每隔 1 分鐘自己主動訪問一次,刷到 filesystem cache 裡去。

對於那些你覺得比較熱的、經常會有人訪問的數據,最好做一個專門的緩存預熱子系統,就是對熱數據每隔一段時間,就提前訪問一下,讓數據進入 filesystem cache 裡面去。這樣下次別人訪問的時候,性能一定會好很多。

冷熱分離

es 可以做類似於 mysql 的水平拆分,就是說將大量的訪問很少、頻率很低的數據,單獨寫一個索引,然後將訪問很頻繁的熱數據單獨寫一個索引。最好是將冷數據寫入一個索引中,然後熱數據寫入另外一個索引中,這樣可以確保熱數據在被預熱之後,儘量都讓他們留在 filesystem os cache 裡,別讓冷數據給衝刷掉。

你看,假設你有 6 臺機器,2 個索引,一個放冷數據,一個放熱數據,每個索引 3 個 shard。3 臺機器放熱數據 index,另外 3 臺機器放冷數據 index。然後這樣的話,你大量的時間是在訪問熱數據 index,熱數據可能就佔總數據量的 10%,此時數據量很少,幾乎全都保留在 filesystem cache 裡面了,就可以確保熱數據的訪問性能是很高的。但是對於冷數據而言,是在別的 index 裡的,跟熱數據 index 不在相同的機器上,大家互相之間都沒什麼聯繫了。如果有人訪問冷數據,可能大量數據是在磁碟上的,此時性能差點,就 10% 的人去訪問冷數據,90% 的人在訪問熱數據,也無所謂了。

document 模型設計

對於 MySQL,我們經常有一些複雜的關聯查詢。在 es 裡該怎麼玩兒,es 裡面的複雜的關聯查詢儘量別用,一旦用了性能一般都不太好。

最好是先在 Java 系統裡就完成關聯,將關聯好的數據直接寫入 es 中。搜索的時候,就不需要利用 es 的搜索語法來完成 join 之類的關聯搜索了。

document 模型設計是非常重要的,很多操作,不要在搜索的時候才想去執行各種複雜的亂七八糟的操作。es 能支持的操作就那麼多,不要考慮用 es 做一些它不好操作的事情。如果真的有那種操作,儘量在 document 模型設計的時候,寫入的時候就完成。另外對於一些太複雜的操作,比如 join/nested/parent-child 搜索都要儘量避免,性能都很差的。

分頁性能優化

es 的分頁是較坑的,為啥呢?舉個例子吧,假如你每頁是 10 條數據,你現在要查詢第 100 頁,實際上是會把每個 shard 上存儲的前 1000 條數據都查到一個協調節點上,如果你有個 5 個 shard,那麼就有 5000 條數據,接著協調節點對這 5000 條數據進行一些合併、處理,再獲取到最終第 100 頁的 10 條數據。

分布式的,你要查第 100 頁的 10 條數據,不可能說從 5 個 shard,每個 shard 就查 2 條數據,最後到協調節點合併成 10 條數據吧?你必須得從每個 shard 都查 1000 條數據過來,然後根據你的需求進行排序、篩選等等操作,最後再次分頁,拿到裡面第 100 頁的數據。你翻頁的時候,翻的越深,每個 shard 返回的數據就越多,而且協調節點處理的時間越長,非常坑爹。所以用 es 做分頁的時候,你會發現越翻到後面,就越是慢。

我們之前也是遇到過這個問題,用 es 作分頁,前幾頁就幾十毫秒,翻到 10 頁或者幾十頁的時候,基本上就要 5~10 秒才能查出來一頁數據了。

有什麼解決方案嗎?

不允許深度分頁(默認深度分頁性能很差)

跟產品經理說,你系統不允許翻那麼深的頁,默認翻的越深,性能就越差。

類似於 app 裡的推薦商品不斷下拉出來一頁一頁的

類似於微博中,下拉刷微博,刷出來一頁一頁的,你可以用 scroll api,關於如何使用,自行上網搜索。

scroll 會一次性給你生成所有數據的一個快照,然後每次滑動向後翻頁就是通過遊標 scroll_id移動,獲取下一頁下一頁這樣子,性能會比上面說的那種分頁性能要高很多很多,基本上都是毫秒級的。但是,唯一的一點就是,這個適合於那種類似微博下拉翻頁的,不能隨意跳到任何一頁的場景。也就是說,你不能先進入第 10 頁,然後去第 120 頁,然後又回到第 58 頁,不能隨意亂跳頁。所以現在很多產品,都是不允許你隨意翻頁的,app,也有一些網站,做的就是你只能往下拉,一頁一頁的翻。

初始化時必須指定 scroll 參數,告訴 es 要保存此次搜索的上下文多長時間。你需要確保用戶不會持續不斷翻頁翻幾個小時,否則可能因為超時而失敗。

除了用 scroll api,你也可以用 search_after 來做,search_after 的思想是使用前一頁的結果來幫助檢索下一頁的數據,顯然,這種方式也不允許你隨意翻頁,你只能一頁頁往後翻。初始化時,需要使用一個唯一值的欄位作為 sort 欄位。

相關焦點

  • JAVA 經典面試題:ES如何做到億級數據查詢毫秒級返回?
    面試題,做到毫秒級數據查詢呢?從 elasticsearch 中根據 name 和 age 去搜索,拿到的結果可能就 20 個 doc id,然後根據 doc id 到 hbase 裡去查詢每個 doc id 對應的完整的數據,給查出來,再返回給前端。寫入 elasticsearch 的數據最好小於等於或者是略微大於 es 的 filesystem cache 的內存容量。
  • 睿帆科技:千億級數據毫秒響應的雪球資料庫
    此時,一款針對海量數據進行毫秒級在線即席查詢分析的資料庫就顯得尤其關鍵——它甚至決定了企業是否能以比競爭對手更低的成本、更快的速度解決問題,構建起核心競爭力。滿足大數據量查詢的穩、準、快過去十年,業內一直推崇的分布式計算平臺是Apache基金會旗下的Hadoop。
  • 千億級數據毫秒響應,為什麼它最有機會幹掉傳統數據存儲模式?
    但數據的價值就在於其時效性,越早分析越能得到快速準確的反饋或響應,並及時利用結論指導後續的業務工作。此時,一款針對海量數據進行毫秒級在線即席查詢分析的資料庫就顯得尤其關鍵——它甚至決定了企業是否能以比競爭對手更低的成本、更快的速度解決問題,構建起核心競爭力。
  • 面試官是怎麼來考察你對ES搜尋引擎的理解?
    面試官心理分析問這個,其實面試官就是要看看你了解不了解 es 的一些基本原理,因為用 es 無非就是寫入數據,搜索數據。你要是不明白你發起一個寫入和搜索請求的時候,es 在幹什麼,那你真的是......對 es 基本就是個黑盒,你還能幹啥?你唯一能幹的就是用 es 的 api 讀寫數據了。
  • 優先級隊列(頭條面試題)
    算法面試題優先級隊列,不同於先進先出隊列,其對每一個元素指定了優先級,一般情況下,出隊時,優先級越高的元素越先出隊。其中enqueue(val,prior)第一個參數val為值,第二個參數prior為優先級(prior越大,優先級越高),優先級越高越先出隊dequeue()出隊操作,每調用一次從隊列中找到一個優先級最高的元素出隊,並返回此元素的值(val)要求:在O(logn)時間複雜度內完成兩種操作思考三分鐘再往下看效果更佳哦。。。
  • 快手大數據崗位招聘面試題分享
    快手面試題學長1快手:視頻面試1)一面:50分鐘(1)介紹項目(2)Flink為什麼用aggregate()不用process()(3)自定義UDF,UDTF實現步驟,有哪些方法?(4)Flume丟不丟數據?PUT,TAKE事務(5)SQL題:1. id department salary manager_id 找出員工薪水比領導薪水高的人員(單表join) 2. student course score 找出哪些學生課程比平均課程成績高?
  • VBA程序中,利用API函數讓程序達到毫秒級的延時
    大家好,我們今日繼續講解VBA代碼解決方案的第82講內容:如何利用代碼讓程序延時,SLEEP函數和timeGetTime函數兩個API函數的講解。第1行代碼Sleep API函數聲明,參數dwMilliseconds為以毫秒為單位的時間長度。在第6行到第9行代碼在每次循環時增加顯示的數據,並且在每次增加時使用Sleep語句延時200毫秒,好像字符逐個輸入,從而達到模擬打字的效果.
  • 2021-Java後端工程師面試指南-(Elasticsearch)
    近實時近實時,兩個意思,從寫入數據到數據可以被搜索到有一個小延遲(大概1秒);基於es執行搜索和分析可以達到秒級。tooktook告訴我們整個搜索請求花費的毫秒數。shards_shards節點告訴我們參與查詢的分片數(total欄位),有多少是成功的(successful欄位),有多少的是失敗的(failed欄位)。通常我們不希望分片失敗,不過這個有可能發生。如果我們遭受一些重大的故障導致主分片和複製分片都故障,那這個分片的數據將無法響應給搜索請求。
  • 解析 BAT 大廠的經典面試題(中篇)
    分享給大家的是 「工具 模塊」- 解析BAT面試題(中篇)。很多人對 BAT 以及其他大廠,也是朝思暮想。也因為一些原因,暫時還未能加入。大廠中有很多經典面試題,直到現在也會用,不要問小編為什麼知道(保密)。
  • hibernate面試題
    * hibernate 面試題小集1.hibernate面試題及答案1.在資料庫中條件查詢速度很慢的時候,如何優化?1.建索引2.減少表之間的關聯3.優化sql,儘量讓sql很快定位數據,不要讓sql做全表查詢,應該走索引,把數據量大的表排在前面4.簡化查詢欄位,沒用的欄位不要,已經對返回結果的控制,儘量返回少量數據2.在hibernate中進行多表查詢,每個表中各取幾個欄位,也就是說查詢出來的結果集並沒有一個實體類與之對應,如何解決這個問題?
  • 面試常問題目:在千萬級的資料庫查詢中,如何提高效率?
    今天主要是和大家分享一下,如何進行資料庫查詢的優化。廢話不多說,直接開始咯。在千萬級的資料庫查詢中,如何提高效率?我覺得要弄清楚這個問題,我們應該從兩方面入手。並不是所有索引對查詢都有效,SQL 是根據表中數據來進行查詢優化的,當索引列有大量數據重複時,查詢可能不會去利用索引,如一表中有欄位 sex,male、female 幾乎各一半,那麼即使在 sex 上建了索引也對查詢效率起不了作用。d.
  • 萬億數據下的多維實時分析系統,如何做到亞秒級響應
    2.實時數據分析平臺的話,事業群內部提供了準實時數據查詢的功能,底層技術用的是Kudu+Impala,Impala雖然是MPP架構的大數據計算引擎,並且訪問以列式存儲數據的Kudu。但是對於實時數據分析場景來說,查詢響應的速度和數據的延遲都還是比較高,查詢一次實時DAU,返回結果耗時至少幾分鐘,無法提供良好的交互式用戶體驗。
  • 面試前必看Java線程面試題
    下面是Java線程相關的熱門面試題,你可以用它來好好準備面試。1.面向對象的特徵有哪些方面?答:面向對象的特徵主要有以下幾個方面:- 抽象:抽象是將一類對象的共同特徵總結出來構造類的過程,包括數據抽象和行為抽象兩方面。
  • 數據分析師面試最常見的十道面試題分享!
    以下是容大教育小編日常整理的數據分析師面試時經常遇到的十道數據分析面試題,下面讓我們一起看看數據分析師面試最常見的十道面試題:1、海量日誌數據,提取出某日訪問百度次數最多的那個IP首先是這一天,並且是訪問百度的日誌中的IP取出來,逐個寫入到一個大文件中。
  • ElasticSearch 億級數據檢索案例實戰!
    改進版本目標:數據能跨月查詢,並且支持1年以上的歷史數據查詢與導出。按條件的數據查詢秒級返回。四、優化案例在我們的案例中,查詢欄位都是固定的,不提供全文檢索功能,這也是幾十億數據能秒級返回的一個大前提:ES僅提供欄位的檢索,僅存儲HBase的Rowkey不存儲實際數據。
  • 第四範式推出業界首個基於持久內存、支持毫秒級恢復的萬億維線上...
    為進一步滿足企業線上預估需求,第四範式定製開發了基於持久內存技術、支持實時恢復的萬億維線上預估系統,為企業提供高可用性、毫秒級恢復的在線預估服務,同時將企業總擁有成本降低80%。該系統基於第四範式AI算力平臺SageOne的持久內存進行了軟硬一體設計,與其他預估系統相比,可實現每秒億級KV查詢的高性能,並能夠與第四範式自研的高維機器學習框架以及TensorFlow等AI開源框架無縫對接。保證了在線預估服務無論在發生物理故障或者程序崩潰的情況下,均具備毫秒級故障實時恢復特性,是企業低成本實現高可用AI線上預估服務的最佳選擇。
  • 直擊資料庫面試題:資料庫查詢語句
    方法二: select top 10 * from A where ID not In (select top 30 ID from A order by ID) order by ID 資料庫面試題
  • 百億級實時查詢優化實戰
    【51CTO.com原創稿件】最近的一個項目是風控過程數據實時統計分析和聚合的一個 OLAP 分析監控平臺,日流量峰值在 10 到 12 億上下,每年數據約 4000 億條,佔用空間大概 200T。面對這樣一個數據量級的需求,我們的數據如何存儲和實現實時查詢將是一個嚴峻的挑戰。
  • 後端接口訪問數據查詢如何提高性能?從MySQL、ES、HBASE等技術出發...
    1.1 索引在數據量不是很大時,大多慢查詢可以用索引解決,大多慢查詢也因為索引不合理而產生。MySQL 索引基於 B+ 樹,這句話相信面試都背爛了,接著就可以問最左前綴索引、 B+ 樹和各種樹了。1.6 大表場景在未二次開發的 MYSQL 中,上億的表肯定算大表,這種情況即使在索引、查詢層面做到了較好實現,面對頻繁聚合操作也可能會出現 IO 或 CPU 瓶頸,即使是單純查詢,效率也會下降。
  • 四六級成績可用支付寶查分啦 四六級和雅思如何換算
    四六級成績可用支付寶查分啦 四六級和雅思如何換算由廣東研究生考試網考試快訊欄目由提供,更多關於四六級成績,四六級和雅思如何換算,廣東研究生考試快訊的內容,請關注廣東研究生考試頻道/廣東人事考試網!