騰訊萬億級 Elasticsearch 技術解密
Elasticsearch(ES)作為開源首選的分布式搜索分析引擎,通過一套系統(tǒng)輕松滿足用戶的日志實時分析、全文檢索、結構化數(shù)據(jù)分析等多種需求,大幅降低大數(shù)據(jù)時代挖掘數(shù)據(jù)價值的成本。騰訊在公司內(nèi)部豐富的場景中大規(guī)模使用 ES,同時聯(lián)合 Elastic 公司在騰訊云上提供內(nèi)核增強版的 ES 云服務,大規(guī)模、豐富多樣的的使用場景推動著騰訊對原生 ES 進行持續(xù)的高可用、高性能、低成本優(yōu)化。今天給大家分享近期在 Elastic 中國開發(fā)者大會上的演講內(nèi)容:騰訊萬億級 Elasticsearch 技術解密。
一、ES 在騰訊的應用場景
本次分享的主要內(nèi)容包含:首先介紹 ES 在騰訊的豐富應用場景及各種場景的典型特點;然后給出我們在大規(guī)模、高壓力、豐富多樣的使用場景下遇到的挑戰(zhàn);針對這些挑戰(zhàn),我們重點介紹騰訊在 ES 內(nèi)核方面進行的高可用性、低成本、高性能等優(yōu)化實踐;最后簡單分享我們在 ES 未來規(guī)劃以及開源貢獻方面的思考。
我們先來看下 ES 在騰訊的應用場景。最初我們使用 ES 于日志實時分析場景,典型日志如下:運營日志,比如慢日志、異常日志,用來定位業(yè)務問題;業(yè)務日志,比如用戶的點擊、訪問日志,可以用來分析用戶行為;審計日志,可以用于安全分析。ES 很完美的解決了日志實時分析的需求,它具有如下特點:
- Elastic 生態(tài)提供了完整的日志解決方案,任何一個開發(fā)、運維同學使用成熟組件,通過簡單部署,即可搭建起一個完整的日志實時分析服務。
- 在 Elastic 生態(tài)中,日志從產(chǎn)生到可訪問一般在 10s 級。相比于傳統(tǒng)大數(shù)據(jù)解決方案的幾十分鐘、小時級,時效性非常高。
- 由于支持倒排索引、列存儲等數(shù)據(jù)結構,ES 提供非常靈活的搜索分析能力。
- 支持交互式分析,即使在萬億級日志的情況下,ES 搜索響應時間也是秒級。
日志是互聯(lián)網(wǎng)行業(yè)最基礎、最廣泛的數(shù)據(jù)形式,ES 非常完美的解決了日志實時分析場景,這也是近幾年 ES 快速發(fā)展的一個重要原因。
第二類使用場景是搜索服務,典型場景包含:商品搜索,類似京東、淘寶、拼多多中的商品搜索;APP 搜索,支持應用商店里的應用搜索;站內(nèi)搜索,支持論壇、在線文檔等搜索功能。我們支持了大量搜索服務,它們主要有以下特點:
- 高性能:單個服務最大達到 10w+ QPS,平響 20ms~,P95 延時小于 100ms。
- 強相關:搜索體驗主要取決于搜索結果是否高度匹配用戶意圖,需要通過正確率、召回率等指標進行評估。
- 高可用:搜索場景通常要求 4 個 9 的可用性,支持單機房故障容災。任何一個電商服務,如淘寶、京東、拼多多,只要故障一個小時就可以上頭條。
第三類使用場景是時序數(shù)據(jù)分析,典型的時序數(shù)據(jù)包含:Metrics,即傳統(tǒng)的服務器監(jiān)控;APM,應用性能監(jiān)控;物聯(lián)網(wǎng)數(shù)據(jù),智能硬件、工業(yè)物聯(lián)網(wǎng)等產(chǎn)生的傳感器數(shù)據(jù)。這類場景騰訊很早就開始探索,在這方面積累了非常豐富的經(jīng)驗。這類場景具有以下特點:
- 高并發(fā)寫入:線上單集群最大規(guī)模達到 600+節(jié)點、1000w/s 的寫入吞吐。
- 高查詢性能:要求單條曲線 或者單個時間線的查詢延時在 10ms~。
- 多維分析:要求靈活、多維度的統(tǒng)計分析能力,比如我們在查看監(jiān)控的時候,可以按照地域、業(yè)務模塊等靈活的進行統(tǒng)計分析。
二、遇到的挑戰(zhàn)
前面我們介紹了 ES 在騰訊內(nèi)部的廣泛應用,在如此大規(guī)模、高壓力、豐富使用場景的背景下,我們遇到了很多挑戰(zhàn),總體可以劃分為兩類:搜索類和時序類。
首先,我們一起看看搜索類業(yè)務的挑戰(zhàn)。以電商搜索、APP 搜索、站內(nèi)搜索為代表,這類業(yè)務非常重視可用性,服務 SLA 達到 4 個 9 以上,需要容忍單機故障、單機房網(wǎng)絡故障等;同時要求高性能、低毛刺,例如 20w QPS、平響 20ms、P95 延時 100ms。總之,在搜索類業(yè)務場景下,核心挑戰(zhàn)點在于高可用、高性能。
另一類我們稱之為時序類業(yè)務挑戰(zhàn),包含日志、Metrics、APM 等場景。相比于搜索類業(yè)務重點關注高可用、高性能,時序類業(yè)務會更注重成本、性能。比如時序場景用戶通常要求高寫入吞吐,部分場景可達 1000w/sWPS;在這樣寫入吞吐下,保留 30 天的數(shù)據(jù),通??蛇_到 PB 級的存儲量。而現(xiàn)實是日志、監(jiān)控等場景的收益相對較低,很可能用戶用于線上實際業(yè)務的機器數(shù)量才是 100 臺,而監(jiān)控、日志等需要 50 臺,這對多數(shù)用戶來說,基本是不可接受的。所以在時序類業(yè)務中,主要的挑戰(zhàn)在于存儲成本、計算成本等方面。
前面我們介紹了在搜索類、時序類業(yè)務場景下遇到的高可用、低成本、高性能等挑戰(zhàn),下面針對這些挑戰(zhàn),我們重點分享騰訊在 ES 內(nèi)核方面的深入實踐。
三、ES 優(yōu)化實踐
首先,我們來看看高可用優(yōu)化,我們把高可用劃分為三個維度:
- 系統(tǒng)健壯性:是指 ES 內(nèi)核自身的健壯性,也是分布式系統(tǒng)面臨的共性難題。例如,在異常查詢、壓力過載下集群的容錯能力;在高壓力場景下,集群的可擴展性;在集群擴容、節(jié)點異常場景下,節(jié)點、多硬盤之間的數(shù)據(jù)均衡能力。
- 容災方案:如果通過管控系統(tǒng)建設,保障機房網(wǎng)絡故障時快速恢復服務,自然災害下防止數(shù)據(jù)丟失,誤操作后快速恢復等。
- 系統(tǒng)缺陷:這在任何系統(tǒng)發(fā)展過程中都會持續(xù)產(chǎn)生,比如說 Master 節(jié)點堵塞、分布式死鎖、滾動重啟緩慢等。
針對上述問題,下面來介紹我們在高可用方面的解決方案:
系統(tǒng)健壯性方面,我們通過服務限流,容忍機器網(wǎng)絡故障、異常查詢等導致的服務不穩(wěn)定,后面展開介紹。通過優(yōu)化集群元數(shù)據(jù)管控邏輯,提升集群擴展能力一個數(shù)量級,支持千級節(jié)點集群、百萬分片,解決集群可擴展性問題;集群均衡方面,通過優(yōu)化節(jié)點、多硬盤間的分片均衡,保證大規(guī)模集群的壓力均衡。
容災方案方面,我們通過擴展 ES 的插件機制支持備份回檔,把 ES 的數(shù)據(jù)備份回檔到廉價存儲,保證數(shù)據(jù)的可恢復;支持跨可用區(qū)容災,用戶可以按需部署多個可用區(qū),以容忍單機房故障。垃圾桶機制,保證用戶在欠費、誤操作等場景下,集群可快速恢復。
系統(tǒng)缺陷方面,我們修復了滾動重啟、Master 阻塞、分布式死鎖等一系列 Bug。其中滾動重啟優(yōu)化,可加速節(jié)點重啟速度 5+倍,具體可參考 PR ES-46520;Master 堵塞問題,我們在 ES 6.x 版本和官方一起做了優(yōu)化。
這里我們展開介紹下服務限流部分。我們做了 4 個層級的限流工作:權限層級,我們支持 XPack 和自研權限來防止攻擊、誤操作;隊列層級,通過優(yōu)化任務執(zhí)行速度、重復、優(yōu)先級等問題,解決用戶常遇到的 Master 任務隊列堆積、任務餓死等問題;內(nèi)存層級,我們從 ES 6.x 開始,支持在 HTTP 入口、協(xié)調(diào)節(jié)點、數(shù)據(jù)節(jié)點等全鏈路上進行內(nèi)存限流,同時使用 JVM 內(nèi)存、梯度統(tǒng)計等方式精準控制;多租戶層級,我們使用 CVM/Cgroups 方案保證多租戶間的資源隔離。
這里詳細介紹下聚合場景限流問題,用戶在使用 ES 進行聚合分析時,經(jīng)常遇到因聚合分桶過多打爆內(nèi)存的問題。官方在 ES 6.8 中提供 max_buckets 參數(shù)控制聚合的最大分桶數(shù),但這個方式局限性非常強。在某些場景下,用戶設置 20 萬個分桶可以正常工作,但在另一些場景下,可能 10 萬個分桶內(nèi)存就已經(jīng)打爆,這主要取決于單分桶的大小,用戶并不能準確把握該參數(shù)設置為多少比較合適。我們在聚合分析的過程中,采用梯度算法進行優(yōu)化,每分配 1000 個分桶檢查一次 JVM 內(nèi)存,當內(nèi)存不足時及時中斷請求,保證 ES 集群的高可用。具體可參考 PR ES-46751 /47806。
我們當前的限流方案,能夠大幅提升在異常查詢、壓力過載、單節(jié)點故障、網(wǎng)絡分區(qū)等場景下,ES 服務的穩(wěn)定性問題。但還有少量場景沒有覆蓋完全,所以我們目前也在引入混沌測試,依賴混沌測試來覆蓋更多異常場景。
前面我們介紹了高可用解決方案,下面我們來介紹成本方面的優(yōu)化實踐。成本方面的挑戰(zhàn),主要體現(xiàn)在以日志、監(jiān)控為代表的時序場景對機器資源的消耗,我們對線上典型的日志、時序業(yè)務進行分析,總體來看,硬盤、內(nèi)存、計算資源的成本比例接近 8:4:1,硬盤、內(nèi)存是主要矛盾,其次是計算成本。
而對時序類場景進行分析,可以發(fā)現(xiàn)時序數(shù)據(jù)有很明顯的訪問特性。一是冷熱特性,時序數(shù)據(jù)訪問具有近多遠少的特點,最近 7 天數(shù)據(jù)的訪問量占比可達到 95%以上;歷史數(shù)據(jù)訪問較少,且通常都是訪問統(tǒng)計類信息。
基于這些瓶頸分析和數(shù)據(jù)訪問特性,我們來介紹成本優(yōu)化的解決方案。
硬盤成本方面,由于數(shù)據(jù)具有明顯的冷熱特性,首先我們采用冷熱分離架構,使用混合存儲的方案來平衡成本、性能;其次,既然對歷史數(shù)據(jù)通常都是訪問統(tǒng)計信息,那么以通過預計算來換取存儲和性能,后面會展開介紹;如果歷史數(shù)據(jù)完全不使用,也可以備份到更廉價的存儲系統(tǒng);其他一些優(yōu)化方式包含存儲裁剪、生命周期管理等。
內(nèi)存成本方面,很多用戶在使用大存儲機型時會發(fā)現(xiàn),存儲資源才用了百分之二十,內(nèi)存已經(jīng)不足。其實基于時序數(shù)據(jù)的訪問特性,我們可以利用 Cache 進行優(yōu)化,后面會展開介紹。
我們展開介紹下 Rollup 部分。官方從 ES 6.x 開始推出 Rollup,實際上騰訊在 5.x 已經(jīng)開始這部分的實踐。Rollup 類似于大數(shù)據(jù)場景下的 Cube、物化視圖,它的核心思想是通過預計算提前生成統(tǒng)計信息,釋放掉原始粒度數(shù)據(jù),從而降低存儲成本、提高查詢性能,通常會有數(shù)據(jù)級的收益。這里舉個簡單的例子,比如在機器監(jiān)控場景下,原始粒度的監(jiān)控數(shù)據(jù)是 10 秒級的,而一個月之前的監(jiān)控數(shù)據(jù),一般只需要查看小時粒度,這即是一個 Rollup 應用場景。
在大數(shù)據(jù)領域,傳統(tǒng)的方案是依賴外部離線計算系統(tǒng),周期性的讀取全量數(shù)據(jù)進行計算,這種方式計算開銷、維護成本高。谷歌的廣告指標系統(tǒng) Mesa 采用持續(xù)生成方案,數(shù)據(jù)寫入時系統(tǒng)給每個 Rollup 產(chǎn)生一份輸入數(shù)據(jù),并對數(shù)據(jù)進行排序,底層在 Compact/Merge 過程中通過多路歸并完成 Rollup,這種方式的計算、維護成本相對較低。ES 從 6.x 開始支持數(shù)據(jù)排序,我們通過流式查詢進行多路歸并生成 Rollup,最終計算開銷小于全量數(shù)據(jù)寫入時 CPU 開銷的 10%,內(nèi)存使用小于 10MB。我們已反饋內(nèi)核優(yōu)化至開源社區(qū),解決開源 Rollup 的計算、內(nèi)存瓶頸,具體可參考 PR ES-48399。
接下來,我們展開介紹內(nèi)存優(yōu)化部分。前面提到很多用戶在使用大存儲機型時,內(nèi)存優(yōu)先成為瓶頸、硬盤不能充分利用的問題,主要瓶頸在于索引占用大量內(nèi)存。但是我們知道時序類場景對歷史數(shù)據(jù)訪問很少,部分場景下某些字段基本不使用,所我們可以通過引入 Cache 來提高內(nèi)存利用效率。
在內(nèi)存優(yōu)化方面,業(yè)界的方案是什么樣的呢?ES 社區(qū)從 7.x 后支持索引放于堆外,和 DocValue 一樣按需加載。但這種方式不好的地方在于索引和數(shù)據(jù)的重要性完全不同,一個大查詢很容易導致索引被淘汰,后續(xù)查詢性能倍數(shù)級的衰減。Hbase 通過緩存 Cache 緩存索引、數(shù)據(jù)塊,提升熱數(shù)據(jù)訪問性能,并且從 HBase 2.0 開始,重點介紹其 Off Heap 技術,重點在于堆外內(nèi)存的訪問性能可接近堆內(nèi)。我們基于社區(qū)經(jīng)驗進行迭代,在 ES 中引入 LFU Cache 以提高內(nèi)存的利用效率,把 Cache 放置在堆外以降低堆內(nèi)存壓力,同時通過 Weak Reference、減少堆內(nèi)外拷貝等技術降低損耗。最終效果是內(nèi)存利用率提升 80%,可以充分利用大存儲機型,查詢性能損耗不超過 2%,GC 開銷降低 30%。
前面我們介紹了可用性、成本優(yōu)化的解決方案,最后我們來介紹性能方面的優(yōu)化實踐。以日志、監(jiān)控為代表的時序場景,對寫入性能要求非常高,寫入并發(fā)可達 1000w/s。然而我們發(fā)現(xiàn)在帶主鍵寫入時,ES 性能衰減 1+倍,部分壓測場景下,CPU 無法充分利用。以搜索服務為代表的場景,對查詢性的要求非常高,要求 20w QPS, 平響 20ms,而且盡量避免 GC、執(zhí)行計劃不優(yōu)等造成的查詢毛刺。
針對上述問題,我們介紹下騰訊在性能方面的優(yōu)化實踐:
寫入方面,針對主鍵去重場景,通過利用索引進行裁剪,加速主鍵去重的過程,寫入性能提升 45%,具體可參考 PR Lucene-8980。對于部分壓測場景下 CPU 不能充分利用的問題,通過優(yōu)化 ES 刷新 Translog 時的資源搶占,提升性能提升 20%,具體可參考 PR ES-45765 /47790。我們正在嘗試通過向量化執(zhí)行優(yōu)化寫入性能,通過減少分支跳轉(zhuǎn)、指令 Miss,預期寫入性能可提升 1 倍。
查詢方面,我們通過優(yōu)化 Merge 策略,提升查詢性能,這部分稍后展開介紹。基于每個 Segment 記錄的 min/max 索引,進行查詢剪枝,提升查詢性能 30%。通過 CBO 策略,避免查詢 Cache 操作導致查詢耗時 10+倍的毛刺,具體可參考Lucene-9002。此外,我們也在嘗試通過一些新硬件來優(yōu)化性能,比如說英特爾的 AEP、Optane、QAT 等。
接下來我們展開介紹下 Merge 策略優(yōu)化部分。ES 原生的 Merge 策略主要關注大小相似性和最大上限,大小相似性是指 Merge 時盡量選擇大小相似的 Segments 進行 Merge,最大上限則考慮盡量把 Segment 拼湊到 5GB。那么有可能出現(xiàn)某個 Segment 中包含了 1 月整月、3 月 1 號的數(shù)據(jù),當用戶查詢 3 月 1 號某小時的數(shù)據(jù)時,就必須掃描大量無用數(shù)據(jù),性能損耗嚴重。
我們在 ES 中引入了時序 Merge,在選擇 Segments 進行 Merge 時,重點考慮時間因素,這樣時間相近的 Segments 被 Merge 到一起。當我們查詢 3 月 1 號的數(shù)據(jù)時,只需要掃描個別較小的 Segments 就好,其他的 Segments 可以快速裁剪掉。
另外,ES 官方推薦搜索類用戶在寫入完成之后,進行一次 Force Merge,用意是把所有 Segments 合并為一個,以提高搜索性能。但這增加了用戶的使用成本,且在時序場景下,不利于裁剪,需要掃描全部數(shù)據(jù)。我們在 ES 中引入了冷數(shù)據(jù)自動 Merge,對于非活躍的索引,底層 Segments 會自動 Merge 到接近 5GB,降低文件數(shù)量的同時,方便時序場景裁剪。對于搜索場景,用戶可以調(diào)大目標 Segment 的大小,使得所有 Segments 最終 Merge 為一個。我們對 Merge 策略的優(yōu)化,可以使得搜索場景性能提升 1 倍。
前面介紹完畢我們再 ES 內(nèi)核方面的優(yōu)化實踐,最后我們來簡單分享下我們在開源貢獻及未來規(guī)劃方面的思考。
四、未來規(guī)劃及開源貢獻
近半年我們向開源社區(qū)提交了 10+PR,涉及到寫入、查詢、集群管理等各個模塊,部分優(yōu)化是和官方開發(fā)同學一起來完成的,前面介紹過程中,已經(jīng)給出相應的 PR 鏈接,方便大家參考。我們在公司內(nèi)部也組建了開源協(xié)同的小組,來共建 Elastic 生態(tài)。
總體來說,開源的收益利大于弊,我們把相應收益反饋出來,希望更多同學參與到 Elastic 生態(tài)的開源貢獻中:首先,開源可以降低分支維護成本,隨著自研的功能越來越多,維護獨立分支的成本越來越高,主要體現(xiàn)在與開源版本同步、快速引入開源新特性方面;其次,開源可以幫助研發(fā)同學更深入的把控內(nèi)核,了解最新技術動態(tài),因為在開源反饋的過程中,會涉及與官方開發(fā)人員持續(xù)的交互。此外,開源有利于建立大家在社區(qū)的技術影響力,獲得開源社區(qū)的認可。最后 Elastic 生態(tài)的快速發(fā)展,有利于業(yè)務服務、個人技術的發(fā)展,希望大家一起參與進來,助力 Elastic 生態(tài)持續(xù)、快速的發(fā)展。
未來規(guī)劃方面,這次分享我們重點介紹了騰訊在 ES 內(nèi)核方面的優(yōu)化實踐,包含高可用、低成本、高性能等方面。此外,我們也提供了一套管控平臺,支持線上集群自動化管控、運維,為騰訊云客戶提供 ES 服務。但是從線上大量的運營經(jīng)驗分析,我們發(fā)現(xiàn)仍然有非常豐富、高價值的方向需要繼續(xù)跟進,我們會持續(xù)繼續(xù)加強對產(chǎn)品、內(nèi)核的建設。
長期探索方面,我們結合大數(shù)據(jù)圖譜來介紹。整個大數(shù)據(jù)領域,按照數(shù)據(jù)量、延時要求等特點,可以劃分為三部分:第一部分是 Data Engineering,包含我們熟悉的批量計算、流式計算;第二部分是 Data Discovery,包含交互式分析、搜索等;第三個部分是 Data Apps,主要用于支撐在線服務。
雖然我們把 ES 放到搜索領域內(nèi),但是也有很多用戶使用 ES 支持在線搜索、文檔服務等;另外,我們了解到有不少成熟的 OLAP 系統(tǒng),也是基于倒排索引、行列混存等技術棧,所以我們認為 ES 未來往這兩個領域發(fā)展的可行性非常強,我們未來會在 OLAP 分析和在線服務等方向進行重點探索。