這篇文章主要講解了“如何調(diào)優(yōu)Elasticsearch”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“如何調(diào)優(yōu)Elasticsearch”吧!
創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、浉河網(wǎng)絡(luò)推廣、重慶小程序開(kāi)發(fā)公司、浉河網(wǎng)絡(luò)營(yíng)銷、浉河企業(yè)策劃、浉河品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供浉河建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com
每天都有數(shù)量相當(dāng)龐大的新聞和微博產(chǎn)生;在高峰期需要索引大約300多萬(wàn)社論文章,和近1億條社交帖子數(shù)據(jù)。其中社論數(shù)據(jù)長(zhǎng)期保存以供檢索(可回溯到2009年),社交帖子數(shù)據(jù)保存近15個(gè)月的。當(dāng)前的主分片數(shù)據(jù)使用了大約200 TB的磁盤(pán)空間,副本數(shù)據(jù)大約600 TB。
我們的業(yè)務(wù)每分鐘有3千次請(qǐng)求。所有的請(qǐng)求通過(guò)一個(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)求以外,沒(méi)有一個(gè)查詢是像在 Google 里查詢 “Barack Obama” 這么簡(jiǎn)單的;這簡(jiǎn)直就是可怕的野獸,但ES節(jié)點(diǎn)必須努力找出一個(gè)匹配的文檔集。
我們運(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é)果來(lái)說(shuō)開(kāi)銷非常大,不過(guò)在 Elasticsearch 2.X 中已經(jīng)做了優(yōu)化。
為何不使用較新版本的 Elasticsearch 呢?主要原因是升級(jí)困難。在主版本間滾動(dòng)升級(jí)只適用于從ES 5到6(從ES 2到5應(yīng)該也支持滾動(dòng)升級(jí),但沒(méi)有試過(guò))。因此,我們只能通過(guò)重啟整個(gè)集群來(lái)升級(jí)。宕機(jī)對(duì)我們來(lái)說(shuō)幾乎不可接受,但或許可以應(yīng)對(duì)一次重啟所帶來(lái)的大約30-60分鐘宕機(jī)時(shí)間;而真正令人擔(dān)心的,是一旦發(fā)生故障并沒(méi)有真正的回滾過(guò)程。
截止目前我們選擇了不升級(jí)集群。當(dāng)然我們希望可以升級(jí),但目前有更為緊迫的任務(wù)。實(shí)際上該如何實(shí)施升級(jí)尚未有定論,很可能選擇創(chuàng)建另一個(gè)新的集群,而不是升級(jí)現(xiàn)有的。
我們自2017年6月開(kāi)始在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。這是避免腦裂問(wèn)題 split-brain problem 非常通用的策略。
我們的數(shù)據(jù)集在存儲(chǔ)方面,要求80%容量和3個(gè)以上的副本,這使得我們運(yùn)行了430個(gè)數(shù)據(jù)節(jié)點(diǎn)。起初打算使用不同層級(jí)的數(shù)據(jù),在較慢的磁盤(pán)上存儲(chǔ)較舊的數(shù)據(jù),但是由于我們只有相關(guān)的較低量級(jí)舊于15個(gè)月的數(shù)據(jù)(只有編輯數(shù)據(jù),因?yàn)槲覀儊G棄了舊的社交數(shù)據(jù)),然而這并未奏效。每個(gè)月的硬件開(kāi)銷遠(yuǎn)大于運(yùn)行在COLO中,但是云服務(wù)支持?jǐn)U容集群到2倍,而幾乎不用花費(fèi)多少時(shí)間。
你可能會(huì)問(wèn),為何選擇自己管理維護(hù)ES集群。其實(shí)我們考慮過(guò)托管方案,但最后還是選擇自己安裝,理由是: 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 來(lái)完成該項(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)存,剩下的用于磁盤(pán)緩存。為何是26GB?因?yàn)?nbsp; JVM 是在一個(gè)黑魔法之上構(gòu)建的 。
我們同時(shí)使用 Terraform 自動(dòng)擴(kuò)容組來(lái)提供實(shí)例,并使用 Puppet 完成一切安裝配置。
因?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,但通過(guò)TCP壓縮可減少到3 MB(可以通過(guò) 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ū)(比如 最基本的通過(guò)公共互聯(lián)網(wǎng))之間傳輸。這會(huì)比較耗時(shí),尤其是在刪除數(shù)百個(gè)索引時(shí)。我們希望新版本的 Elasticsearch 能優(yōu)化這一點(diǎn),首先從 ES 2.0支持僅發(fā)送集群狀態(tài)的差分?jǐn)?shù)據(jù) 這一特性開(kāi)始。
如前所述,我們的ES集群為了滿足客戶的檢索需求,需要處理一些非常復(fù)雜的查詢。
為應(yīng)對(duì)查詢負(fù)載,過(guò)去幾年我們?cè)谛阅芊矫孀隽舜罅康墓ぷ?。我們必須嘗試公平分享ES集群的性能測(cè)試,從下列引文就可以看出。
不幸的是,當(dāng)集群宕機(jī)的時(shí)候,不到三分之一的查詢能成功完成。我們相信測(cè)試本身導(dǎo)致了集群宕機(jī)。
—— 摘錄自使用真實(shí)查詢?cè)谛翬S集群平臺(tái)上的第一次性能測(cè)試
為了控制查詢執(zhí)行過(guò)程,我們開(kāi)發(fā)了一個(gè)插件,實(shí)現(xiàn)了一系列自定義查詢類型。通過(guò)使用這些查詢類型來(lái)提供Elasticsearch官方版本不支持的功能和性能優(yōu)化。比如,我們實(shí)現(xiàn)了 phrases 中的 wildcard 查詢,支持在 SpanNear 查詢中執(zhí)行;另一個(gè)優(yōu)化是支持“*”代替 match-all-query ;還有其他一系列特性。
Elasticsearch 和 Lucene 的性能高度依賴于具體的查詢和數(shù)據(jù),沒(méi)有銀彈。即便如此,仍可給出一些從基礎(chǔ)到進(jìn)階的參考:
限制你的檢索范圍,僅涉及相關(guān)數(shù)據(jù)。比如,對(duì)于每日索引庫(kù),只按相關(guān)日期范圍檢索。對(duì)于檢索范圍中間的索引,避免使用范圍查詢/過(guò)濾器。
使用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工具或者通過(guò) JMX 代理獲得。如果 ParNewGC 消耗了超過(guò)15%的時(shí)間,去檢查下內(nèi)存日志。如果有任何的 SerialGC 停頓,你可能真的遇到問(wèn)題了。不太了解這些內(nèi)容?
沒(méi)關(guān)系,這個(gè)系列博文很好地介紹了 JVM性能 。記住, ES和G1垃圾回收器一起并非最佳 。
如果遇到垃圾回收問(wèn)題,請(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)存問(wèn)題,但沒(méi)有時(shí)間解決,可考慮查詢Azul Zing。這是一個(gè)很貴的產(chǎn)品,但僅僅使用它們的JVM就可以提升2倍的吞吐量。不過(guò)最終我們并沒(méi)有使用它,因?yàn)槲覀儫o(wú)法證明物有所值。
考慮使用緩存,包括 Elasticsearch 外緩存和 Lucene 級(jí)別的緩存。在 Elasticsearch 1.X 中可以通過(guò)使用 filter 來(lái)控制緩存。之后的版本中看起來(lái)更難一些,但貌似可以實(shí)現(xiàn)自己用于緩存的查詢類型。我們?cè)谖磥?lái)升級(jí)到2.X的時(shí)候可能會(huì)做類似的工作。
查看是否有熱點(diǎn)數(shù)據(jù)(比如某個(gè)節(jié)點(diǎn)承擔(dān)了所有的負(fù)載)??梢試L試均衡負(fù)載,使用分片分配過(guò)濾策略 shard allocation filtering ,或者嘗試通過(guò)集群重新路由 cluster rerouting 來(lái)自行遷移分片。我們已經(jīng)使用線性優(yōu)化自動(dòng)重新路由,但使用簡(jiǎn)單的自動(dòng)化策略也大有幫助。
搭建測(cè)試環(huán)境(我更喜歡筆記本)可從線上環(huán)境加載一部分代表性的數(shù)據(jù)(建議至少有一個(gè)分片)。使用線上的查詢回放加壓(較難)。使用本地設(shè)置來(lái)測(cè)試請(qǐng)求的資源消耗。
綜合以上各點(diǎn),在 Elasticsearch 進(jìn)程上啟用一個(gè) profiler。這是本列表中最重要的一條。
我們同時(shí)通過(guò) Java Mission Control 和 VisualVM 使用飛行記錄器。在性能問(wèn)題上嘗試投機(jī)(包括付費(fèi)顧問(wèn)/技術(shù)支持)的人是在浪費(fèi)他們(以及你自己)的時(shí)間。排查下 JVM 哪部分消耗了時(shí)間和內(nèi)存,然后探索下 Elasticsearch/Lucene 源代碼,檢查是哪部分代碼在執(zhí)行或者分配內(nèi)存。
一旦搞清楚是請(qǐng)求的哪一部分導(dǎo)致了響應(yīng)變慢,你就可以通過(guò)嘗試修改請(qǐng)求來(lái)優(yōu)化(比如, 修改term聚合的執(zhí)行提示 ,或者切換查詢類型)。修改查詢類型或者查詢順序,可以有較大影響。如果不湊效,還可以嘗試優(yōu)化 ES/Lucene 代碼。這看起來(lái)太夸張,卻可以為我們降低3到4倍的CPU消耗和4到8倍的內(nèi)存使用。某些修改很細(xì)微(比如 indices query ),但其他人可能要求我們完全重寫(xiě)查詢執(zhí)行。最終的代碼嚴(yán)重依賴于我們的查詢模式,所以可能適合也可能不適合他人使用。因此目前為止我們并沒(méi)有開(kāi)源這部分代碼。不過(guò)這可能是下一篇博文的好素材。
圖表說(shuō)明:響應(yīng)時(shí)間。有/沒(méi)有 重寫(xiě) Lucene 查詢執(zhí)行。同時(shí)也表明不再有節(jié)點(diǎn)每天多次發(fā)生內(nèi)存不足。
感謝各位的閱讀,以上就是“如何調(diào)優(yōu)Elasticsearch”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)如何調(diào)優(yōu)Elasticsearch這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!