溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

400+節(jié)點(diǎn)的 Elasticsearch 集群運(yùn)維

發(fā)布時(shí)間:2020-06-25 12:02:29 來源:網(wǎng)絡(luò) 閱讀:283 作者:vivo互聯(lián)網(wǎng) 欄目:大數(shù)據(jù)

作者:Anton H?gerstrand
翻譯:楊振濤

目錄:

  1. 數(shù)據(jù)量
  2. 版本
  3. 節(jié)點(diǎn)配置
  4. 索引結(jié)構(gòu)
  5. 性能

Meltwater每天要處理數(shù)百萬量級(jí)的帖子數(shù)據(jù),因此需要一種能處理該量級(jí)數(shù)據(jù)的存儲(chǔ)和檢索技術(shù)。

400+節(jié)點(diǎn)的 Elasticsearch 集群運(yùn)維

從0.11.X 版本開始我們就已經(jīng)是Elasticsearch的忠實(shí)用戶了。在經(jīng)歷了一些波折之后,最終我們認(rèn)為做出了正確的技術(shù)選型。

Elasticsearch 用于支持我們的主要媒體監(jiān)控應(yīng)用,客戶通過該應(yīng)用可以檢索和分析媒體數(shù)據(jù),比如新聞文章、(公開的)Facebook帖子、Instagram帖子、博客和微博。我們通過使用一個(gè)混合API來收集這些內(nèi)容,并爬取和稍作加工,使得它們可被 Elasticsearch 檢索到。

本文將分享我們所學(xué)到的經(jīng)驗(yàn)、如何調(diào)優(yōu) Elasticsearch,以及要繞過的一些陷阱。

如果想了解更多關(guān)于我們?cè)贓lasticsearch方面的點(diǎn)滴,可參考之前博文中的 numad issues 和 batch percolator。

1.數(shù)據(jù)量

每天都有數(shù)量相當(dāng)龐大的新聞和微博產(chǎn)生;在高峰期需要索引大約300多萬社論文章,和近1億條社交帖子數(shù)據(jù)。其中社論數(shù)據(jù)長(zhǎng)期保存以供檢索(可回溯到2009年),社交帖子數(shù)據(jù)保存近15個(gè)月的。當(dāng)前的主分片數(shù)據(jù)使用了大約200 TB的磁盤空間,副本數(shù)據(jù)大約600 TB。

我們的業(yè)務(wù)每分鐘有3千次請(qǐng)求。所有的請(qǐng)求通過一個(gè)叫做 “search-service” 的服務(wù),該服務(wù)會(huì)依次完成所有與 Elasticsearch 集群的交互。大部分檢索規(guī)則比較復(fù)雜,包括在面板和新聞流中。比如,一個(gè)客戶可能對(duì) Tesla 和 Elon Musk 感興趣,但希望排除所有關(guān)于 SpaceX 或 PayPal 的信息。用戶可以使用一種與 Lucene 查詢語(yǔ)法類似的靈活語(yǔ)法,如下:

Tesla AND "Elon Musk" NOT (SpaceX OR PayPal)

我們最長(zhǎng)的此類查詢有60多頁(yè)。重點(diǎn)是:除了每分鐘3千次請(qǐng)求以外,沒有一個(gè)查詢是像在 Google 里查詢 “Barack Obama” 這么簡(jiǎn)單的;這簡(jiǎn)直就是可怕的野獸,但ES節(jié)點(diǎn)必須努力找出一個(gè)匹配的文檔集。

400+節(jié)點(diǎn)的 Elasticsearch 集群運(yùn)維

2.版本

我們運(yùn)行的是一個(gè)基于 Elasticsearch 1.7.6 的定制版本。該版本與1.7.6 主干版本的唯一區(qū)別是,我們向后移植(backport)了 roaring bitsets/bitmaps 作為緩存。該功能是從 Lucene 5 移植到 Lucene 4 的,對(duì)應(yīng)移植到了 ES 1.X 版本。Elasticsearch 1.X 中使用默認(rèn)的 bitset 作為緩存,對(duì)于稀疏結(jié)果來說開銷非常大,不過在 Elasticsearch 2.X 中已經(jīng)做了優(yōu)化。

為何不使用較新版本的 Elasticsearch 呢?主要原因是升級(jí)困難。在主版本間滾動(dòng)升級(jí)只適用于從ES 5到6(從ES 2到5應(yīng)該也支持滾動(dòng)升級(jí),但沒有試過)。因此,我們只能通過重啟整個(gè)集群來升級(jí)。宕機(jī)對(duì)我們來說幾乎不可接受,但或許可以應(yīng)對(duì)一次重啟所帶來的大約30-60分鐘宕機(jī)時(shí)間;而真正令人擔(dān)心的,是一旦發(fā)生故障并沒有真正的回滾過程。

截止目前我們選擇了不升級(jí)集群。當(dāng)然我們希望可以升級(jí),但目前有更為緊迫的任務(wù)。實(shí)際上該如何實(shí)施升級(jí)尚未有定論,很可能選擇創(chuàng)建另一個(gè)新的集群,而不是升級(jí)現(xiàn)有的。

3.節(jié)點(diǎn)配置

我們自2017年6月開始在AWS上運(yùn)行主集群,使用i3.2xlarge實(shí)例作為數(shù)據(jù)節(jié)點(diǎn)。之前我們?cè)贑OLO(Co-located Data Center)里運(yùn)行集群,但后續(xù)遷移到了AWS云,以便在新機(jī)器宕機(jī)時(shí)能贏得時(shí)間,使得我們?cè)跀U(kuò)容和縮容時(shí)更加彈性。

我們?cè)诓煌目捎脜^(qū)運(yùn)行3個(gè)候選 master 節(jié)點(diǎn),并設(shè)置 discovery.zen.minimum_master_nodes 為2。這是避免腦裂問題 split-brain problem 非常通用的策略。

我們的數(shù)據(jù)集在存儲(chǔ)方面,要求80%容量和3個(gè)以上的副本,這使得我們運(yùn)行了430個(gè)數(shù)據(jù)節(jié)點(diǎn)。起初打算使用不同層級(jí)的數(shù)據(jù),在較慢的磁盤上存儲(chǔ)較舊的數(shù)據(jù),但是由于我們只有相關(guān)的較低量級(jí)舊于15個(gè)月的數(shù)據(jù)(只有編輯數(shù)據(jù),因?yàn)槲覀儊G棄了舊的社交數(shù)據(jù)),然而這并未奏效。每個(gè)月的硬件開銷遠(yuǎn)大于運(yùn)行在COLO中,但是云服務(wù)支持?jǐn)U容集群到2倍,而幾乎不用花費(fèi)多少時(shí)間。

你可能會(huì)問,為何選擇自己管理維護(hù)ES集群。其實(shí)我們考慮過托管方案,但最后還是選擇自己安裝,理由是: AWS Elasticsearch Service

暴露給用戶的可控性太差了,Elastic Cloud 的成本比直接在EC2上運(yùn)行集群要高2-3倍。

為了在某個(gè)可用區(qū)宕機(jī)時(shí)保護(hù)我們自身,節(jié)點(diǎn)分散于eu-west-1的所有3個(gè)可用區(qū)。我們使用 AWS plugin 來完成該項(xiàng)配置。它提供了一個(gè)叫做aws_availability_zone 的節(jié)點(diǎn)屬性,我們把 cluster.routing.allocation.awareness.attributes 設(shè)置為 aws_availability_zone。這保證了ES的副本盡可能地存儲(chǔ)在不同的可用區(qū),而查詢盡可能被路由到相同可用區(qū)的節(jié)點(diǎn)。

這些實(shí)例運(yùn)行的是 Amazon Linux,臨時(shí)掛載為 ext4,有約64GB的內(nèi)存。我們分配了26GB用于ES節(jié)點(diǎn)的堆內(nèi)存,剩下的用于磁盤緩存。為何是26GB?因?yàn)?JVM 是在一個(gè)黑魔法之上構(gòu)建的 。

我們同時(shí)使用 Terraform 自動(dòng)擴(kuò)容組來提供實(shí)例,并使用 Puppet 完成一切安裝配置。

4.索引結(jié)構(gòu)

因?yàn)槲覀兊臄?shù)據(jù)和查詢都是基于時(shí)間序列的,所以使用了 time-based indexing ,類似于ELK (elasticsearch, logstash, kibana) stack。同時(shí)也讓不同類型的數(shù)據(jù)保存在不同的索引庫(kù)中,以便諸如社論文檔和社交文檔類數(shù)據(jù)最終位于不同的每日索引庫(kù)中。這樣可以在需要的時(shí)候只丟棄社交索引,并增加一些查詢優(yōu)化。每個(gè)日索引運(yùn)行在兩個(gè)分片中的一個(gè)。

該項(xiàng)設(shè)置產(chǎn)生了大量的分片(接近40k)。有了這么多的分片和節(jié)點(diǎn),集群操作有時(shí)變得更特殊。比如,刪除索引似乎成為集群master的能力瓶頸,它需要把集群狀態(tài)信息推送給所有節(jié)點(diǎn)。我們的集群狀態(tài)數(shù)據(jù)約100 MB,但通過TCP壓縮可減少到3 MB(可以通過 curl localhost:9200/_cluster/state/_all 查看你自己集群的狀態(tài)數(shù)據(jù))。Master 節(jié)點(diǎn)仍然需要在每次變更時(shí)推送1.3 GB數(shù)據(jù)(430 節(jié)點(diǎn) x 3 MB 狀態(tài)大小)。除了這1.3 GB數(shù)據(jù)外,還有約860 MB必須在可用區(qū)(比如 最基本的通過公共互聯(lián)網(wǎng))之間傳輸。這會(huì)比較耗時(shí),尤其是在刪除數(shù)百個(gè)索引時(shí)。我們希望新版本的 Elasticsearch 能優(yōu)化這一點(diǎn),首先從 ES 2.0支持僅發(fā)送集群狀態(tài)的差分?jǐn)?shù)據(jù) 這一特性開始。

5.性能

如前所述,我們的ES集群為了滿足客戶的檢索需求,需要處理一些非常復(fù)雜的查詢。

為應(yīng)對(duì)查詢負(fù)載,過去幾年我們?cè)谛阅芊矫孀隽舜罅康墓ぷ鳌N覀儽仨殗L試公平分享ES集群的性能測(cè)試,從下列引文就可以看出。

不幸的是,當(dāng)集群宕機(jī)的時(shí)候,不到三分之一的查詢能成功完成。我們相信測(cè)試本身導(dǎo)致了集群宕機(jī)。

—— 摘錄自使用真實(shí)查詢?cè)谛翬S集群平臺(tái)上的第一次性能測(cè)試

為了控制查詢執(zhí)行過程,我們開發(fā)了一個(gè)插件,實(shí)現(xiàn)了一系列自定義查詢類型。通過使用這些查詢類型來提供Elasticsearch官方版本不支持的功能和性能優(yōu)化。比如,我們實(shí)現(xiàn)了 phrases 中的 wildcard 查詢,支持在 SpanNear 查詢中執(zhí)行;另一個(gè)優(yōu)化是支持“*”代替 match-all-query ;還有其他一系列特性。

Elasticsearch 和 Lucene 的性能高度依賴于具體的查詢和數(shù)據(jù),沒有銀彈。即便如此,仍可給出一些從基礎(chǔ)到進(jìn)階的參考:

限制你的檢索范圍,僅涉及相關(guān)數(shù)據(jù)。比如,對(duì)于每日索引庫(kù),只按相關(guān)日期范圍檢索。對(duì)于檢索范圍中間的索引,避免使用范圍查詢/過濾器。

使用wildcards時(shí)忽略前綴wildcards - 除非你能對(duì)term建立倒排索引。雙端wildcards難以優(yōu)化。

關(guān)注資源消耗的相關(guān)跡象 數(shù)據(jù)節(jié)點(diǎn)的CPU占用持續(xù)飆高嗎?IQ等待走高嗎?看看GC統(tǒng)計(jì)。這些可以從profilers工具或者通過 JMX 代理獲得。如果 ParNewGC 消耗了超過15%的時(shí)間,去檢查下內(nèi)存日志。如果有任何的 SerialGC 停頓,你可能真的遇到問題了。不太了解這些內(nèi)容?

沒關(guān)系,這個(gè)系列博文很好地介紹了JVM性能 。記住,ES和G1垃圾回收器一起并非最佳 。

如果遇到垃圾回收問題,請(qǐng)不要嘗試調(diào)整GC設(shè)置。這一點(diǎn)經(jīng)常發(fā)生,因?yàn)槟J(rèn)設(shè)置已經(jīng)很合理了。相反,應(yīng)該聚焦在減少內(nèi)存分配上。具體怎么做?參考下文。

如果遇到內(nèi)存問題,但沒有時(shí)間解決,可考慮查詢Azul Zing。這是一個(gè)很貴的產(chǎn)品,但僅僅使用它們的JVM就可以提升2倍的吞吐量。不過最終我們并沒有使用它,因?yàn)槲覀儫o法證明物有所值。

考慮使用緩存,包括 Elasticsearch 外緩存和 Lucene 級(jí)別的緩存。在 Elasticsearch 1.X 中可以通過使用 filter 來控制緩存。之后的版本中看起來更難一些,但貌似可以實(shí)現(xiàn)自己用于緩存的查詢類型。我們?cè)谖磥砩?jí)到2.X的時(shí)候可能會(huì)做類似的工作。

查看是否有熱點(diǎn)數(shù)據(jù)(比如某個(gè)節(jié)點(diǎn)承擔(dān)了所有的負(fù)載)??梢試L試均衡負(fù)載,使用分片分配過濾策略 shard allocation filtering ,或者嘗試通過集群重新路由 cluster rerouting 來自行遷移分片。我們已經(jīng)使用線性優(yōu)化自動(dòng)重新路由,但使用簡(jiǎn)單的自動(dòng)化策略也大有幫助。

搭建測(cè)試環(huán)境(我更喜歡筆記本)可從線上環(huán)境加載一部分代表性的數(shù)據(jù)(建議至少有一個(gè)分片)。使用線上的查詢回放加壓(較難)。使用本地設(shè)置來測(cè)試請(qǐng)求的資源消耗。

綜合以上各點(diǎn),在 Elasticsearch 進(jìn)程上啟用一個(gè) profiler。這是本列表中最重要的一條。

我們同時(shí)通過Java Mission Control 和 VisualVM 使用飛行記錄器。在性能問題上嘗試投機(jī)(包括付費(fèi)顧問/技術(shù)支持)的人是在浪費(fèi)他們(以及你自己)的時(shí)間。排查下 JVM 哪部分消耗了時(shí)間和內(nèi)存,然后探索下 Elasticsearch/Lucene 源代碼,檢查是哪部分代碼在執(zhí)行或者分配內(nèi)存。

一旦搞清楚是請(qǐng)求的哪一部分導(dǎo)致了響應(yīng)變慢,你就可以通過嘗試修改請(qǐng)求來優(yōu)化(比如,修改term聚合的執(zhí)行提示 ,或者切換查詢類型)。修改查詢類型或者查詢順序,可以有較大影響。如果不湊效,還可以嘗試優(yōu)化 ES/Lucene 代碼。這看起來太夸張,卻可以為我們降低3到4倍的CPU消耗和4到8倍的內(nèi)存使用。某些修改很細(xì)微(比如 indices query ),但其他人可能要求我們完全重寫查詢執(zhí)行。最終的代碼嚴(yán)重依賴于我們的查詢模式,所以可能適合也可能不適合他人使用。因此目前為止我們并沒有開源這部分代碼。不過這可能是下一篇博文的好素材。

400+節(jié)點(diǎn)的 Elasticsearch 集群運(yùn)維

圖表說明:響應(yīng)時(shí)間。有/沒有 重寫 Lucene 查詢執(zhí)行。同時(shí)也表明不再有節(jié)點(diǎn)每天多次發(fā)生內(nèi)存不足。

順便說明下,因?yàn)槲抑罆?huì)面臨一個(gè)問題:從上一次性能測(cè)試我們知道通過升級(jí)到 ES 2.X 能小幅提升性能,但是并不能改變什么。話雖如此,但如果你已經(jīng)從 ES 1.X 集群遷移到了 ES 2.X,我們很樂意聽取關(guān)于你如何完成遷移的實(shí)踐經(jīng)驗(yàn)。

如果讀到了這里,說明你對(duì) Elasticsearch 是真愛?。ɑ蛘咧辽倌闶钦娴男枰N覀兒軜芬鈱W(xué)習(xí)你的經(jīng)驗(yàn),以及任何可以分享的內(nèi)容。歡迎在評(píng)論區(qū)分享你的反饋和問題。

英文原文鏈接:http://underthehood.meltwater.com/blog/2018/02/06/running-a-400+-node-es-cluster/

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI