Elasticsearch系列—生產集群部署(上)_網頁設計公司

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

概要

本篇開始介紹Elasticsearch生產集群的搭建及相關參數的配置。

ES集群的硬件特性

我們從開始編程就接觸過各種各樣的組件,而每種功能的組件,對硬件要求的特性都不太相同,有的需要很強的CPU計算能力,有的對內存需求量大,有的對網卡要求高等待,下面我們討論一下ES集群對幾種硬件的特性需求。

CPU

ES集群對CPU的要求相對低一些,畢竟純計算的比重要小一些,選用主流的CPU,2核到8核的都可以。

如果有兩種CPU可以挑選,一種是主頻高但核數少的CPU,另一種是主頻一般核數多的CPU,肯定選后一種,因為多核的CPU可以提供更多的併發處理能力,遠比單核高性能帶來的效益要高。

內存

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都需要佔用大量的帶寬,集群最好部署在同一個局域網內,異地容災等跨數據中心的部署方案,要考慮到網絡故障帶來的影響。

JVM選擇

使用ES官網推薦的JDK版本,服務端和客戶端盡量使用同一個版本的JDK。

涉及到ES服務端的JVM調優設置,保持原樣不要輕易改動,畢竟ES已經花了大量人力物力驗證過的,隨意調整jvm參數可能適得其反。

容量規劃

規劃集群里,要規劃好投入幾台服務器,數據量上限是多少,業務模型數據讀寫的比例是多少,歷史數據的遷移方案等,一般來說,百萬到10億內的數據量,使用ES集群還是能夠支撐下來的,ES節點數建議不要超過100個。

舉個例子:數據量10億以內,部署5台服務器,8核64GB內存,是能夠支撐的。

生產案例模擬

Linux操作系統搭建

我們使用Linux虛擬機來演示一個生產ES集群的搭建。我們創建4台虛擬機,每台2核CPU,4GB內存,操作系統為CentOS 7 64bit。

虛擬機我用的是VMware workstation,有用virtual box也行,CentOS 7、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機器上,我們執行以下操作:

  1. 生成公鑰文件,命令:
ssh-keygen -t rsa

一直輸入回車,不要設置密碼默認會將公鑰放在/root/.ssh目錄下生成id_rsa.pub和id_rsa兩個文件

  1. 拷貝公鑰文件
cp id_rsa.pub authorized_keys
  1. 將公鑰文件拷貝到另外三台機器
ssh-copy-id -i elasticsearch02
ssh-copy-id -i elasticsearch03
ssh-copy-id -i elasticsearch03

拷貝完成后,可以在目標機器上/root/.ssh/目錄下看到多了一個authorized_keys文件。

  1. 嘗試免密登錄,在elasticsearch01機器上輸入ssh elasticsearch02,如果不需要輸入密碼就能登錄到elasticsearch02,說明配置成功,其他機器類似。

這4台機器也可以相互做ssh免密設置。

這裏補充一點免密登錄的方向性問題,上面的案例是在elasticsearch01機器生成的公鑰,並且發送給了elasticsearch02等三台機器,那麼我從elasticsearch01跳到elasticsearch02是不需要密碼的,反過來從elasticsearch02登錄到elasticsearch01,還是需要密碼的。

最後補充幾個常用檢查命令:

  • 檢查NetManager的狀態:systemctl status NetworkManager.service
  • 檢查NetManager管理的網絡接口:nmcli dev status
  • 檢查NetManager管理的網絡連接:nmcli connection show

Elasticsearch服務端

這裏選用的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
  • bin:存放es的一些可執行腳本,比如用於啟動進程的elasticsearch命令,以及用於安裝插件的elasticsearch-plugin插件
  • config:用於存放es的配置文件,比如elasticsearch.yml
  • logs:用於存放es的日誌文件
  • plugins:用於存放es的插件
  • data:用於存放es的數據文件的默認目錄,就是每個索引的shard的數據文件,一般會另外指定一個目錄。

Elasticsearch參數設置

在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最多存儲日誌的大小、數量。

Elasticsearch集群發現機制

配置參數

Zen Discovery是Elasticsearch集群發現機制的默認實現,底層通信依賴transport組件,我們完成Elasticsearch集群的配置主要有下面幾個參數:

  • cluster.name 指定集群的名稱。
  • node.name 節點名稱。
  • network.host 節點綁定的IP。
  • node.master 可選值為true/false,決定該節點類型為master eligible或data node。
  • discovery.zen.ping.unicast.hosts gossip路由服務的IP地址,即集群發現協議通信的公共節點,可以寫多個,有節點啟動時會向裏面的IP發送消息,獲取集群其他節點的信息,最後加入集群。

Elasticsearch集群是點對點(P2P)的分佈式系統架構,數據索引、搜索操作是node之間直接通信的,沒有中心式的master節點,但Elasticsearch集群內的節點也分成master node和data node兩種角色。

正常情況下,Elasticsearch集群只有一個master節點,它負責維護整個集群的狀態信息,集群的元數據信息,有新的node加入或集群內node宕機下線時,重新分配shard,並同步node的狀態信息給所有的node節點,這樣所有的node節點都有一份完整的cluster state信息。

集群發現的一般步驟如下:

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊

  1. 節點配置network.host綁定內網地址,配置各自的node.name信息,cluster.name設置為相同的值。
  2. discovery.zen.ping.unicast.hosts配置了幾個gossip路由的node。
  3. 所有node都可以發送ping消息到路由node,再從路由node獲取cluster state回來。
  4. 所有node執行master選舉。
  5. 所有node都會跟master進行通信,然後加入master的集群。

master選舉

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選舉過程是自動完成的,有幾個參數可以影響選舉的過程:

  • discovery.zen.ping_timeout: 選舉超時時間,默認3秒,網絡狀況不好時可以增加超時時間。

  • discovery.zen.join_timeout: 有新的node加入集群時,會發送一個join request到master node,同樣因為網絡原因可以調大,如果一次超時,默認最多重試20次。

  • discovery.zen.master_election.ignore_non_master_pings:如果master node意外宕機了,集群進行重新選舉,如果此值為true,那麼只有master eligible node才有資格被選為master。

  • discovery.zen.minimum_master_nodes: 新選舉master時,要求必須有多少個 master eligible node去連接那個新選舉的master。而且還用於設置一個集群中必須擁有的master eligible node。如果這些要求沒有被滿足,那麼master node就會被停止,然後會重新選舉一個新的master。這個參數必須設置為我們的master eligible node的quorum數量。一般避免說只有兩個master eligible node,因為2的quorum還是2。如果在那個情況下,任何一個master候選節點宕機了,集群就無法正常運作了。

集群故障探查

有兩種集群故障探查機制

  1. master主動對集群中所有的其他node發起ping命令,判斷它們是否是存活着的。
  2. 每個node向master node發送ping請求,判斷master node是否存活,否則就會發起一個選舉過程。

有下面三個參數用來配置集群故障的探查過程:

  • ping_interval:ping一次node的間隔時間,默認是1s
  • ping_timeout:每次ping的timeout等待時長,默認是30s
  • ping_retries:對node的ping請求失敗了,重試次數,默認3次。

集群狀態更新

master node是集群中唯一可以對cluster state進行更新的node。更新的步驟如下:

  1. master node收到更新事件,如shard移動,可能會有多條事件,但master node一次只處理一個集群狀態的更新事件。
  2. master node將事件更新到本地,併發布publish message到集群所有的node上。
  3. node接收publish message后,對這個message返回ack響應,但是不會立即更新。
  4. 如果master沒有在指定的時間內(discovery.zen.commit_timeout配置項,默認是30s),從至少N個節點(discovery.zen.minimum_master_nodes配置項)獲取ack響應,那麼這次cluster state change事件就會被reject,最終不會被提交。
  5. 如果在指定時間內,指定數量的node都返回了ack消息,那麼cluster state就會被commit,然後master node把 commit message發送給所有的node。所有的node接收到那個commit message之後,接着才會將之前接收到的集群狀態應用到自己本地的狀態副本中去。
  6. master會等待所有node的commit message 的ack消息,在一個等待超時時長內,如果接收到了響應,表示狀態更新成功,master node繼續處理內存queue中保存的下一個更新事件。

discovery.zen.publish_timeout默認是30s,這個超時等待時長是從plublish cluster state開始計算的。

我們可以參照此圖:

master node宕機問題

Elasticsearch集群中,master node扮演着非常重要的角色,如果master node宕機了,那豈不是群龍無首了?雖然有master選舉,但這個也是要時間的,沒有master node那段空檔期集群該怎麼辦?

說了一半,基本上是完了,但我們也可以設置,群龍無首時哪些操作可以做,哪些操作不能做。

discovery.zen.no_master_block配置項可以控制在群龍無首時的策略:

  • all: 一旦master宕機,那麼所有的操作都會被拒絕。
  • write:默認的選項,所有寫操作都會被拒絕,但是讀操作是被允許的。

split-brain(腦分裂問題)

在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,就可以避免腦裂問題的產生。

minimum_master_nodes動態修改

因為集群是可以動態增加和下線節點的,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架構社區微信群共同探討技術

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※想知道最厲害的網頁設計公司嚨底家"!

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

您可能也會喜歡…