ElasticSearch集群構(gòu)建及容量規(guī)劃指南

導(dǎo)言

ES 是在系統(tǒng)架構(gòu)設(shè)計(jì)時(shí)常用到的數(shù)據(jù)搜索與存儲系統(tǒng),對于輸入的數(shù)據(jù),ES會按照預(yù)先定義好的設(shè)置(如果沒有預(yù)先設(shè)置好,可以設(shè)置動(dòng)態(tài)映射)進(jìn)行分詞,建立倒排索引和Doc_values,以方便搜索查詢。ES本身具備對索引進(jìn)行分片和備份的功能,使用者可以在索引建立時(shí)進(jìn)行設(shè)置。ES 底層使用了Luence對數(shù)據(jù)進(jìn)行管理,對宿主機(jī)的內(nèi)存和磁盤IO有較高的要求,這使得每個(gè)ES的節(jié)點(diǎn)成本會比較高,因此在規(guī)劃階段需要對要使用的ES節(jié)點(diǎn)數(shù)目進(jìn)行評估,以了解后續(xù)的成本狀況。

節(jié)點(diǎn)

不考慮使用MachineLearning的情況,ES 的節(jié)點(diǎn)角色設(shè)置有以下幾種:

  • Master(主節(jié)點(diǎn))

    集群的主節(jié)點(diǎn),負(fù)責(zé)集群的編排。對應(yīng)節(jié)點(diǎn)配置中的node.master設(shè)為true

  • Data(數(shù)據(jù)節(jié)點(diǎn))

    數(shù)據(jù)節(jié)點(diǎn),負(fù)責(zé)數(shù)據(jù)的搜索與寫入。對應(yīng)節(jié)點(diǎn)配置中的node.data設(shè)為true

  • Ingest(ingest節(jié)點(diǎn))

    負(fù)責(zé)進(jìn)行請求的預(yù)處理(pipeline)。對應(yīng)節(jié)點(diǎn)配置中的node.ingest設(shè)為true

  • coordinate(協(xié)調(diào)節(jié)點(diǎn))

    接收外部請求,并將請求分配到相應(yīng)應(yīng)的節(jié)點(diǎn),并對節(jié)點(diǎn)返回的數(shù)據(jù)進(jìn)行合并處理。當(dāng)前三個(gè)角色的配置都是false的情況下,該節(jié)點(diǎn)會承擔(dān)專門協(xié)調(diào)的角色。實(shí)際情況下,所有節(jié)點(diǎn)都具備coordinator請求的能力。

對于小規(guī)模的集群,由于設(shè)備有限,往往node.master,node.data,node.ingest都設(shè)置為true,方便管理。對于較大規(guī)模的集群,由于這幾個(gè)角色對計(jì)算資源的要求不同,往往分配單獨(dú)角色節(jié)點(diǎn)以最優(yōu)化資源利用。

同時(shí),考慮到冷熱數(shù)據(jù)不同的索引需求,一般會將數(shù)據(jù)節(jié)點(diǎn)再按冷熱溫(Hot,Warm,Cold)進(jìn)行劃分,同時(shí)結(jié)合索引的生命周期管理(ILM)模塊進(jìn)行搭配使用。(ILM參考:http://www.itdecent.cn/p/9f7f39efeda3)

  • Hot節(jié)點(diǎn)

    處理當(dāng)前最新數(shù)據(jù)的寫入和查詢,一般會配置大內(nèi)存和固態(tài)硬盤,具有較高的磁盤IO,SSD一般會具備200,000到400,000的IOPS,如果以存儲量來算,單塊SSD能夠達(dá)到1-2GBps。

    相對而言,普通HDD的順序?qū)懭胨俣却蟾偶s240MBps,如果是隨機(jī)寫入則速度更低,可以通過配置Raid0來提示HDD的性能。由于ES本身在邏輯成本實(shí)現(xiàn)了高可用,因此不需要再通過搭建raid5的方式提供磁盤的高可用。

  • Warm節(jié)點(diǎn)

    一般用來存儲非最新數(shù)據(jù),不會有實(shí)時(shí)寫入的請求,有時(shí)候會處理一些查詢,索引處于只讀狀態(tài)。一般會使用HDD配合中等配置的內(nèi)存。

  • Cold節(jié)點(diǎn)

    Cold節(jié)點(diǎn)用來存放歸檔的數(shù)據(jù),以滿足一些法律法規(guī)。如果數(shù)據(jù)并沒有留存的需求,一般超過一定的時(shí)限就會刪除相關(guān)的索引。Cold節(jié)點(diǎn)需要廉價(jià)的大容量存儲,索引處于關(guān)閉狀態(tài),沒有實(shí)時(shí)的查詢需求。

ES的數(shù)據(jù)節(jié)點(diǎn)往往有較大的負(fù)載壓力,一般建議節(jié)點(diǎn)不要共用硬件設(shè)備,一防止因?yàn)橛布驅(qū)е露鄠€(gè)節(jié)點(diǎn)同時(shí)離線。

由于Java壓縮指針的原因,分配給節(jié)點(diǎn)JVM的堆內(nèi)存不建議超過32GB,一般推薦分配一般的內(nèi)存給JVM,另外一般內(nèi)存用來做page cache。節(jié)點(diǎn)的swap需要禁止,其原因在于如果不禁止swap,節(jié)點(diǎn)就可能交換JVM的堆內(nèi)存而不是page cache,這會導(dǎo)致更長的系統(tǒng)響應(yīng)時(shí)間。

業(yè)務(wù)場景

對于數(shù)據(jù)來說,對應(yīng)操作包括,增(index),刪(delete),改(update),查(search/query)。對于ES來說,比較重要的兩個(gè)場景為新增(數(shù)據(jù)寫入)和查詢。

數(shù)據(jù)寫入

如下圖所示,數(shù)據(jù)的寫入有以下流程:

  1. coordinator節(jié)點(diǎn)接收到外界的寫入請求。
  2. 如果集群有配置ingest pipeline,coordinator節(jié)點(diǎn)會將請求發(fā)放到ingest節(jié)點(diǎn)進(jìn)行預(yù)處理。
  3. 如果沒有配置pipeline或者在預(yù)處理結(jié)束后,相應(yīng)節(jié)點(diǎn)會根據(jù)routing規(guī)則決定該請求需要寫入到哪個(gè)分片(shard)(一般會根據(jù)_id值做hash。shard_id = hash(routing) % number_of_shard),并且請求分配到對應(yīng)節(jié)點(diǎn)。
  4. shard對應(yīng)節(jié)點(diǎn)處理寫入請求。
  5. 寫入請求完成后,向副本分片所在節(jié)點(diǎn)發(fā)出replication請求。
  6. 副本分片所在節(jié)點(diǎn)處理副本寫入請求。
put.png

數(shù)據(jù)搜索

對數(shù)據(jù)進(jìn)行搜索時(shí),會有不同于寫入時(shí)的處理流程。不會進(jìn)行pipeline處理。相關(guān)流程為:

  1. coordinator節(jié)點(diǎn)接收到查詢請求。
  2. 在本地找到需要查詢的分片后,coordinator節(jié)點(diǎn)將請求分配到相關(guān)shard所在節(jié)點(diǎn)。
  3. 各shard處理完搜索后,將結(jié)果返回給coordinator節(jié)點(diǎn)。
  4. coordinator節(jié)點(diǎn)會將各shard返回來的結(jié)果進(jìn)行合并。
  5. coordinator節(jié)點(diǎn)將合并好的結(jié)果返回給請求客戶端。
ES_analyzer-Query.png

資源

可以看出coordinator節(jié)點(diǎn)負(fù)責(zé)處理外界的request,并將相應(yīng)的操作指派到相應(yīng)節(jié)點(diǎn)上去。在搜索或者聚合的情況下,還要合并從各個(gè)節(jié)點(diǎn)返回的結(jié)果,再將結(jié)果返回給客戶端。因此可以看出,coordinator節(jié)點(diǎn)對于網(wǎng)絡(luò)帶寬,CPU,和內(nèi)存的要求都較高。對于大規(guī)模集群來說,coordinator節(jié)點(diǎn)本身負(fù)載壓力就比較大,不適合在擔(dān)任其他角色。

ingest節(jié)點(diǎn)負(fù)責(zé)在文檔寫入之前對數(shù)據(jù)進(jìn)行預(yù)處理,功能比較單一,主要是CPU和內(nèi)存。

數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)具體的寫入和搜索邏輯,對內(nèi)存要求比較高,數(shù)據(jù)節(jié)點(diǎn)的CPU能力決定了其可以承載的并發(fā)數(shù)。同時(shí)數(shù)據(jù)節(jié)點(diǎn)也承擔(dān)了數(shù)據(jù)的存儲職能,對磁盤IO有一定的要求。由于數(shù)據(jù)在做replication時(shí),會有n倍的流量在集群內(nèi)部備份節(jié)點(diǎn)之間發(fā)生,因此數(shù)據(jù)節(jié)點(diǎn)對網(wǎng)絡(luò)也有一定的要求,這取決于數(shù)據(jù)的副本數(shù)。

下表是各種角色的節(jié)點(diǎn)對資源的依賴情況下,僅代表個(gè)人觀點(diǎn)。

角色 CPU 內(nèi)存 IO 網(wǎng)絡(luò)
coordinator 一般
ingest 一般 一般 一般 一般
data 一般
master 一般 取決于集群大小 一般 一般

對數(shù)據(jù)量進(jìn)行估算

在規(guī)劃ES集群之前,我們需要問自己幾個(gè)問題:

  1. 我的數(shù)據(jù)是什么樣的。
    • 每天會有多少新增數(shù)據(jù)?
    • 這些數(shù)據(jù)需要保留多少天?
    • 給這些數(shù)據(jù)設(shè)置幾個(gè)副本?
    • 原始數(shù)據(jù)在寫入ES后大小會有所變化,比如,要建立倒排索引。keyword字段和其他結(jié)構(gòu)化字段會構(gòu)建doc_values正排索引,這些都會導(dǎo)致落盤后的數(shù)據(jù)發(fā)生變化。
  2. 我的資源是怎么樣的
    • 數(shù)據(jù)節(jié)點(diǎn)有多少堆內(nèi)存
    • 我需要留出部分磁盤空間給系統(tǒng)和后臺,按5%計(jì)算。
    • ES默認(rèn)的磁盤low.watermark是85%,超過該閾值后,將不允許向該節(jié)點(diǎn)分配shard。
    • 考慮到系統(tǒng)的高可用,需要考慮在一個(gè)或多個(gè)節(jié)點(diǎn)下線的情況下,離線的分片可以得到重新分配。

獲得了這些數(shù)據(jù)后,我們就可以進(jìn)行計(jì)算了。

  • 總數(shù)據(jù)量 = 每天新增原始數(shù)據(jù)量 * 保留天數(shù) * (副本數(shù)+1)*膨脹系數(shù)
  • 磁盤空間 = 總數(shù)據(jù)量 / (1-15%-5%) = 總數(shù)據(jù)量 * 1.25
  • 所需節(jié)點(diǎn)數(shù) = 磁盤空間 / (節(jié)點(diǎn)內(nèi)存/內(nèi)存磁盤比)
    • 一個(gè)經(jīng)驗(yàn)數(shù)字是,使用SSD的Hot類型節(jié)點(diǎn)(內(nèi)存/磁盤)為1/30。使用HDD的Warm類型節(jié)點(diǎn)(內(nèi)存/磁盤)比為1/160。而用來歸檔,使用廉價(jià)硬盤存儲的Cold類型節(jié)點(diǎn)(內(nèi)存/磁盤)為1/1000。
  • 一個(gè)經(jīng)驗(yàn)數(shù)字,所需的磁盤空間一般為原始數(shù)據(jù)大小的3.38倍。僅供參考,具體使用的磁盤空間。

使用多個(gè)類型(Hot,Warm,Cold)分片時(shí),需要按照每個(gè)階段分別進(jìn)行計(jì)算。

對分片數(shù)進(jìn)行估算

在進(jìn)行分片估計(jì)時(shí),我們需要先準(zhǔn)備以下數(shù)據(jù):

  1. 有多少個(gè)索引
  2. 每個(gè)索引設(shè)置多少個(gè)shard以及幾個(gè)replication
  3. 每個(gè)索引保留多長時(shí)間
  4. 每個(gè)數(shù)據(jù)節(jié)點(diǎn)有多少內(nèi)存

現(xiàn)在我們有以下一些經(jīng)驗(yàn)數(shù)據(jù):

  1. 每1GB堆內(nèi)存最多包含20個(gè)分片(每個(gè)分片50MB,是一個(gè)非常小的值,建議按情況適當(dāng)提高該數(shù)值)
  2. 每個(gè)分片不超過50GB。(一般30-40GB)

可以計(jì)算得到:

  • 總分片數(shù) = 索引數(shù)量 * shard數(shù) * (副本數(shù) + 1)
  • 所需節(jié)點(diǎn) = 總分片數(shù) / (節(jié)點(diǎn)堆內(nèi)存[GB]/每GB堆內(nèi)存承載分片數(shù) )

ES權(quán)威指南里提到了一種通過實(shí)踐的評估方式,可以參考:https://www.elastic.co/guide/cn/elasticsearch/guide/cn/capacity-planning.html

根據(jù)搜索量進(jìn)行估算

我們需要預(yù)先假設(shè)幾個(gè)數(shù)據(jù):

  1. 峰值每秒請求數(shù)。
  2. 平均請求延時(shí)。

我們預(yù)先知道每個(gè)節(jié)點(diǎn)的線程池大小,搜索線程池大小一般配為:

線程池大小 = int(核數(shù) * 3/2) + 1,該公式來源于https://www.elastic.co/guide/cn/elasticsearch/guide/current/dont-touch-these-settings.html

先計(jì)算:

  1. 每線程每秒處理請求數(shù) = 1s/平均請求延時(shí)
  2. 處理峰值請求所需的并發(fā)數(shù) = 峰值每秒請求數(shù)/每線程每秒處理請求數(shù)
  3. 所需節(jié)點(diǎn)數(shù) = 峰值并發(fā)數(shù)/每節(jié)點(diǎn)線程池大小。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容