本篇開始介紹Elasticsearch生產集羣的搭建及相關參數的配置。java
咱們從開始編程就接觸過各類各樣的組件,而每種功能的組件,對硬件要求的特性都不太相同,有的須要很強的CPU計算能力,有的對內存需求量大,有的對網卡要求高等待,下面咱們討論一下ES集羣對幾種硬件的特性需求。node
ES集羣對CPU的要求相對低一些,畢竟純計算的比重要小一些,選用主流的CPU,2核到8核的均可以。編程
若是有兩種CPU能夠挑選,一種是主頻高但核數少的CPU,另外一種是主頻通常核數多的CPU,確定選後一種,由於多核的CPU能夠提供更多的併發處理能力,遠比單核高性能帶來的效益要高。api
ES集羣對內存的要求很高,部署ES集羣時,要把大部分資源投入到內存當中。內存分配主要有兩部分,JVM heap內存(堆內存)和OS Cache內存。緩存
JVM heap內存用得很少,主要是OS Cache,咱們知道,ES創建的倒排索引,正排索引,過濾器緩存,都是優先放在內存當中的,OS Cache的大小直接決定搜索的性能,若是OS Cache不夠,ES搜索等操做只有被迫讀硬盤,延時就會從毫秒級升到秒級。安全
OS Cache具體在多大才算夠,取決於數據量,若是是百萬級別的數據,16GB左右應該能夠接受,若是是億級,通常單節點都是64GB內存。生產環境最低要求內存應不低於8GB。服務器
硬盤成本自己比較便宜,能用SSD就用SSD,訪問速度確定比機械硬盤快,預估好數據量後就儘量多規劃一些容量。微信
另外儘可能使用本地存儲,網絡存儲還依賴於網絡傳輸,這個容易形成一些延遲。網絡
對ES集羣這種分佈式系統來講,快速而且可靠的網絡仍是比較重要的,shard的分配和rebalance都須要佔用大量的帶寬,集羣最好部署在同一個局域網內,異地容災等跨數據中心的部署方案,要考慮到網絡故障帶來的影響。架構
使用ES官網推薦的JDK版本,服務端和客戶端儘可能使用同一個版本的JDK。
涉及到ES服務端的JVM調優設置,保持原樣不要輕易改動,畢竟ES已經花了大量人力物力驗證過的,隨意調整jvm參數可能拔苗助長。
規劃集羣裏,要規劃好投入幾臺服務器,數據量上限是多少,業務模型數據讀寫的比例是多少,歷史數據的遷移方案等,通常來講,百萬到10億內的數據量,使用ES集羣仍是可以支撐下來的,ES節點數建議不要超過100個。
舉個例子:數據量10億之內,部署5臺服務器,8核64GB內存,是可以支撐的。
咱們使用Linux虛擬機來演示一個生產ES集羣的搭建。咱們建立4臺虛擬機,每臺2核CPU,4GB內存,操做系統爲CentOS 7 64bit。
虛擬機我用的是VMware workstation,有用virtual box也行,CentOS 七、JDK的安裝不贅述。記得把CentOS的防火牆關了。
修改每臺機器的hostname信息,命令vi /etc/hostname
,修改文件,保存便可,建議修改爲elasticsearch01,elasticsearch02,elasticsearch03,elasticsearch04。
假定咱們4臺虛擬機的域名和IP是這樣分配的:
192.168.17.138 elasticsearch01 192.168.17.137 elasticsearch02 192.168.17.132 elasticsearch03 192.168.17.139 elasticsearch04
把這段配置放在 /etc/hosts
文件末尾,4臺機器作相同的配置。
這4臺機器之間,能夠配置免密登陸,如在elasticsearch01機器上,咱們執行如下操做:
ssh-keygen -t rsa
一直輸入回車,不要設置密碼默認會將公鑰放在/root/.ssh目錄下生成id_rsa.pub和id_rsa兩個文件
cp id_rsa.pub authorized_keys
ssh-copy-id -i elasticsearch02 ssh-copy-id -i elasticsearch03 ssh-copy-id -i elasticsearch03
拷貝完成後,能夠在目標機器上/root/.ssh/
目錄下看到多了一個authorized_keys文件。
ssh elasticsearch02
,若是不須要輸入密碼就能登陸到elasticsearch02,說明配置成功,其餘機器相似。這4臺機器也能夠相互作ssh免密設置。
這裏補充一點免密登陸的方向性問題,上面的案例是在elasticsearch01機器生成的公鑰,而且發送給了elasticsearch02等三臺機器,那麼我從elasticsearch01跳到elasticsearch02是不須要密碼的,反過來從elasticsearch02登陸到elasticsearch01,仍是須要密碼的。
最後補充幾個經常使用檢查命令:
這裏選用的JDK版本爲1.8.0_211,Elasticsearch版本爲6.3.1,自行安裝不贅述。
ES解壓後的目錄結構:
# 用 "tree -L 1" 命令獲得的樹狀結構 . ├── bin ├── config ├── lib ├── LICENSE.txt ├── logs ├── modules ├── NOTICE.txt ├── plugins └── README.textile
在config目錄下的文件,包含了ES的基本配置信息:
. ├── elasticsearch.yml ├── jvm.options ├── log4j2.properties ├── role_mapping.yml ├── roles.yml ├── users └── users_roles
Elasticsearch的配置項比較豐富而且默認配置已經很是優秀了,基本上咱們須要改動的是跟服務器環境相關的配置,如IP地址,集羣名稱,數據存儲位置,日誌存儲位置等外圍參數,涉及到內部機制及JVM參數的,通常不干預,不恰當的JVM參數調整反而會致使集羣出現性能故障,若是沒有充足的理由或數據驗證結果,不要輕易嘗試修改。
在elasticsearch.yml文件裏這項配置表示集羣名稱,配置項默認是註釋掉的,集羣名稱默認爲elasticsearch。
#cluster.name: my-application
這個配置項強烈建議打開,用項目約定的命名規範進行重命名,而且將研發環境、測試環境、STG準生產環境、生產環境分別命名,如elasticsearch_music_app_dev表示研發環境,elasticsearch_music_app_sit表示測試環境,elasticsearch_music_app_pro表示生產環境等。避免開發測試環境連錯環境,無心中加入集羣致使數據問題。
cluster.name: elasticsearch_music_app_pro
節點名稱的配置項
#node.name: node-1
默認也是註釋掉的,ES啓動時會分配一個隨機的名稱,建議仍是自行分配一個名稱,這樣容易記住是哪臺機器,如
node.name: es_node_001_data
涉及到文件路徑的幾個參數,主要有數據、日誌、插件等,默認這幾個地址都是在Elasticsearch安裝的根目錄下,但Elasticsearch升級時,有些目錄可能會有影響,安全起見,能夠單獨設置目錄。
# # ----------------------------------- Paths ------------------------------------ # # Path to directory where to store the data (separate multiple locations by comma): # #path.data: /path/to/data # # Path to log files: # #path.logs: /path/to/logs #
例如咱們能夠在/var
目錄下建立相應的文件夾,而且賦予相應的讀寫權限,如:
path.data: /var/es/data path.logs: /var/es/logs
log4j2.properties文件,ES日誌框架選用的是log4j2,也就是log4j的進化版本,對Java技術棧熟悉的童鞋,看到這個配置文件會很是熟悉,默認的日誌輸入配置、格式均能知足平常的故障定位和分析,也不須要什麼改動。
默認是一天生成一個日期文件,若是ES承載的數據量特別大,能夠調整日誌文件產生頻率和每一個日誌文件的大小,以及ES最多存儲日誌的大小、數量。
Zen Discovery是Elasticsearch集羣發現機制的默認實現,底層通訊依賴transport組件,咱們完成Elasticsearch集羣的配置主要有下面幾個參數:
Elasticsearch集羣是點對點(P2P)的分佈式系統架構,數據索引、搜索操做是node之間直接通訊的,沒有中心式的master節點,但Elasticsearch集羣內的節點也分紅master node和data node兩種角色。
正常狀況下,Elasticsearch集羣只有一個master節點,它負責維護整個集羣的狀態信息,集羣的元數據信息,有新的node加入或集羣內node宕機下線時,從新分配shard,並同步node的狀態信息給全部的node節點,這樣全部的node節點都有一份完整的cluster state信息。
集羣發現的通常步驟以下:
node.master設置爲true的,將成爲master eligible node,也叫master候選節點,只有master eligible node才能被選舉成master node。若是是個小集羣,那麼全部節點均可以是master eligible node,10個節點以上的集羣,能夠考慮拆分master node和data node,通常建議master eligible node給3個便可。
master選舉過程是自動完成的,有幾個參數能夠影響選舉的過程:
有兩種集羣故障探查機制
有下面三個參數用來配置集羣故障的探查過程:
master node是集羣中惟一能夠對cluster state進行更新的node。更新的步驟以下:
discovery.zen.publish_timeout默認是30s,這個超時等待時長是從plublish cluster state開始計算的。
咱們能夠參照此圖:
Elasticsearch集羣中,master node扮演着很是重要的角色,若是master node宕機了,那豈不是羣龍無首了?雖然有master選舉,但這個也是要時間的,沒有master node那段空檔期集羣該怎麼辦?
說了一半,基本上是完了,但咱們也能夠設置,羣龍無首時哪些操做能夠作,哪些操做不能作。
discovery.zen.no_master_block配置項能夠控制在羣龍無首時的策略:
在Elasticsearch集羣中,master node很是重要,而且只有一個,至關於整個集羣的大腦,控制將整個集羣狀態的更新,若是Elasticsearch集羣節點之間出現區域性的網絡中斷,好比10個節點的Elasticsearch集羣,4臺node部署在機房A區,6臺node部署在機房B區,若是A區與B區的交換機故障,致使兩個區隔離開來了,那麼沒有master node的那個區,會觸發master選舉,若是選舉了新的master,那麼整個集羣就會出現兩個master node,這種現象叫作腦分裂。
這樣現象很嚴重,會破壞集羣的數據,該如何避免呢?
回到咱們前面提到的discovery.zen.minimum_master_nodes
參數,這個值的正確設置,能夠避免上述的腦分裂問題。
discovery.zen.minimum_master_nodes
參數表示至少須要多少個master eligible node,才能夠成功地選舉出master,不然不進行選舉。
足夠的master eligible node計算公式:
quorum = master_eligible_nodes / 2 + 1
如上圖咱們10個node的集羣,若是所有是master eligible node,那麼quorum = 10/2 + 1 = 6。
若是咱們有3個master eligible node,7個data node,那麼quorum = 3/2 + 1 = 2。
若是集羣只有2個節點,而且全是master eligible node,那麼quorum = 2/2 + 1 = 2,問題就來了,若是隨便一個node宕機,在只剩下一個node狀況下,沒法知足quorum的值,master永遠選舉不成功,集羣就完全沒法寫入了,因此只能設置成1,後果是隻要這兩個node之間網絡斷了,就會發生腦分裂的現象。
因此一個Elasticsearch集羣至少得有3個node,所有爲master eligible node的話,quorum = 3/2 + 1 = 2。若是咱們設置minimum_master_nodes=2,分析一下會不會出現腦分裂的問題。
場景一:A區一個node,爲master,B區兩個node,爲master eligible node
A區由於只剩下一個node,沒法知足quorum的條件,此時master取消當前的master角色,且沒法選舉成功。
B區兩個master eligible node,知足quorum條件,成功選舉出master。
此時集羣仍是隻有一個master,待網絡故障恢復後,集羣數據正常。
場景二:A區一個node,爲master eligible node,B區2個node,其中一個是master
A區只有一個master eligible node,不知足quorum的條件,沒法進行選舉。
B區本來的master存在,不須要進行選舉,而且滿quorum的條件,master角色能夠保留。
此時集羣仍是一個master,正常。
綜上所述:3個節點的集羣,所有爲master eligible node,配置discovery.zen.minimum_master_nodes: 2,就能夠避免腦裂問題的產生。
由於集羣是能夠動態增長和下線節點的,quorum的值也會跟着改變。minimum_master_nodes參數值須要經過api隨時修改的,特別是在節點上線和下線的時候,都須要做出對應的修改。並且一旦修改事後,這個配置就會持久化保存下來。
修改api請求以下:
PUT /_cluster/settings { "persistent" : { "discovery.zen.minimum_master_nodes" : 2 } }
響應報文:
{ "acknowledged": true, "persistent": { "discovery": { "zen": { "minimum_master_nodes": "2" } } }, "transient": {} }
也能夠經過命令查詢當前的配置:
GET /_cluster/settings
響應結果以下:
{ "persistent": { "discovery": { "zen": { "minimum_master_nodes": "1" } } }, "transient": {} }
上圖10個節點的集羣,假設全是master eligible node,按照上述的網絡故障,會不會出現腦分裂現象 ?配置項minimum_master_nodes最低要配置成多少,纔不會出現腦分裂的問題?
本篇主要介紹了Elasticsearch集羣的部署和參數設置等知識,大部分都不須要人工干預,默認值已是最優選,集羣發現機制和master選舉機制瞭解一下就OK。
專一Java高併發、分佈式架構,更多技術乾貨分享與心得,請關注公衆號:Java架構社區
能夠掃左邊二維碼添加好友,邀請你加入Java架構社區微信羣共同探討技術