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