一、概述
高可用性
Elasticsearch 作為一個搜索引擎,我們對它的基本要求就是存儲海量數據並且可以在非常短的時間內查詢到我們想要的信息。所以第一步我們需要保證的就是 Elasticsearch 的高可用性,什么是高可用性呢?它通常是指,通過設計減少系統不能提供服務的時間。假設系統一直能夠提供服務,我們說系統的可用性是 100%。如果系統在某個時刻宕掉了,比如某個網站在某個時間掛掉了,那么就可以它臨時是不可用的。所以,為了保證 Elasticsearch 的高可用性,我們就應該盡量減少 Elasticsearch 的不可用時間。
那么怎樣提高 Elasticsearch 的高可用性呢?這時集群的作用就體現出來了。假如 Elasticsearch 只放在一台服務器上,即單機運行,假如這台主機突然斷網了或者被攻擊了,那么整個 Elasticsearch 的服務就不可用了。但如果改成 Elasticsearch 集群的話,有一台主機宕機了,還有其他的主機可以支撐,這樣就仍然可以保證服務是可用的。
那可能有的小伙伴就會說了,那假如一台主機宕機了,那么不就無法訪問這台主機的數據了嗎?那假如我要訪問的數據正好存在這台主機上,那不就獲取不到了嗎?難道其他的主機里面也存了一份一模一樣的數據?那這豈不是很浪費嗎?
為了解答這個問題,這里就引出了 Elasticsearch 的信息存儲機制了。首先解答上面的問題,一台主機宕機了,這台主機里面存的數據依然是可以被訪問到的,因為在其他的主機上也有備份,但備份的時候也不是整台主機備份,是分片備份的,那這里就又引出了一個概念——分片。
分片,英文叫做 Shard,顧名思義,分片就是對數據切分成了多個部分。我們知道 Elasticsearch 中一個索引(Index)相當於是一個數據庫,如存某網站的用戶信息,我們就建一個名為 user 的索引。但索引存儲的時候並不是整個存一起的,它是被分片存儲的,Elasticsearch 默認會把一個索引分成五個分片,當然這個數字是可以自定義的。分片是數據的容器,數據保存在分片內,分片又被分配到集群內的各個節點里。當你的集群規模擴大或者縮小時, Elasticsearch 會自動的在各節點中遷移分片,使得數據仍然均勻分布在集群里,所以相當於一份數據被分成了多份並保存在不同的主機上。
那這還是沒解決問題啊,如果一台主機掛掉了,那么這個分片里面的數據不就無法訪問了?別的主機都是存儲的其他的分片。其實是可以訪問的,因為其他主機存儲了這個分片的備份,叫做副本,這里就引出了另外一個概念——副本。
副本,英文叫做 Replica,同樣顧名思義,副本就是對原分片的復制,和原分片的內容是一樣的,Elasticsearch 默認會生成一份副本,所以相當於是五個原分片和五個分片副本,相當於一份數據存了兩份,並分了十個分片,當然副本的數量也是可以自定義的。這時我們只需要將某個分片的副本存在另外一台主機上,這樣當某台主機宕機了,我們依然還可以從另外一台主機的副本中找到對應的數據。所以從外部來看,數據結果是沒有任何區別的。
一般來說,Elasticsearch 會盡量把一個索引的不同分片存儲在不同的主機上,分片的副本也盡可能存在不同的主機上,這樣可以提高容錯率,從而提高高可用性。
但這時假如你只有一台主機,那不就沒辦法了嗎?分片和副本其實是沒意義的,一台主機掛掉了,就全掛掉了。
健康狀態
針對一個索引,Elasticsearch 中其實有專門的衡量索引健康狀況的標志,分為三個等級:
-
green,綠色。這代表所有的主分片和副本分片都已分配。你的集群是 100% 可用的。
-
yellow,黃色。所有的主分片已經分片了,但至少還有一個副本是缺失的。不會有數據丟失,所以搜索結果依然是完整的。不過,你的高可用性在某種程度上被弱化。如果更多的分片消失,你就會丟數據了。所以可把 yellow 想象成一個需要及時調查的警告。
-
red,紅色。至少一個主分片以及它的全部副本都在缺失中。這意味着你在缺少數據:搜索只能返回部分數據,而分配到這個分片上的寫入請求會返回一個異常。
如果你只有一台主機的話,其實索引的健康狀況也是 yellow,因為一台主機,集群沒有其他的主機可以防止副本,所以說,這就是一個不健康的狀態,因此集群也是十分有必要的。
存儲空間
另外,既然是群集,那么存儲空間肯定也是聯合起來的,假如一台主機的存儲空間是固定的,那么集群它相對於單個主機也有更多的存儲空間,可存儲的數據量也更大。
所以綜上所述,我們需要一個集群!
二、詳細了解 Elasticsearch 集群
接下來我們再來了解下集群的結構是怎樣的。
首先我們應該清楚多台主機構成了一個集群,每台主機稱作一個節點(Node)。
如圖就是一個三節點的集群:
在圖中,每個 Node 都有三個分片,其中 P 開頭的代表 Primary 分片,即主分片,R 開頭的代表 Replica 分片,即副本分片。所以圖中主分片 1、2,副本分片 0 儲存在 1 號節點,副本分片 0、1、2 儲存在 2 號節點,主分片 0 和副本分片 1、2 儲存在 3 號節點,一共是 3 個主分片和 6 個副本分片。同時我們還注意到 1 號節點還有個 MASTER 的標識,這代表它是一個主節點,它相比其他的節點更加特殊,它有權限控制整個集群,比如資源的分配、節點的修改等等。
這里就引出了一個概念就是節點的類型,我們可以將節點分為這么四個類型:
-
主節點:即 Master 節點。主節點的主要職責是和集群操作相關的內容,如創建或刪除索引,跟蹤哪些節點是群集的一部分,並決定哪些分片分配給相關的節點。穩定的主節點對集群的健康是非常重要的。默認情況下任何一個集群中的節點都有可能被選為主節點。索引數據和搜索查詢等操作會占用大量的cpu,內存,io資源,為了確保一個集群的穩定,分離主節點和數據節點是一個比較好的選擇。雖然主節點也可以協調節點,路由搜索和從客戶端新增數據到數據節點,但最好不要使用這些專用的主節點。一個重要的原則是,盡可能做盡量少的工作。
-
數據節點:即 Data 節點。數據節點主要是存儲索引數據的節點,主要對文檔進行增刪改查操作,聚合操作等。數據節點對 CPU、內存、IO 要求較高,在優化的時候需要監控數據節點的狀態,當資源不夠的時候,需要在集群中添加新的節點。
-
負載均衡節點:也稱作 Client 節點,也稱作客戶端節點。當一個節點既不配置為主節點,也不配置為數據節點時,該節點只能處理路由請求,處理搜索,分發索引操作等,從本質上來說該客戶節點表現為智能負載平衡器。獨立的客戶端節點在一個比較大的集群中是非常有用的,他協調主節點和數據節點,客戶端節點加入集群可以得到集群的狀態,根據集群的狀態可以直接路由請求。
-
預處理節點:也稱作 Ingest 節點,在索引數據之前可以先對數據做預處理操作,所有節點其實默認都是支持 Ingest 操作的,也可以專門將某個節點配置為 Ingest 節點。
以上就是節點幾種類型,一個節點其實可以對應不同的類型,如一個節點可以同時成為主節點和數據節點和預處理節點,但如果一個節點既不是主節點也不是數據節點,那么它就是負載均衡節點。具體的類型可以通過具體的配置文件來設置。
三、搭建
環境說明
系統 | docker | ip | es節點名 | 配置 |
---|---|---|---|---|
centos 7.6 | 19.03.5 | 192.168.31.149 | node-1 | 2核4G |
centos 7.6 | 19.03.5 | 192.168.31.181 | node-2 | 2核4G |
centos 7.6 | 19.03.5 | 192.168.31.233 | node-3 | 2核4G |
修改內核參數
登錄到每一台服務器,修改內核參數
vi /etc/sysctl.conf
修改以下參數,如果沒有,則添加
vm.max_map_count=262144
刷新參數
sysctl -p
啟動elasticsearch
node-1執行
docker run -d \ --name=elasticsearch \ --restart=always \ -p 9200:9200 \ -p 9300:9300 \ -e node.name=node-1 \ -e network.publish_host=192.168.31.149 \ -e network.host=0.0.0.0 \ -e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.name=es-cluster \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ elasticsearch:7.5.1
環境變量說明:
node.name 節點名稱,集群模式下每個節點名稱唯一
network.publish_host 用於集群內各機器間通信,對外使用,其他機器訪問本機器的es服務,一般為本機宿主機IP
network.host 設置綁定的ip地址,可以是ipv4或ipv6的,默認為0.0.0.0,即本機
discovery.seed_hosts es7.0之后新增的寫法,寫入候選主節點的設備地址,在開啟服務后,如果master掛了,哪些可以被投票選為主節點
cluster.initial_master_nodes es7.0之后新增的配置,初始化一個新的集群時需要此配置來選舉master
cluster.name 集群名稱,相同名稱為一個集群, 三個es節點須一致
ES_JAVA_OPTS 設置內存,如內存不足,可以嘗試調低點
node-2執行
docker run -d \ --name=elasticsearch \ --restart=always \ -p 9200:9200 \ -p 9300:9300 \ -e node.name=node-2 \ -e network.publish_host=192.168.31.181 \ -e network.host=0.0.0.0 \ -e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.name=es-cluster \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ elasticsearch:7.5.1
注意:修改node.name和network.publish_host參數即可
node-3執行
docker run -d \ --name=elasticsearch \ --restart=always \ -p 9200:9200 \ -p 9300:9300 \ -e node.name=node-3 \ -e network.publish_host=192.168.31.233 \ -e network.host=0.0.0.0 \ -e discovery.seed_hosts=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.initial_master_nodes=192.168.31.149,192.168.31.181,192.168.31.233 \ -e cluster.name=es-cluster \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ elasticsearch:7.5.1
注意:修改node.name和network.publish_host參數即可
修改配置文件
默認的elasticsearch不允許跨域,因此elasticsearch head插件無法連接。需要修改配置文件才行!
拷貝數據文件
登錄node-1,node-2,node-3分別執行:
mkdir -p /data/elk7 docker cp elasticsearch:/usr/share/elasticsearch /data/elk7/
編輯配置文件
vi /data/elk7/elasticsearch/config/elasticsearch.yml
內容如下:
cluster.name: "docker-cluster" network.host: 0.0.0.0 http.cors.enabled: true http.cors.allow-origin: "*"
重啟eelasticsearch
docker restart elasticsearch
四、測試集群
查看集群健康狀態
http://192.168.31.149:9200/_cluster/health?pretty
效果如下:
可以看到集群節點有3個。
查看集群node狀態
http://192.168.31.149:9200/_cat/nodes?pretty
效果如下:
發現node-1前面有一個星號,表示它是主節點
使用elasticsearch head連接
可以看到,三台機器組成了es集群。集群的狀態為綠色,健康狀態。帶星標的節點els-node1為主節點(選舉)。還可以做一些增加/刪除索引,查詢等操作。
本文參考鏈接: