文章很長,而且持續更新,建議收藏起來,慢慢讀!瘋狂創客圈總目錄 博客園版 為您奉上珍貴的學習資源 :
免費贈送 :《尼恩Java面試寶典》 持續更新+ 史上最全 + 面試必備 2000頁+ 面試必備 + 大廠必備 +漲薪必備
免費贈送 經典圖書:《Java高並發核心編程(卷1)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高並發核心編程(卷2)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高並發核心編程(卷3)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《尼恩Java面試寶典 最新版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 資源寶庫: Java 必備 百度網盤資源大合集 價值>10000元 加尼恩領取
背景:
下一個視頻版本,從架構師視角,尼恩為大家打造高可用、高並發中間件的原理與實操。
目標:通過視頻和博客的方式,為各位潛力架構師,徹底介紹清楚架構師必須掌握的高可用、高並發環境,包括但不限於:
-
高可用、高並發nginx架構的原理與實操
-
高可用、高並發mysql架構的原理與實操
-
高可用、高並發nacos架構的原理與實操
-
高可用、高並發rocketmq架構的原理與實操
-
高可用、高並發es架構的原理與實操
-
高可用、高並發minio架構的原理與實操
why 高可用、高並發中間件的原理與實操:
實際的開發過程中,很多小伙伴聚焦crud開發,環境出了問題,都不能啟動。
作為架構師,或者未來想走向高端開發,或者做架構,必須掌握高可用、高並發中間件的原理,掌握其實操。
本系列博客的具體內容,請參見 Java 高並發 發燒友社群:瘋狂創客圈
ES是如何解決高可用
ES是一個分布式全文檢索框架,隱藏了復雜的處理機制,核心數據分片機制、集群發現、分片負載均衡請求路由。
ES的高可用架構,總體如下圖:
ES基本概念名詞
Cluster
代表一個集群,集群中有多個節點,其中有一個為主節點,這個主節點是可以通過選舉產生的,主從節點是對於集群內部來說的。
es的一個概念就是去中心化,字面上理解就是無中心節點,這是對於集群外部來說的,因為從外部來看es集群,在邏輯上是個整體,你與任何一個節點的通信和與整個es集群通信是等價的。
Shards
代表索引分片,es可以把一個完整的索引分成多個分片,這樣的好處是可以把一個大的索引拆分成多個,分布到不同的節點上。構成分布式搜索。
分片的數量只能在索引創建前指定,並且索引創建后不能更改。(why,大家可以獨立思考一下!)
分片數由index.number_of_shards在索引創建的時候指定,如果需要修改主分片數,需要重建索引:
1 按照需要創建一個新的索引;
2 reindex把索引現有的數據同步到新索引中;
3 別名綁定新創建的索引上;
規避主分片不能修改的問題的方法,官方的說明:
我們當前的選擇只有一個就是將數據重新索引至一個擁有更多分片的一個更大的索引,但這樣做將消耗的時間是我們無法提供的。
通過事先規划,我們可以使用 預分配 的方式來完全避免這個問題。
注意:ES在不斷升級,在ES6.1開始,已經%50支持修改主分片的操作。
在老版本的ES(例如2.3版本)中, index的shard數量定好后,就不能再修改,除非重建數據才能實現。
從ES6.1開始,ES 支持split操作,可以在線操作擴大shard的數量(注意:操作期間也需要對index鎖寫)
從ES7.0開始,split時候,不再需要加參數 index.number_of_routing_shards
在 這個split的過程中, 它會先復制全量數據,然后再去做刪除多余數據的操作,需要注意磁盤空間的占用。
所以,可以理解為,ES還是沒有完全 支持修改主分片的操作。 不到萬不得已,不建議在線修改主分片。
replicas
代表索引副本,es可以設置多個索引的副本。
副本的作用:
-
一是提高系統的容錯性,當某個節點某個分片損壞或丟失時可以從副本中恢復。
-
二是提高es的查詢效率,es會自動對搜索請求進行負載均衡。
Recovery
代表數據恢復或叫數據重新分布,es在有節點加入或退出時會根據機器的負載對索引分片進行重新分配;
掛掉的節點重新啟動時也會進行數據恢復。
總覽:ES集群中的五大角色
在Elasticsearch中,有五大角色,主要如下:
Master Node:主節點
主節點,該節點不和應用創建連接,每個節點都保存了集群狀態.
master節點控制整個集群的元數據。
只有Master Node節點可以修改節點狀態信息及元數據(metadata)的處理,比如索引的新增、刪除、分片路由分配、所有索引和相關 Mapping 、Setting 配置等等。
從資源占用的角度來說:master節點不占用磁盤IO和CPU,內存使用量一般, 沒有data 節點高
Master eligible nodes:合格主節點
合格節點,每個節點部署后不修改配置信息,默認就是一個 eligible 節點.
有資格成為Master節點但暫時並不是Master的節點被稱為 eligible 節點,該節點可以參加選主流程,成為Mastere節點.
該節點只是與集群保持心跳,判斷Master是否存活,如果Master故障則參加新一輪的Master選舉。
從資源占用的角度來說:eligible節點比Master節點更節省資源,因為它還未成為 Master 節點,只是有資格成功Master節點。
Data Node:數據節點
數據節點,改節點用於建立文檔索引, 接收 應用創建連接、接收索引請求,接收用戶的搜索請求
data節點真正存儲數據,ES集群的性能取決於該節點的個數(每個節點最優配置的情況下),
data節點的分片執行查詢語句獲得查詢結果后將結果反饋給Coordinating節點,在查詢的過程中非常消耗硬件資源,如果在分片配置及優化沒做好的情況下,進行一次查詢非常緩慢(硬件配置也要跟上數據量)。
數據節點:保存包含索引文檔的分片數據,執行CRUD、搜索、聚合相關的操作。屬於:內存、CPU、IO密集型,對硬件資源要求高。
從資源占用的角度來說:data節點會占用大量的CPU、IO和內存
Coordinating Node:協調節點(/路由節點/client節點)
協調節點,該節點專用與接收應用的查詢連接、接受搜索請求,但其本身不負責存儲數據
協調節點的職責:
接受客戶端搜索請求后將請求轉發到與查詢條件相關的多個data節點的分片上,然后多個data節點的分片執行查詢語句或者查詢結果再返回給協調節點,協調節點把各個data節點的返回結果進行整合、排序等一系列操作后再將最終結果返回給用戶請求。
搜索請求在兩個階段中執行(query 和 fetch),這兩個階段由接收客戶端請求的節點 - 協調節點協調。
- 在請求query 階段,協調節點將請求轉發到保存數據的數據節點。 每個數據節點在本地執行請求並將其結果返回給協調節點。
- 在收集fetch階段,協調節點將每個數據節點的結果匯集為單個全局結果集。
從資源占用的角度來說:協調節點,可當負責均衡節點,該節點不占用io、cpu和內存
Ingest Node:ingest節點
ingest 節點可以看作是數據前置處理轉換的節點,支持 pipeline管道 設置,可以使用 ingest 對數據進行過濾、轉換等操作,類似於 logstash 中 filter 的作用,功能相當強大。
Ingest節點處理時機——在數據被索引之前,通過預定義好的處理管道對數據進行預處理。默認情況下,所有節點都啟用Ingest,因此任何節點都可以處理Ingest任務。
我們也可以創建專用的Ingest節點。
詳解:Coordinating Only Nodes
ES 本身是一個分布式的計算集群,每個 Node 都可以響應用戶的請求,包括 Master Node、Data Node,它們都有完整的 Cluster State 信息。
正如我們知道的一樣,在某個 Node 收到用戶請求的時候,會將請求轉發到集群中所有索引相關的 Node 上,之后將每個 Node 的計算結果合並后返回給請求方。
我們暫且將這個 Node 稱為查詢節點,整個過程跟分布式數據庫原理類似。那問題來了,這個查詢節點如果在並發和數據量比較大的情況下,由於數據的聚合可能會讓內存和網絡出現瓶頸。
因此,在職責分離指導思想的前提下,這些操作我們也應該從這些角色中剝離出來,官方稱它是 Coordinating Nodes,只負責路由用戶的請求,包括讀、寫等操作,對內存、網絡和 CPU 要求比較高。
本質上,Coordinating Only Nodes 可以籠統的理解為是一個負載均衡器,或者反向代理,只負責讀,本身不寫數據。
它的配置是:
node.master: false
node.data: false
node.ingest: false
search.remote.connect: false
增加 Coordinating Nodes 的數量可以提高 API 請求響應的性能, 提升集群的吞吐量
我們也可以針對不同量級的 Index 分配獨立的 Coordinating Nodes 來滿足請求性能。
那是不是越多越好呢?
在一定范圍內是肯定的,但凡事有個度,過了負作用就會突顯,太多的話會給集群增加負擔。
詳解:Ingest Node:ingest節點
由於其他幾種類型節點和用途都很好理解,無非主節點、數據節點、路由節點。
但是,Ingest不好理解。
Ingest的用途:
可以把Ingest節點的功能抽象為:大數據處理環節的“ETL”——抽取、轉換、加載。
Ingest的用途:
1)ingest 節點可以看作是數據前置處理轉換的節點,支持 pipeline管道 設置,可以使用 ingest 對數據進行過濾、轉換等操作,類似於 logstash 中 filter 的作用,功能相當強大。
2)Ingest節點 可用於執行常見的數據轉換和豐富。 處理器配置為形成管道。 在寫入時,Ingest Node有20個內置處理器,例如grok,date,gsub,小寫/大寫,刪除和重命名。
3)在批量請求或索引操作之前,Ingest節點攔截請求,並對文檔進行處理。
Ingest的例子:
一個例子是,可以是日期處理器,其用於解析字段中的日期。
另一個例子是:轉換處理器,它將字段值轉換為目標類型,例如將字符串轉換為整數。
ingest 節點能解決什么問題?
上面的Ingest節點介紹太官方,看不大懂怎么辦?來個實戰場景例子吧。
思考問題1:線上寫入數據改字段需求
如何在數據寫入階段修改字段名(不是修改字段值)?
思考問題2:線上業務數據添加特定字段需求
如何在批量寫入數據的時候,每條document插入實時時間戳?
這時,腦海里開始對已有的知識點進行搜索。
針對思考問題1:字段值的修改無非:update,update_by_query?但是字段名呢?貌似沒有相關接口或實現。
針對思考問題2:插入的時候,業務層面處理,讀取當前時間並寫入貌似可以,有沒有不動業務層面的字段的方法呢?
答案是有的,這就是Ingest節點的妙處。
Ingest的實操體驗
針對問題1:
如何在數據寫入階段修改字段名(不是修改字段值)?
PUT _ingest/pipeline/rename_hostname
{
"processors": [
{
"field": "hostname",
"target_field": "host",
"ignore_missing": true
}
}
]
}
PUT server
POST server/values/?pipeline=rename_hostname
{
"hostname": "myserver"
}
如上,借助Ingest節點的 rename_hostname管道的預處理功能,實現了字段名稱的變更:由hostname改成host。
針對問題2:
線上業務數據添加特定字段需求**
PUT _ingest/pipeline/indexed_at
{
"description": "Adds indexed_at timestamp to documents",
"processors": [
{
"set": {
"field": "_source.indexed_at",
"value": "{{_ingest.timestamp}}"
}
}
]
}
PUT ms-test
{
"settings": {
"index.default_pipeline": "indexed_at"
}
}
POST ms-test/_doc/1
{"title":"just testing"}
如上,通過indexed_at管道的set處理器與ms-test的索引層面關聯操作, ms-test索引每插入一篇document,都會自動添加一個字段index_at=最新時間戳。
6.5版本ES驗證ok。
Ingest節點的核心原理
在實際文檔索引發生之前,使用Ingest節點預處理文檔。Ingest節點攔截批量和索引請求,它應用轉換,然后將文檔傳遞回索引或Bulk API。
強調一下: Ingest節點處理時機——在數據被索引之前,通過預定義好的處理管道對數據進行預處理。
默認情況下,所有節點都啟用Ingest,因此任何節點都可以處理Ingest任務。我們也可以創建專用的Ingest節點。
要禁用節點的Ingest功能,需要在elasticsearch.yml 設置如下:
node.ingest:false
Ingest節點的核心原理, 涉及幾個知識點:
1、預處理 pre-process
要在數據索引化(indexing)之前預處理文檔。
2、管道 pipeline
每個預處理過程可以指定包含一個或多個處理器的管道。
管道的實際組成:
{
"description" : "...",
"processors" : [ ... ]
}
description:管道功能描述。
processors:注意是數組,可以指定1個或多個處理器。
3、處理器 processors
每個處理器以某種特定方式轉換文檔。
例如,管道可能有一個從文檔中刪除字段的處理器,然后是另一個重命名字段的處理器。
這樣,再反過來看第4部分就很好理解了。
Ingest API
Ingest API共分為4種操作,分別對應:
- PUT(新增)、
- GET(獲取)、
- DELETE(刪除)、
- Simulate (仿真模擬)。
模擬管道AP Simulate 針對請求正文中提供的文檔集執行特定管道。
除此之外,高階操作包括:
- 1、支持復雜條件的Nested類型的操作;
- 2、限定條件的管道操作;
- 3、限定條件的正則操作等。
詳細內容,參見官網即可。
常見的處理器有如下28種,舉例:
- append處理器:添加1個或1組字段值;
- convert處理器:支持類型轉換。
建議:沒必要都過一遍,根據業務需求,反查文檔即可。
Ingest節點和Logstash Filter 啥區別?
業務選型中,肯定會問到這個問題。
- 區別一:支持的數據源不同。
Logstash:大量的輸入和輸出插件(比如:kafka,redis等)可供使用,還可用來支持一系列不同的架構。
Ingest節點:不能從外部來源(例如消息隊列或數據庫)提取數據,必須批量bulk或索引index請求將數據推送到 Elasticsearch. - 區別二:應對數據激增的能力不同。
Logstash:Logstash 可在本地對數據進行緩沖以應對采集驟升情況。如前所述,Logstash 同時還支持與大量不同的消息隊列類型進行集成。
Ingest節點:極限情況下會出現:在長時間無法聯系上 Elasticsearch 或者 Elasticsearch 無法接受數據的情況下,均有可能會丟失數據。 - 區別三:處理能力不同。
Logstash:支持的插件和功能點較Ingest節點多很多。
Ingest節點:支持28類處理器操作。Ingest節點管道只能在單一事件的上下文中運行。Ingest通常不能調用其他系統或者從磁盤中讀取數據。
詳解:一次ES搜索的兩階段
ES的搜索過程,目標是符合搜索條件的文檔,這些文檔可能散落在各個node、各個shard中,
ES的搜索,需要找到匹配的文檔,並且把從各個node,各個shard返回的結果進行匯總、排序,組成一個最終的結果排序列表,才算完成一個搜索過程。
一次搜索請求在兩個階段中執行(query 和 fetch),這兩個階段由接收客戶端請求的節點 (協調節點)協調。
- 在請求query 階段,協調節點將請求轉發到保存數據的數據節點。 每個數據節點在本地執行請求並將其結果返回給協調節點。
- 在收集fetch階段,協調節點將每個數據節點的結果匯集為單個全局結果集。
我們將按兩階段的方式對這個過程進行講解。
phase 1: query 查詢階段
假定我們的ES集群有三個node,number_of_primary_shards為3,replica shard為1,我們執行一個這樣的查詢請求:
GET /music/children/_search
{
"from": 980,
"size": 20
}
query 查詢階段的過程示意圖如下:
query 查詢階段的過程示如下:
- Java客戶端發起查詢請求,接受請求的node-1成為Coordinate Node(協調者),該node會創建一個priority queue,長度為from + size即1000。
- Coordinate Node將請求分發到所有的primary shard或replica shard中,每個shard在本地創建一個同樣大小的priority queue,長度也為from + size,用於存儲該shard執行查詢的結果。
- 每個shard將各自priority queue的元素返回給Coordinate Node,元素內只包含文檔的ID和排序值(如_score),Coordinate Node將合並所有的元素到自己的priority queue中,並完成排序動作,最終根據from、size值對結果進行截取。
補充說明:
-
哪個node接收客戶端的請求,該node就會成為Coordinate Node。
-
Coordinate Node轉發請求時,會根據負載均衡算法分配到同一分片的primary shard或replica shard上,注意,這里是或,不是與。
為什么說replica值設置得大一些, 可以增加系統吞吐量呢 ?
原理就在這里
Coordinate Node的查詢請求負載均衡算法會輪詢所有的可用shard,並發場景時就會有更多的硬件資源(CPU、內存,IO)會參與其中,系統整體的吞吐量就能提升。
-
此查詢過程Coordinate Node得到是輕量級的文檔元素信息,只包含文檔ID和_score這些信息,這樣可以減輕網絡負載,因為分頁過程中,大部分的數據是會丟棄掉的。
phase 2: fetch取回階段
在完成了查詢階段后,此時Coordinate Node已經得到查詢的列表,但列表內的元素只有文檔ID和_score信息,並無實際的_source內容,取回階段就是根據文檔ID,取到完整的文檔對象的過程。
如下圖所示:
fetch取回階段的過程示意圖如下:
- Coordinate Node根據from、size信息截取要取回文檔的ID,如{"from": 980, "size": 20},則取第981到第1000這20條數據,其余丟棄,from/size為空則默認取前10條,向其他shard發出mget請求。
- shard接收到請求后,根據_source參數(可選)加載文檔信息,返回給Coordinate Node。
- 一旦所有的shard都返回了結果,Coordinate Node將結果返回給客戶端。
注意:
使用from和size進行分頁時,傳遞信息給Coordinate Node的每個shard,都創建了一個from + size長度的隊列,並且Coordinate Node需要對所有傳過來的數據進行排序,工作量為number_of_shards * (from + size),然后從里面挑出size數量的文檔,如果from值特別大,那么會帶來極大的硬件資源浪費,鑒於此原因,強烈建議不要使用深分頁。
不過深分頁操作很少符合人的行為,翻幾頁還看不到想要的結果,人的第一反應是換一個搜索條件
只有機器人或爬蟲才這么不知疲倦地一直翻頁, 直到服務器崩潰。
ES的副本高可用架構
ES核心存放的核心數據是索引。
ES集群中索引可能由多個分片構成,並且每個分片可以擁有多個副本。
通過將一個單獨的索引分為多個分片,解決單一索引的大小過大,導致的搜索效率問題。
分片之后,由於每個分片可以有多個副本,通過將副本分配到多個服務器,可以提高查詢的負載能力。
每個索引會被分成多個分片shards進行存儲,默認創建索引是分配5個分片進行存儲。
每個分片都會分布式部署在多個不同的節點上進行部署,該分片成為primary shards。
如果ES實現了集群的話,會將單台服務器節點的索引文件使用分片技術,分布式存放在多個不同的物理機器上。
分片就是將數據拆分成多台節點進行存放,這樣做是為了提升索引、搜索效率。
通過 _setting API可以查詢到索引的元數據:
兩個很重要的數據:
-
5: 每個索引拆分5片存儲
-
1:備份一份
注意:索引的主分片primary shards定義好后,后面不能做修改。
分片的副本
在ES分片技術中,分為主(primary)分片、副(replicas)分片。
為了實現高可用數據的高可用、高並發,主分片可以有對應的副本分片replics shards。
replic shards分片承載了負責容錯、以及請求的負載均衡。
**注意: **
-
每一個主分片為了實現高可用,都會有自己對應的副本分片
-
分片對應的副本分片不能存放同一台服務器上(單台ES沒有副本用分片的)。
-
主分片primary shards可以和其他replics shards存放在同一個node節點上。
在往主分片服務器存放數據時候,會對應實時同步到備用分片服務器:
但是查詢時候,所有(主、備)分片都參與查詢。由協調節點進行負載均衡。
分片的存放
假設一個索引:
number_of_shards=3
number_of_replicas=3
3個分片,每個分片一個 副本,總共6個shard。
放在一個3個data node的集群中,具體的存放方式為:
三個節點 6/3 為 2 每個節點存放兩個分片
在創建索引時候,主分片數量定義好后是不能修改的
修改副的分片 number_of_replica =2
3個主分片6個備分片, 一共9個分片,具體的存放方式為:
從高可用/高並發的角度出發,官方建議, shard為 節點的平方數 !!
節點的擴容
假設data node由2個節點,擴容到3個節點。
主分片3 備份1, 主分片3個 ,每個主分片對應的1個備分片,
總的shard數=3*2=6
那么官方達到建議, shard為 節點的平方數。
按照官方的建議,如果每個主分片,可以對應的2個備分片,總共的分片數=3*3=9。
百億數據的分片和節點規划
百億數據,放在數據庫的量是多少?
假設 1T 。
實際的生產經驗,一個shard應該是30-50G比較合理,機械硬盤,不建議大於50G
磁盤好的話,比如SSD固態硬盤,這個可以大點,比如100G
如果是1T,一個分片50G,建議你最少primary shards 20個
從高可用/高並發的角度出發,官方建議, shard為 節點的平方數 !!
所以,replicas 可以根據節點數來推算。
比如10 個Data node,10 X 10=100, 則副本數可以為 4 ,(4+1)*20=100
注意:副本太多有很大的副作用,集群內部的需要保障primary 和 replica 的數據一致性,需要的網絡流量消耗與 CPU消耗會大大提升。
數據路由
documnet routing(數據路由)
當客戶端發起創建document的時候,es需要確定這個document放在該index哪個shard上。這個過程就是數據路由。
路由算法:shard = hash(routing) % number_of_primary_shards
如果number_of_primary_shards在查詢的時候取余發生的變化,無法獲取到該數據
注意:索引的主分片數量定義好后,不能被修改
已知主分片數量為3,
路由算法: shard = hash(routing) % 主分片數量3
分片位置 p1 = % 3 , p2 =2%3 , p0=3%3
routing 就是采用 id
在查詢時候,底層根據文檔 id % 主分片數量獲取分片位置
計算的算法 取模時候 除數改變了 查詢時候 怎么辦?!
所以 不能亂改啊~
ES集群的架構規划
首先是集群節點的角色規划。
一個節點在默認角色
Elasticsearch的員工 Christian_Dahlqvist解讀如下:
一個節點的缺省配置是:主節點+數據節點兩屬性為一身。
對於3-5個節點的小集群來講,通常讓所有節點存儲數據和具有獲得主節點的資格。你可以將任何請求發送給任何節點,並且由於所有節點都具有集群狀態的副本,它們知道如何路由請求。
通常只有較大的集群才能開始分離專用主節點、數據節點。 對於許多用戶場景,路由節點根本不一定是必需的。
專用協調節點(也稱為client節點或路由節點)從數據節點中消除了聚合/查詢的請求解析和最終階段,並允許他們專注於處理數據。
在多大程度上這對集群有好處將因情況而異。 通常我會說,在查詢大量使用情況下路由節點更常見。
實際上,一個節點在默認情況下會同時扮演:Master Node,Data Node 和 Ingest Node。
節點類型 | 配置參數 | 默認值 |
---|---|---|
Master Eligible | node.master | true |
Data | node.data | true |
Ingest | node.ingest | true |
Coordinating only | 無 | 設置上面 3 個參數全為 false,節點為協調節點 |
節點的角色建議
分環境:
-
在開發環境,一個節點可以承擔多種角色;
-
生產環境中,需要根據數據量,寫入和查詢的吞吐量,選擇合適的部署方式,建議設置單一角色的節點(dedicated node);
ES2.X及之前版本節點角色概述
注意,在ES2.X及之前, 節點的角色有點不一樣,具體如下:
ES5.X節點角色清單
注意,在ES5.X及之后, 節點的角色基本穩定下來了,具體如下:
配置節點類型
-
開發環境中一個節點可以承擔多種角色
-
生產環境中,應該設置單一的角色
節點類型 | 配置參數 | 默認值 |
---|---|---|
Master | node.master | true |
Master eligible | node.master | true |
Data | node.data | true |
Coordinating | 無 | 每個節點都是協調節點,設置其它節點全部為false則為協調節點 |
Ingest | node.ingest | true |
兩個屬性的四種組合
Master和Data兩個角色,這些功能是由三個屬性控制的。
1. node.master
- node.data
3. node.ingest
默認情況下這三個屬性的值都是true。
默認情況下,elasticsearch 集群中每個節點都有成為主節點的資格,也都存儲數據,還可以提供查詢服務,做預處理。
node.master:這個屬性表示節點是否具有成為主節點的資格
注意:此屬性的值為 true,並不意味着這個節點就是主節點。因為真正的主節點,是由多個具有主節點資格的節點進行選舉產生的。所以,這個屬性只是代表這個節點是不是具有主節點選舉資格。
node.data:這個屬性表示節點是否存儲數據。
組合1
node.master: true AND node.data: true AND node.ingest: true
這種組合表示這個節點既有成為主節點的資格,又可以存儲數據,還可以作為預處理節點
這個時候如果某個節點被選舉成為了真正的主節點,那么他還要存儲數據,這樣對於這個節點的壓力就比較大了。
elasticsearch 默認是:每個節點都是這樣的配置,在測試環境下這樣做沒問題。實際工作中建議不要這樣設置,這樣相當於 主節點 和 數據節點 的角色混合到一塊了。
組合2
node.master: false AND node.data: **true **AND node.ingest: false
這種組合表示這個節點沒有成為主節點的資格,也就不參與選舉,只會存儲數據。
這個節點我們稱為 data(數據)節點。在集群中需要單獨設置幾個這樣的節點負責存儲數據。
后期提供存儲和查詢服務
組合3
node.master: true AND node.data: falseAND node.ingest: false
這種組合表示這個節點不會存儲數據,有成為主節點的資格,可以參與選舉,有可能成為真正的主節點。這個節點我們稱為master節點
組合4
node.master: false AND node.data: falseAND node.ingest: true
這種組合表示這個節點即不會成為主節點,也不會存儲數據,這個節點的意義是作為一個 client(客戶端)節點,主要是針對海量請求的時候可以進行負載均衡。
在新版 ElasticSearch5.x 之后該節點稱之為:coordinate 節點,其中還增加了一個叫:ingest 節點,用於預處理數據(索引和搜索階段都可以用到)。
當然,作為一般應用是不需要這個預處理節點做什么額外的預處理過程,那么這個節點和我們稱之為 client 節點之間可以看做是等同的,我們在代碼中配置訪問節點就都可以配置這些 ingest 節點即可。
不同角色節點 的配置選擇
Dedicated Master Eligible Node
- 負責集群狀態的管理;
- 使用低配置的 CPU,RAM 和磁盤;
Dedicated Data Node
- 負責數據存儲及處理客戶端請求;
- 使用高配置的 CPU,RAM 和磁盤;
Dedicated Ingest Node
- 負責數據處理;
- 使用高配置的 CPU,中等配置的 RAM,低配置的磁盤;
Coordinating only Node
- 高配或中配的 CPU,高配或中配的 RAM,低配的磁盤;
- 生產環境中,建議為一些大的集群配置 Coordinating Only Node,其扮演的角色:
- Load Balancer,降低 Master 和 Data Nodes 的負載;
- 負責搜索結果的 Gather 和 Reduce;
- 有時無法預知客戶端會發送怎樣的請求,大量占用內存的聚合操作,比如一個深度聚合可能會發生 OOM;
高可用ES部署的基本原則
配置 多個Dedicated Master Node
為什么要配置 多個Dedicated Master Node?
從高可用 & 避免腦裂的角度出發,需要配置多個 Dedicated Master Node
- 一般在生產環境中配置 3 台,當有1 台丟失的時候,其余的節點會被提升成活躍主節點;
- 一個集群必須有一台活躍的主節點,負責分片管理,索引創建,集群管理等操作;
Elasticsearch集群至少三個Master實例,並且,生產建議每個es實例部署在不同的設備上,三個Master節點最多只能故障一台Master節點,數據不會丟失; 如果三個節點故障兩個節點,則造成數據丟失並無法組成集群。
三台Master做集群,其中一台被真正選為了Master,那么其它兩台就是 eligible 節點。
Master Node 和 Data Node 或 Coordinating Node 分開部署
如果 Master Node 和 Data Node 或 Coordinating Node 混合部署
- Data Node 相對有比較大的內存占用;
- Coordinating Node 有時候會有開銷很高的查詢,導致 OOM;
- 這些都有可能影響 Master 節點,導致集群的不穩定;
Data Node 水平擴展
在Elasticsearch集群中,此節點應該是最多的。
Data Node 在以下兩種場景,可以不斷擴展:
- 當磁盤容量無法滿足時,可以增加 Data Node;
- 當磁盤讀寫壓力大時,可以增加 Data Node;
內存建議:
假如一台機器部署了一個ES實例,則ES最大可用內存,不要超過物理內存的50%;
ES最大可用內存,最多不可超過32G;
如果單台機器上部署了多個ES實例,則多個ES實例內存相加等於物理內存的50%。
每1GB堆內存對應集群的分片,建議保持在20個以內;
分片建議:
每個分片大小不要超過30G,硬盤條件好的話,不建議超過100G.
Coordinating Node 水平擴展
- 當系統中有大量復雜查詢及聚合的時候,增加 Coordinating Node,提升查詢和聚合的性能;
- 可以在 Coordinating Node 前配置 LB,軟件或硬件實現,此時 Application 只需要和 LB 交互;
讀寫分離與LB負載均衡
- 讀請求發到 Coordinating Node;
- 寫請求發到 Ingest Node;
- Coordinating Node 和 Ingest Node 前都可以配置 LB;
高可用ES的部署源規划
小型的ES集群的節點架構
小型的ES集群,就是3/5/7這種少於10個節點的集群。
對於3個節點、5個節點甚至更多節點角色的配置,Elasticsearch官網、國內外論壇、博客都沒有明確的定義。
小型的ES集群的節點角色規划:
1)對於Ingest節點,如果我們沒有格式轉換、類型轉換等需求,直接設置為false。
2)3-5個節點屬於輕量級集群,要保證主節點個數滿足((節點數/2)+1)。
3)輕量級集群,節點的多重屬性如:Master&Data設置為同一個節點可以理解的。
4)如果進一步優化,5節點可以將Master和Data再分離。
大型的ES集群的節點架構
ES數據庫最好的高可用集群部署架構為:
- 三台服務器做master節點
- N(比如20)台服務器作為data節點(存儲資源要大)
- N(比如2)台做ingest節點(用於數據轉換,可以提高ES查詢效率)
高可用進階:異地多活部署場景(多個data center)
異地多活部署場景, 可以在多個data center 部署多套ES集群。
在多個data center的部署場景。 如何進一步保證ES集群的高可用呢
讀高可用架構
這幾個集群需要確保有相同的數據。通過gtm進行流量路由,將用戶的讀請求,路由到最優的集群。
GTM主要用來做數據的讀取。
具體的讀高可用架構圖如下:
如何保證數據一致性
兩種方案:
-
需要程序分別寫入這幾個集群,保持數據一致。
-
或者就寫入一個集群 ,使用es的跨集群復制確保數據一致
一致性保障策略1:集群多寫
需要程序分別寫入這幾個集群,保持數據一致
由於建立索引的及時性,沒有那么高,更多的情況,是寫入消息隊列。
各個數據中心的程序,去消費消息隊列中的數據。
一致性保障策略2:ES的跨集群復制
Elasticsearch(后面統稱ES) cross-cluster replication (后面統稱CCR)是ES 6.5的一個測試特性,是ES 6.7的的一個全局高可用特性。
CCR將索引復制到其他ES集群,可以解決多個用例,包括跨數據中心高可用(HA),災難恢復(DR)和CDN樣體系結構,最終實現ES集群的高可用。
CCR沒有所謂的沖突監測,如果要獨立flower,只需要暫定同步,關閉索引,取消對leader的關注,重新打開索引即可。
CCR 是雙向的
CCR 這個特性可以讓你將一個集群的索引數據同步復制到遠程的另外一個集群上面去。或者反過來,將一個遠程的集群的索引數據同步的復制到本地 Elasticsearch 集群中來。
CCR 可以復制到多個集群
CCR允許不同的索引復制到一個或多個ES 集群中。
集群復制類似於數據訂閱的方式,一個集群的數據可以被多個集群訂閱,也就是可以被復制到多個集群上面去。
CCR 工作在索引層面
CCR 工作在索引層面,使用 Pull 的模式,Follower 索引主動的去 Pull Leader 的數據。
CCR 有兩個角色,一個是 Leader,表示數據的源頭,另外一個Follower,表示數據的訂閱方,得到的是數據副本。
CCR是一個leader/fllower架構,leader可以進行任何操作,但是fllower則不能進行寫入操作,fllower的mapping和setting也是跟隨leader的變化而變化,無需進行單獨的修改。
CCR不是免費的特性
這個特性是 Elasticsearch 的商業特性,需要白金訂閱。
CCR的使用場景
- 異地多活多data center 集群高可用以及災難恢復
- 全球化多data center 實現數據的就近訪問(地理)
- 集中式的報告集群
第一個場景,關於保證 Elasticsearch 集群的高可用和災難恢復。
通過部署多套 Elasticsearch 集群,並且分布在不同地域的數據中心,然后接着 CCR,將數據做一個實時的同步,假如其中一個數據中心失聯或者因為不可抗力的因素,如台風、地震,我們照樣還能通過訪問剩下的集群來獲取完整的數據,如下圖示意:
當 Production DC 失聯之后,我們可以立即切換到 Disaster Recovery DC。
第二個場景,數據的就近訪問。
假設是一個大集團,有總公司和分公司,通過按地理位置來划分分公司自己的業務集群,不同城市的業務數據可以使用各自的集群,這樣能夠更快的進行當地業務的處理,不過也有一些數據,可能是總公司下發的數據,各個分公司都只能讀,比如一些元數據,我們借助 CCR,可以把這部分數據下發到各個分公司的 Elasticsearch 集群,這樣每個分公司都能實時的獲取到最新的數據,並且直接訪問各自的本地集群就可以了,大大提升訪問速度。
上圖中,Central DC 借助 CCR 實時的同步下發數據到 Singapore DC、Canada DC 和 Ireland DC。
第三個場景:就是做集中式的報告分析。
接上面的案例,我們反過來處理我們的業務數據,我們將每個分公司的業務數據實時的同步到總公司的 Elasticsearch 集群,這樣總公司就有了每個分公司的完整數據,這樣進行報告分析的時候,就可以直接的在總公司的 Elasticsearch 集群里面進行快速的可視化分析了。
CCR 如何使用
說了這么多 CCR 的適用場景,那接下來我們來看一下具體如何使用吧。
假設我有兩個機器,北京集群(192.168.1.100:9300)和深圳集群(192.168.3.100:9300),這倆個集群之間的網絡是互通的。現在我們希望把北京集群的銷售數據同步到深圳集群上去。
第一步,在北京集群上,設置 Leader 索引
這個 Leader Index 需要設置好允許 Soft Deletes,這個參數非常重要,CCR 依賴這個特性來,如果這個索引之前沒有開啟過這個參數,需要重新創建索引才行。
比如,我創建一個 bj_sales
這個索引:
PUT bj_sales
{
"settings": {
"index.soft_deletes.retention.operations": 2000,
"index.soft_deletes.enabled": true
}
}
現在,這個 bj_sales
就已經具備跨集群復制的能力了。
第二步,北京集群,創建幾條銷售數據。
POST bj_sales/doc/
{
"name":"Jack Ma",
"age":40
}
POST bj_sales/doc/
{
"name":"Pony Ma",
"age":40
}
第三步,在深圳集群上,把北京集群的信息加到遠程集群里面去。
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"bj": {
"seeds": [
"192.168.1.100:9300"
]
}
}
}
}
}
bj
是我們能夠在深圳集群里面訪問北京集群的命名空間。
第四步,我們在深圳集群里面通過 CCR API 創建一個索引,並訂閱北京機器的 bj_sales
這個索引。
PUT /bj_sales_replica/_ccr/follow
{
"remote_cluster" : "bj",
"leader_index" : "bj_sales"
}
bj_sales_replica
是我們將要創建在深圳集群上的索引名稱,remote 集群是 bj
,訂閱了對方的 bj_sales
索引。
第五步,驗證
如果不出意外,我們在深圳集群上,應該就會創建一個新的 bj_sales_replica
的索引,並且里面會有兩條數據,我們可以驗證一下,如下:
GET bj_sales_replica/_search
返回結果如下:
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "bj_sales_replica",
"_type" : "doc",
"_id" : "iNZYymcBGbeu9hnEe7-G",
"_score" : 1.0,
"_source" : {
"name" : "Pony Ma",
"age" : 40
}
},
{
"_index" : "bj_sales_replica",
"_type" : "doc",
"_id" : "QdZYymcBGbeu9hnEJb-Z",
"_score" : 1.0,
"_source" : {
"name" : "Jack Ma",
"age" : 40
}
}
]
}
}
果然,自動將遠程集群的數據復制過來了。
繼續驗證,數據同步
我們在北京集群上,繼續新增數據和刪除數據,看看深圳集群是否都能正常同步。
POST bj_sales/doc/5
{
"name":"Tony",
"age":30
}
DELETE bj_sales/doc/5
這里就留給大家自己去測試了。
接下來
接下來要介紹的內容,是實操:
進行 5個節點的高可用ES 高可用集群搭建實操。
參考鏈接
https://www.cnblogs.com/liang1101/p/7284205.html
https://blog.csdn.net/laoyang360/article/details/78290484
https://www.jianshu.com/p/716408af7ebb
https://blog.csdn.net/laoyang360/article/details/93376355
https://segmentfault.com/a/1190000021614149
https://www.jianshu.com/p/716408af7ebb
https://discuss.elastic.co/t/dec-22nd-2018-cn-elasticsearch-ccr/161626
https://www.elastic.co/guide/en/elasticsearch/reference/7.5/indices-split-index.html
https://www.elastic.co/guide/en/elasticsearch/reference/6.1/indices-split-index.html