elasticsearch生產集羣部署-集羣規劃建議(轉載)

一般來說,如果我們剛開始用es,都是先在自己的筆記本電腦上,或者是幾個虛擬機組成的小集羣上,安裝一個es,然後開始學習和試用其中的功能。但是如果我們要將es部署到生產環境中,那麼是由很多額外的事情要做的。需要考慮我們部署的機器的內存、CPU、磁盤、JVM等各種資源和配置。

1、內存

es是很吃內存的,es吃的主要不是你的jvm的內存,一般來說es用jvm heap(堆內存)還是用的比較少的,主要吃的是你的機器的內存

es底層基於lucene,lucene是基於磁盤文件來讀寫和保存你的索引數據的,倒排索引,正排索引,lucene的特點就是會基於os filesystem cache,會盡量將頻繁訪問的磁盤文件的數據在操作系統的內存中進行緩存,然後儘量提升磁盤文件讀寫的性能

很小夥伴都說,es的性能感覺不太理想,es的性能80%取決於說,你的機器上,除了分配給jvm heap內存以外,還剩下多少內存,剩下的內存會留給es的磁盤索引文件做緩存,如果os cache能夠緩存更多的磁盤文件的數據,索引文件的數據,索引讀寫的性能都會高很多,特別是檢索

但是如果你的大量的索引文件在os cache中放不下,還是停留在磁盤上,那麼搜索、聚合的時候大量的都是讀寫磁盤文件,性能當然低了,一個數量級,ms級,s級

問我,es上千萬數據的搜索,要耗費10s,大量讀寫磁盤了

如果在es生產環境中,哪種資源最容易耗盡,那麼就是內存了。排序和聚合都會耗費掉很多內存,所以給es進程分配足夠的jvm heap內存是很重要的。除了給jvm heap分配內存,還需要給予足夠的內存給os filesystem cache。因爲lucene用的數據結構都是給予磁盤的格式,es是通過os cache來進行高性能的磁盤文件讀寫的。

關於機器的內存相關的知識,後面會有很深入的講解,這裏先簡單提一下,一般而言,除非說你的數據量很小,比如就是一些os系統,各種信息管理系統,要做一個內部的檢索引擎,幾萬,幾十萬,幾百萬的數據量,對機器的資源配置要求還是蠻低的。一般而言,如果你的數據量過億,幾億,幾十億。那麼其實建議你的每臺機器都給64G的內存的量。

如果一個機器有64G的內存,那麼是比較理想的狀態,但是32GB和16GB的內存也是ok的。具體的內存數量還是根據數據量來決定。但是如果一個機器的內存數量小於8G,那麼就不太適合生產環境了,因爲我們可能就需要很多小內存的機器來搭建集羣。而大於64G的機器也不是很有必要。

筆記本電腦,24G內存(16G+8G),雙核,虛擬機4臺2核4G

2、CPU

大多數的es集羣對於cpu的要求都會比較低一些,因此一臺機器有多少個cpu core其實對生產環境的es集羣部署相對來說沒有那麼的重要了,至少沒有內存來的重要。當然,肯定是要用多核處理器的,一般來說2個cpu core~8個cpu core都是可以的。

此外,如果要選擇是較少的cpu core但是cpu性能很高,還是較多的cpu core但是cpu性能較爲一般,那麼肯定是選擇性能較爲一般但是更多的cpu core。因爲更多的cpu core可以提供更強的併發處理能力,遠比單個cpu性能高帶來的效果更加明顯。

3、磁盤

對於es的生產環境來說,磁盤是非常重要的,尤其是對那些大量寫入的es集羣,比如互聯網公司將每天的實時日誌數據以高併發的速度寫入es集羣。在服務器上,磁盤是最慢的那個資源,所以對於大量寫入的es集羣來說,會很容易因爲磁盤的讀寫性能造成整個集羣的性能瓶頸。

如果我們能夠使用SSD固態硬盤,而不是機械硬盤,那麼當然是最好的,SSD的性能比機械硬盤可以高很多倍,可以讓es的讀寫性能都高很多倍。所以,如果公司出的起錢大量使用固態硬盤,那麼當然是最好的。

連我的筆記本電腦,都是有100多G的SSD啊,還有1T的機械硬盤

如果我們在用SSD硬盤的化,那麼需要檢查我們的I/O scheduler,需要正確的配置IO scheduler。當我們將數據寫入磁盤時,IO scheduler會決定什麼時候數據纔會真正的寫入磁盤,而不是停留在os cache內存緩衝中。大多數機器上,默認的IO scheduler是cfq,也就是completely fair queuing。

這個scheduler會給每個進程都分配一些時間分片,time slice,然後會優化每個進程的數據如何寫入磁盤中,優化的思路主要 是根據磁盤的物理佈局來決定如何將數據寫入磁盤,進而提升寫入磁盤的性能。這是針對機械硬盤做出的優化,因爲機械硬盤是一種旋轉存儲介質,是通過機械旋轉磁盤+磁頭進行磁盤讀寫的機制。

但是scheduler的這種默認的執行機制,對於SSD來說是不太高效的,因爲SSD跟機械硬盤是不一樣的,SSD不涉及到機械磁盤旋轉和磁頭讀取這種傳統的讀寫機制。對於SSD來說,應該用deadline/noop scheduler。deadline scheduler會基於寫操作被pending了多長時間來進行寫磁盤優化,而noop scheduler就是一個簡單的FIFO隊列先進先出的機制。

調整io scheduler可以帶來很大的性能提升,甚至可以達到數百倍。

如果我們沒有辦法使用SSD,只能使用機械硬盤,那麼至少得儘量正確讀寫速度最快的磁盤,比如高性能的服務器磁盤。

此外,使用RAID 0也是一種提升磁盤讀寫速度的高效的方式,無論是對於機械硬盤,還是SSD,都一樣。RAID 0也被稱之爲條帶式存儲機制,striping,在RAID各種級別中性能是最高的。RAID 0的基本原理,是把連續的數據分散存儲到多個磁盤上進行讀寫,也就是對數據進行條帶式存儲。這樣系統的磁盤讀寫請求就可以被分散到多個磁盤上並行執行。但是沒有必要使用鏡像或者RAID的其他模式,因爲我們不需要通過RAID來實現數據高可用存儲,es的replica副本機制本身已經實現了數據高可用存儲。

最後,我們要避免跟網絡相關的存儲模式,network-attached storage,NAS,比如基於網絡的分佈式存儲模式。雖然很多供應商都說他們的NAS解決方案性能非常高,而且比本地存儲的可靠性更高。但是實際上用起來會有很多性能和可靠性上的風險,一般因爲網絡傳輸會造成較高的延時,同時還有單點故障的風險。

4、網絡

對於es這種分佈式系統來說,快速而且可靠的網絡是非常的重要的。因爲高速網絡通信可以讓es的節點間通信達到低延時的效果,高帶寬可以讓shard的移動和恢復,以及分配等操作更加的快速。現代的數據中心的網絡對於大多數的集羣來說,性能都足夠高了。比如千兆網卡,這都是可以的。

但是要避免一個集羣橫跨多個數據中心,比如異地多機房部署一個集羣,因爲那樣的話跨機房,跨地域的傳輸會導致網絡通信和數據傳輸性能較差。es集羣是一種p2p模式的分佈式系統架構,不是master-slave主從分佈式系統。在es集羣中,所有的node都是相等的,任意兩個node間的互相通信都是很頻繁和正常的。因此如果部署在異地多機房,那麼可能會導致node間頻繁跨地域進行通信,通信延時會非常高,甚至造成集羣運行頻繁不正常。

就跟NAS存儲模式一樣,很多供應商都說跨地域的多數據中心是非常可靠的,而且低延時的。一般來說,可能的確是這樣,但是一旦發生了網絡故障,那麼集羣就完了。通常來說,跨地域多機房部署一個es集羣帶來的效益,遠遠低於維護這樣的集羣所帶來的額外成本。

5、自建集羣 vs 雲部署

現在一般很容易就可以拿到高性能的機器來部署集羣:很多高性能的機器可以有上百G的內存資源,還有幾十個cpu core。但是同時我們也可以再雲供應商上,比如阿里雲,租用大量的小資源的虛擬機。那麼對於自己購買昂貴高性能服務器自建集羣,以及租用雲機器來部署,該選擇哪種方案呢?

你是自己購買5臺,比如說,8核64G的物理機,搭建es集羣

或者是,比如說,上阿里雲,或者其他的雲服務,購買了2核4G,16臺,虛擬機,搭建es集羣

你上阿里雲,也可以買到大資源量的虛擬機,4/8/16核64G

一般來說,對於es集羣而言,是建議擁有少數機器,但是每個機器的資源都非常多,儘量避免擁有大量的少資源的虛擬機。因爲對於運維和管理來說,管理5個物理機組成的es集羣,遠遠比管理100個虛擬機組成的es集羣要簡單的多。

同時即使是自建集羣,也要儘量避免那種超大資源量的超級服務器,因爲那樣可能造成資源無法完全利用,然後在一個物理機上部署多個es節點,這會導致我們的集羣管理更加的複雜。

6、JVM

對於最新的es版本,一般多建議用最新的jvm版本,除非es明確說明要用哪個jdk版本。es和lucene都是一種滿足特殊需求的軟件,lucene的單元測試和集成測試中,經常會發現jvm自身的一些bug。這些bug涵蓋的範圍很廣,因此儘量用最新的jvm版本,bug會少一些。

就目前es 5.x版本而言,建議用jdk 8,而不是jdk 7,同時jdk 6已經不再被支持了。

如果我們用java編寫es應用程序,而且在使用transport client或者node client,要確保運行我們的應用程序的jvm版本跟es服務器運行的jvm版本是一樣的。在es中,有些java的本地序列化機制都被使用了,比如ip地址,異常信息,等等。而jvm可能在不同的minor版本之間修改序列化格式,所以如果client和server的jvm版本不一致,可能有序列化的問題。

同時官方推薦,絕對不要隨便調整jvm的設置。雖然jvm有幾百個配置選項,而且我們可以手動調優jvm的幾乎方方面面。同時遇到一個性能場景的時候,每個人都會第一時間想到去調優jvm,但是es官方還是推薦我們不要隨便調節jvm參數。因爲es是一個非常複雜的分佈式軟件系統,而且es的默認jvm配置都是基於真實業務場景中長期的實踐得到的。隨便調節jvm配置反而有可能導致集羣性能變得更加差,以及出現一些未知的問題。反而是很多情況下,將自定義的jvm配置全部刪除,性能是保持的最好的。

7、容量規劃

在規劃你的es集羣的時候,一般要規劃你需要多少臺服務器,每臺服務器要有多少資源,能夠支撐你預計的多大的數據量。但是這個東西其實不是一概而論的,要視具體的讀寫場景,包括你執行多麼複雜的操作,讀寫QPS來決定的。不過一般而言,根據講師的實際經驗,對於很多的中小型公司,都是建議es集羣承載的數據量在10億規模以內。用最合理的技術做最合理的事情。

這裏可以給出幾個在國內es非常適合的幾個場景,es是做搜索的,當然可以做某個系統的搜索引擎。比如網站或者app的搜索引擎,或者是某些軟件系統的搜索引擎,此外es還可以用來做數據分析。那麼針對這幾個不同的場景,都可以給出具體建議。比如做網站或者app的搜索引擎,一般數據量會相對來說大一些,但是通常而言,一個網站或者app的內容都是有限的,不會無限膨脹,通常數據量從百萬級到億級不等,因此用於搜索的數據都放在es中是合理的。

然後一些軟件系統或者特殊項目的搜索引擎,根據項目情況不同,數據量也是從百萬量級到幾十億,甚至幾百億,或者每日增量幾億,都有可能,那麼此時就要根據具體的業務場景來決定了。如果數據量特別大,日增量都幾億規模,那麼其實建議不要將每天全量的數據都寫入es中,es也不適合這種無限規模膨脹的場景。es是很耗費內存的,無限膨脹的數據量,會導致我們無法提供足夠的資源來支撐這麼大的數據量。可以考慮是不是就將部分熱數據,比如最近幾天的數據,放到es中做高頻高性能搜索,然後將大量的很少訪問的冷數據放大數據系統做離線批量處理,比如hadoop系統裏面。

比如說,你預計一下,你的數據量有多大,需要多少臺機器,每臺機器要多少資源,來支撐,可以達到多大的性能

數據量 -> 性能,10億 -> 1s

es達到ms級的化,你必須要有足夠的os cache去緩存幾乎大部分的索引數據

10億,每條數據是多大,比如多少個字節,1k -> 100G

5臺,64G,8核,300G -> 100G總數據量,300G,一般要分給es jvm heap,150G -> 100G,100G落地到磁盤文件加入很多es自己的信息,100G -> 200G

200G落地磁盤的數據,物理內存剩餘的只有150G,可能還有一些操作系統,還有其他的損耗100G

200G落地磁盤的數據,100G物理內存可以用來做os cache,50%的概率是基於os cache做磁盤索引文件的讀寫,幾秒,很正常啦。。。

根據我們的實踐經驗而言,一般來說,除非是你的機器的內存資源,完全可以容納所有的落地的磁盤文件的os cache,ms,否則的話,如果不是的話,會大量走磁盤,幾秒

同時如果數據量在10億以內的規模,那麼一般而言,如果提供5臺以上的機器,每臺機器的配置到8核64G的配置,一般而言都能hold住。當然,這個也看具體的使用場景,如果你讀寫特別頻繁,或者查詢特別複雜,那麼可能還需要更多的機器資源。如果你要承載更大的數據量,那麼就相應的提供更多的機器和資源。

要提升你的es的性能,最重要的,還是說規劃合理的數據量,物理內存資源大小,os cache

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章