導(dǎo)言
ES 是在系統(tǒng)架構(gòu)設(shè)計時常用到的數(shù)據(jù)搜索與存儲系統(tǒng)澳叉,對于輸入的數(shù)據(jù),ES會按照預(yù)先定義好的設(shè)置(如果沒有預(yù)先設(shè)置好,可以設(shè)置動態(tài)映射)進行分詞成洗,建立倒排索引和Doc_values五督,以方便搜索查詢。ES本身具備對索引進行分片和備份的功能瓶殃,使用者可以在索引建立時進行設(shè)置充包。ES 底層使用了Luence對數(shù)據(jù)進行管理,對宿主機的內(nèi)存和磁盤IO有較高的要求遥椿,這使得每個ES的節(jié)點成本會比較高基矮,因此在規(guī)劃階段需要對要使用的ES節(jié)點數(shù)目進行評估,以了解后續(xù)的成本狀況冠场。
節(jié)點
不考慮使用MachineLearning的情況家浇,ES 的節(jié)點角色設(shè)置有以下幾種:
-
Master(主節(jié)點)
集群的主節(jié)點,負責集群的編排碴裙。對應(yīng)節(jié)點配置中的node.master設(shè)為true
-
Data(數(shù)據(jù)節(jié)點)
數(shù)據(jù)節(jié)點钢悲,負責數(shù)據(jù)的搜索與寫入。對應(yīng)節(jié)點配置中的node.data設(shè)為true
-
Ingest(ingest節(jié)點)
負責進行請求的預(yù)處理(pipeline)舔株。對應(yīng)節(jié)點配置中的node.ingest設(shè)為true
-
coordinate(協(xié)調(diào)節(jié)點)
接收外部請求莺琳,并將請求分配到相應(yīng)應(yīng)的節(jié)點,并對節(jié)點返回的數(shù)據(jù)進行合并處理载慈。當前三個角色的配置都是false的情況下惭等,該節(jié)點會承擔專門協(xié)調(diào)的角色。實際情況下娃肿,所有節(jié)點都具備coordinator請求的能力咕缎。
對于小規(guī)模的集群,由于設(shè)備有限料扰,往往node.master凭豪,node.data,node.ingest都設(shè)置為true晒杈,方便管理嫂伞。對于較大規(guī)模的集群,由于這幾個角色對計算資源的要求不同拯钻,往往分配單獨角色節(jié)點以最優(yōu)化資源利用帖努。
同時,考慮到冷熱數(shù)據(jù)不同的索引需求粪般,一般會將數(shù)據(jù)節(jié)點再按冷熱溫(Hot拼余,Warm,Cold)進行劃分亩歹,同時結(jié)合索引的生命周期管理(ILM)模塊進行搭配使用匙监。(ILM參考:http://www.reibang.com/p/9f7f39efeda3)
-
Hot節(jié)點
處理當前最新數(shù)據(jù)的寫入和查詢凡橱,一般會配置大內(nèi)存和固態(tài)硬盤,具有較高的磁盤IO亭姥,SSD一般會具備200稼钩,000到400,000的IOPS达罗,如果以存儲量來算坝撑,單塊SSD能夠達到1-2GBps。
相對而言粮揉,普通HDD的順序?qū)懭胨俣却蟾偶s240MBps巡李,如果是隨機寫入則速度更低,可以通過配置Raid0來提示HDD的性能滔蝉。由于ES本身在邏輯成本實現(xiàn)了高可用击儡,因此不需要再通過搭建raid5的方式提供磁盤的高可用。
-
Warm節(jié)點
一般用來存儲非最新數(shù)據(jù)蝠引,不會有實時寫入的請求阳谍,有時候會處理一些查詢,索引處于只讀狀態(tài)螃概。一般會使用HDD配合中等配置的內(nèi)存矫夯。
-
Cold節(jié)點
Cold節(jié)點用來存放歸檔的數(shù)據(jù),以滿足一些法律法規(guī)吊洼。如果數(shù)據(jù)并沒有留存的需求训貌,一般超過一定的時限就會刪除相關(guān)的索引。Cold節(jié)點需要廉價的大容量存儲冒窍,索引處于關(guān)閉狀態(tài)递沪,沒有實時的查詢需求。
ES的數(shù)據(jù)節(jié)點往往有較大的負載壓力综液,一般建議節(jié)點不要共用硬件設(shè)備款慨,一防止因為硬件原因?qū)е露鄠€節(jié)點同時離線。
由于Java壓縮指針的原因谬莹,分配給節(jié)點JVM的堆內(nèi)存不建議超過32GB檩奠,一般推薦分配一般的內(nèi)存給JVM,另外一般內(nèi)存用來做page cache附帽。節(jié)點的swap需要禁止埠戳,其原因在于如果不禁止swap,節(jié)點就可能交換JVM的堆內(nèi)存而不是page cache蕉扮,這會導(dǎo)致更長的系統(tǒng)響應(yīng)時間整胃。
業(yè)務(wù)場景
對于數(shù)據(jù)來說,對應(yīng)操作包括喳钟,增(index)爪模,刪(delete)欠啤,改(update),查(search/query)屋灌。對于ES來說,比較重要的兩個場景為新增(數(shù)據(jù)寫入)和查詢应狱。
數(shù)據(jù)寫入
如下圖所示共郭,數(shù)據(jù)的寫入有以下流程:
- coordinator節(jié)點接收到外界的寫入請求。
- 如果集群有配置ingest pipeline疾呻,coordinator節(jié)點會將請求發(fā)放到ingest節(jié)點進行預(yù)處理除嘹。
- 如果沒有配置pipeline或者在預(yù)處理結(jié)束后,相應(yīng)節(jié)點會根據(jù)routing規(guī)則決定該請求需要寫入到哪個分片(shard)(一般會根據(jù)_id值做hash岸蜗。shard_id = hash(routing) % number_of_shard)尉咕,并且請求分配到對應(yīng)節(jié)點。
- shard對應(yīng)節(jié)點處理寫入請求璃岳。
- 寫入請求完成后年缎,向副本分片所在節(jié)點發(fā)出replication請求。
- 副本分片所在節(jié)點處理副本寫入請求铃慷。
數(shù)據(jù)搜索
對數(shù)據(jù)進行搜索時单芜,會有不同于寫入時的處理流程。不會進行pipeline處理犁柜。相關(guān)流程為:
- coordinator節(jié)點接收到查詢請求洲鸠。
- 在本地找到需要查詢的分片后,coordinator節(jié)點將請求分配到相關(guān)shard所在節(jié)點馋缅。
- 各shard處理完搜索后宣增,將結(jié)果返回給coordinator節(jié)點。
- coordinator節(jié)點會將各shard返回來的結(jié)果進行合并出刷。
- coordinator節(jié)點將合并好的結(jié)果返回給請求客戶端板鬓。
資源
可以看出coordinator節(jié)點負責處理外界的request,并將相應(yīng)的操作指派到相應(yīng)節(jié)點上去稚疹。在搜索或者聚合的情況下居灯,還要合并從各個節(jié)點返回的結(jié)果,再將結(jié)果返回給客戶端内狗。因此可以看出怪嫌,coordinator節(jié)點對于網(wǎng)絡(luò)帶寬,CPU柳沙,和內(nèi)存的要求都較高岩灭。對于大規(guī)模集群來說,coordinator節(jié)點本身負載壓力就比較大赂鲤,不適合在擔任其他角色噪径。
ingest節(jié)點負責在文檔寫入之前對數(shù)據(jù)進行預(yù)處理柱恤,功能比較單一,主要是CPU和內(nèi)存找爱。
數(shù)據(jù)節(jié)點負責具體的寫入和搜索邏輯梗顺,對內(nèi)存要求比較高,數(shù)據(jù)節(jié)點的CPU能力決定了其可以承載的并發(fā)數(shù)车摄。同時數(shù)據(jù)節(jié)點也承擔了數(shù)據(jù)的存儲職能寺谤,對磁盤IO有一定的要求。由于數(shù)據(jù)在做replication時吮播,會有n倍的流量在集群內(nèi)部備份節(jié)點之間發(fā)生变屁,因此數(shù)據(jù)節(jié)點對網(wǎng)絡(luò)也有一定的要求,這取決于數(shù)據(jù)的副本數(shù)意狠。
下表是各種角色的節(jié)點對資源的依賴情況下粟关,僅代表個人觀點。
角色 | CPU | 內(nèi)存 | IO | 網(wǎng)絡(luò) |
---|---|---|---|---|
coordinator | 高 | 高 | 一般 | 高 |
ingest | 一般 | 一般 | 一般 | 一般 |
data | 一般 | 高 | 高 | 高 |
master | 一般 | 取決于集群大小 | 一般 | 一般 |
對數(shù)據(jù)量進行估算
在規(guī)劃ES集群之前环戈,我們需要問自己幾個問題:
- 我的數(shù)據(jù)是什么樣的闷板。
- 每天會有多少新增數(shù)據(jù)?
- 這些數(shù)據(jù)需要保留多少天谷市?
- 給這些數(shù)據(jù)設(shè)置幾個副本蛔垢?
- 原始數(shù)據(jù)在寫入ES后大小會有所變化,比如迫悠,要建立倒排索引鹏漆。keyword字段和其他結(jié)構(gòu)化字段會構(gòu)建doc_values正排索引,這些都會導(dǎo)致落盤后的數(shù)據(jù)發(fā)生變化创泄。
- 我的資源是怎么樣的
- 數(shù)據(jù)節(jié)點有多少堆內(nèi)存
- 我需要留出部分磁盤空間給系統(tǒng)和后臺艺玲,按5%計算。
- ES默認的磁盤low.watermark是85%鞠抑,超過該閾值后饭聚,將不允許向該節(jié)點分配shard。
- 考慮到系統(tǒng)的高可用搁拙,需要考慮在一個或多個節(jié)點下線的情況下秒梳,離線的分片可以得到重新分配。
獲得了這些數(shù)據(jù)后箕速,我們就可以進行計算了酪碘。
- 總數(shù)據(jù)量 = 每天新增原始數(shù)據(jù)量 * 保留天數(shù) * (副本數(shù)+1)*膨脹系數(shù)
- 磁盤空間 = 總數(shù)據(jù)量 / (1-15%-5%) = 總數(shù)據(jù)量 * 1.25
- 所需節(jié)點數(shù) = 磁盤空間 / (節(jié)點內(nèi)存/內(nèi)存磁盤比)
- 一個經(jīng)驗數(shù)字是,使用SSD的Hot類型節(jié)點(內(nèi)存/磁盤)為1/30盐茎。使用HDD的Warm類型節(jié)點(內(nèi)存/磁盤)比為1/160兴垦。而用來歸檔,使用廉價硬盤存儲的Cold類型節(jié)點(內(nèi)存/磁盤)為1/1000。
- 一個經(jīng)驗數(shù)字探越,所需的磁盤空間一般為原始數(shù)據(jù)大小的3.38倍狡赐。僅供參考,具體使用的磁盤空間钦幔。
使用多個類型(Hot枕屉,Warm,Cold)分片時鲤氢,需要按照每個階段分別進行計算搀庶。
對分片數(shù)進行估算
在進行分片估計時,我們需要先準備以下數(shù)據(jù):
- 有多少個索引
- 每個索引設(shè)置多少個shard以及幾個replication
- 每個索引保留多長時間
- 每個數(shù)據(jù)節(jié)點有多少內(nèi)存
現(xiàn)在我們有以下一些經(jīng)驗數(shù)據(jù):
- 每1GB堆內(nèi)存最多包含20個分片(每個分片50MB铜异,是一個非常小的值,建議按情況適當提高該數(shù)值)
- 每個分片不超過50GB秸架。(一般30-40GB)
可以計算得到:
- 總分片數(shù) = 索引數(shù)量 * shard數(shù) * (副本數(shù) + 1)
- 所需節(jié)點 = 總分片數(shù) / (節(jié)點堆內(nèi)存[GB]/每GB堆內(nèi)存承載分片數(shù) )
ES權(quán)威指南里提到了一種通過實踐的評估方式揍庄,可以參考:https://www.elastic.co/guide/cn/elasticsearch/guide/cn/capacity-planning.html
根據(jù)搜索量進行估算
我們需要預(yù)先假設(shè)幾個數(shù)據(jù):
- 峰值每秒請求數(shù)。
- 平均請求延時东抹。
我們預(yù)先知道每個節(jié)點的線程池大小蚂子,搜索線程池大小一般配為:
線程池大小 = int(核數(shù) * 3/2) + 1,該公式來源于https://www.elastic.co/guide/cn/elasticsearch/guide/current/dont-touch-these-settings.html
先計算:
- 每線程每秒處理請求數(shù) = 1s/平均請求延時
- 處理峰值請求所需的并發(fā)數(shù) = 峰值每秒請求數(shù)/每線程每秒處理請求數(shù)
- 所需節(jié)點數(shù) = 峰值并發(fā)數(shù)/每節(jié)點線程池大小缭黔。