springcloud檢索中間件?ElasticSearch?分布式場景的使用
1.分布式集群場景下的使用
單機(jī)的elasticsearch做數(shù)據(jù)存儲,必然面臨兩個(gè)問題:海量數(shù)據(jù)存儲問題、單點(diǎn)故障問題。
- 海量數(shù)據(jù)存儲問題:將索引庫從邏輯上拆分為N個(gè)分片(shard),存儲到多個(gè)節(jié)點(diǎn)
- 單點(diǎn)故障問題:將分片數(shù)據(jù)在不同節(jié)點(diǎn)備份(replica )
ES集群相關(guān)概念:
- 集群(cluster):一組擁有共同的 cluster name 的 節(jié)點(diǎn)。
- 節(jié)點(diǎn)(node) :集群中的一個(gè) Elasticearch 實(shí)例
- 分片(shard):索引可以被拆分為不同的部分進(jìn)行存儲,稱為分片。在集群環(huán)境下,一個(gè)索引的不同分片可以拆分到不同的節(jié)點(diǎn)中
解決問題:數(shù)據(jù)量太大,單點(diǎn)存儲量有限的問題。
此處,我們把數(shù)據(jù)分成3片:shard0、shard1、shard2
- 主分片(Primary shard):相對于副本分片的定義。
- 副本分片(Replica shard)每個(gè)主分片可以有一個(gè)或者多個(gè)副本,數(shù)據(jù)和主分片一樣。
數(shù)據(jù)備份可以保證高可用,但是每個(gè)分片備份一份,所需要的節(jié)點(diǎn)數(shù)量就會翻一倍,成本實(shí)在是太高了!
為了在高可用和成本間尋求平衡,我們可以這樣做:
- 首先對數(shù)據(jù)分片,存儲到不同節(jié)點(diǎn)
- 然后對每個(gè)分片進(jìn)行備份,放到對方節(jié)點(diǎn),完成互相備份
這樣可以大大減少所需要的服務(wù)節(jié)點(diǎn)數(shù)量,如圖,我們以3分片,每個(gè)分片備份一份為例:
現(xiàn)在,每個(gè)分片都有1個(gè)備份,存儲在3個(gè)節(jié)點(diǎn):
- node0:保存了分片0和1
- node1:保存了分片0和2
- node2:保存了分片1和2
這樣單一結(jié)點(diǎn)就算宕機(jī),也可以備用
2.0.搭建ES集群
2.部署es集群
我們會在單機(jī)上利用docker容器(docker容器之間相互獨(dú)立)運(yùn)行多個(gè)es實(shí)例來模擬es集群。不過生產(chǎn)環(huán)境推薦大家每一臺服務(wù)節(jié)點(diǎn)僅部署一個(gè)es的實(shí)例。
部署es集群可以直接使用docker-compose來完成,但這要求你的Linux虛擬機(jī)至少有4G的內(nèi)存空間
2.1.創(chuàng)建es集群
首先編寫一個(gè)docker-compose文件(yml或者yaml),內(nèi)容如下:
- 9200端口已經(jīng)在之前的結(jié)點(diǎn)中使用了,要么停止要么改端口,這三個(gè)結(jié)點(diǎn)都沒有設(shè)置插件數(shù)據(jù)卷,實(shí)際開發(fā)記得指明
- discovery.seed_hosts 這里都是同一網(wǎng)絡(luò) ,實(shí)際開發(fā)中不同結(jié)點(diǎn)都是在不同網(wǎng)絡(luò)機(jī)器上 比如 - discovery.seed_hosts=Machine1_IP:9200,Machine3_IP:9200
version: '2.2' services: es01: image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0 container_name: es01 environment: - node.name=es01 - cluster.name=es-docker-cluster - discovery.seed_hosts=es02,es03 - cluster.initial_master_nodes=es01,es02,es03 - "ES_JAVA_OPTS=-Xms512m -Xmx512m" volumes: - data01:/usr/share/elasticsearch/data ports: - 9210:9200 networks: - elastic es02: image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0 container_name: es02 environment: - node.name=es02 - cluster.name=es-docker-cluster - discovery.seed_hosts=es01,es03 - cluster.initial_master_nodes=es01,es02,es03 - "ES_JAVA_OPTS=-Xms512m -Xmx512m" volumes: - data02:/usr/share/elasticsearch/data ports: - 9201:9200 networks: - elastic es03: image: docker.elastic.co/elasticsearch/elasticsearch:7.15.0 container_name: es03 environment: - node.name=es03 - cluster.name=es-docker-cluster - discovery.seed_hosts=es01,es02 - cluster.initial_master_nodes=es01,es02,es03 - "ES_JAVA_OPTS=-Xms512m -Xmx512m" volumes: - data03:/usr/share/elasticsearch/data networks: - elastic ports: - 9202:9200 volumes: data01: driver: local data02: driver: local data03: driver: local networks: elastic: driver: bridge
我的鏡像名
es運(yùn)行需要修改一些linux系統(tǒng)權(quán)限,修改/etc/sysctl.conf
文件
vi /etc/sysctl.conf
添加下面的內(nèi)容:
vm.max_map_count=262144
然后執(zhí)行命令,讓配置生效:
sysctl -p
在docker-c通過docker-compose啟動(dòng)集群:
docker-compose up -d
如果報(bào)錯(cuò) bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
bootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
那么說明是內(nèi)存警告問題 錯(cuò)誤消息指出虛擬內(nèi)存區(qū)域的 vm.max_map_count 參數(shù)設(shè)置得太低。
檢查當(dāng)前的 vm.max_map_count 值:運(yùn)行以下命令來檢查當(dāng)前值:
sysctl vm.max_map_count
如果當(dāng)前值低于 262144,那么你需要增加它。增加 vm.max_map_count 的值:你可以使用以下命令來增加虛擬內(nèi)存區(qū)域的值:
sysctl vm.max_map_count
這會立即更改 vm.max_map_count 的值,但在系統(tǒng)重新啟動(dòng)后會重置為默認(rèn)值。如果要永久更改此設(shè)置,你需要編輯 /etc/sysctl.conf 或 /etc/sysctl.d/ 下的配置文件,并添加或修改以下行:
vm.max_map_count=262144
然后保存文件并重新加載配置:
sudo sysctl -p
重新啟動(dòng) Elasticsearch:一旦你增加了 vm.max_map_count 的值,重新啟動(dòng) Elasticsearch,問題應(yīng)該得到解決。
啟動(dòng)成功
2.2.集群狀態(tài)監(jiān)控
kibana可以監(jiān)控es集群,不過新版本需要依賴es的x-pack 功能并且默認(rèn)是監(jiān)控但點(diǎn)es,配置比較復(fù)雜。
這里推薦使用cerebro來監(jiān)控es集群狀態(tài),官方網(wǎng)址:https://github.com/lmenezes/cerebro
解壓即可使用,非常方便。
解壓好的目錄如下:
進(jìn)入對應(yīng)的bin目錄:
雙擊其中的cerebro.bat文件即可啟動(dòng)服務(wù)。
訪問http://localhost:9000 即可進(jìn)入管理界面:
輸入你的elasticsearch的任意節(jié)點(diǎn)的地址和端口,點(diǎn)擊connect即可:
綠色的條,代表集群處于綠色(健康狀態(tài))。
圖標(biāo)星星是實(shí)的是當(dāng)前主節(jié)點(diǎn),其他的是備用結(jié)點(diǎn)
2.3.創(chuàng)建索引庫
1)利用kibana的DevTools創(chuàng)建索引庫
(這里集群不使用這種方式)
在DevTools中輸入指令:
PUT /itcast { "settings": { "number_of_shards": 3, // 分片數(shù)量 "number_of_replicas": 1 // 副本數(shù)量 }, "mappings": { "properties": { // mapping映射定義 ... } } }
2)利用cerebro創(chuàng)建索引庫
利用cerebro還可以創(chuàng)建索引庫:
172是我的虛擬機(jī)所在的虛擬地址
填寫索引庫信息:
選項(xiàng)分別是索引名 幾個(gè)分片 幾個(gè)備份
點(diǎn)擊右下角的create按鈕: 2.4.查看分片效果
回到首頁,即可查看索引庫分片效果:
首頁可以看到索引數(shù)據(jù)
索引存儲分為三個(gè)分片每個(gè)文檔分片備份一份所以是6個(gè)數(shù)據(jù),點(diǎn)擊任意分片就可以看到索引信息
這樣就可以保證任意結(jié)點(diǎn)宕機(jī) ,其他結(jié)點(diǎn)把備份數(shù)據(jù)傳遞給宕機(jī)接結(jié)點(diǎn)
3.0.集群腦裂問題
3.1.集群職責(zé)劃分
elasticsearch中集群節(jié)點(diǎn)有不同的職責(zé)劃分:
默認(rèn)情況下,集群中的任何一個(gè)節(jié)點(diǎn)都同時(shí)具備上述四種角色。
但是真實(shí)的集群一定要將集群職責(zé)分離:
- master節(jié)點(diǎn):對CPU要求高,但是內(nèi)存要求第
- data節(jié)點(diǎn):對CPU和內(nèi)存要求都高
- coordinating節(jié)點(diǎn):對網(wǎng)絡(luò)帶寬、CPU要求高
職責(zé)分離可以讓我們根據(jù)不同節(jié)點(diǎn)的需求分配不同的硬件去部署。而且避免業(yè)務(wù)之間的互相干擾。
一個(gè)典型的es集群職責(zé)劃分如圖:
3.2.腦裂問題
但是采用分布式的主從架構(gòu)的服務(wù)一般都會出現(xiàn)腦裂問題
腦裂是因?yàn)榧褐械墓?jié)點(diǎn)失聯(lián)導(dǎo)致的。結(jié)點(diǎn)尚未宕機(jī),但是失去通信(比如網(wǎng)絡(luò)問題)
例如一個(gè)集群中,主節(jié)點(diǎn)與其它節(jié)點(diǎn)失聯(lián):
此時(shí),node2和node3認(rèn)為node1宕機(jī),就會重新選主:
當(dāng)node3當(dāng)選后,集群繼續(xù)對外提供服務(wù),node2和node3自成集群,node1自成集群,兩個(gè)集群數(shù)據(jù)不同步,出現(xiàn)數(shù)據(jù)差異,這個(gè)時(shí)候出現(xiàn)了倆個(gè)大腦
當(dāng)網(wǎng)絡(luò)恢復(fù)后,因?yàn)榧褐杏袃蓚€(gè)master節(jié)點(diǎn),集群狀態(tài)的不一致,出現(xiàn)腦裂的情況:
解決腦裂的方案是,要求選票超過 ( eligible節(jié)點(diǎn)數(shù)量 + 1 )/ 2 才能當(dāng)選為主,因此eligible節(jié)點(diǎn)數(shù)量最好是奇數(shù)。對應(yīng)配置項(xiàng)是discovery.zen.minimum_master_nodes,在es7.0以后,已經(jīng)成為默認(rèn)配置,因此一般不會發(fā)生腦裂問題
例如:3個(gè)節(jié)點(diǎn)形成的集群,選票必須超過 (3 + 1) / 2 ,也就是2票。node3得到node2和node3的選票,當(dāng)選為主。node1只有自己1票,沒有當(dāng)選救失去主節(jié)點(diǎn)身份。集群中依然只有1個(gè)主節(jié)點(diǎn),沒有出現(xiàn)腦裂。
3.3.小結(jié)
master eligible節(jié)點(diǎn)的作用是什么?
參與集群選主主節(jié)點(diǎn)可以管理集群狀態(tài)、管理分片信息、處理創(chuàng)建和刪除索引庫的請求
data節(jié)點(diǎn)的作用是什么?
數(shù)據(jù)的CRUD
coordinator節(jié)點(diǎn)的作用是什么?
路由請求到其它節(jié)點(diǎn)
合并查詢到的結(jié)果,返回給用戶
3.4.集群分布式存儲
當(dāng)新增文檔時(shí),應(yīng)該保存到不同分片,保證數(shù)據(jù)均衡,那么coordinating node如何確定數(shù)據(jù)該存儲到哪個(gè)分片呢?
3.4.1.分片存儲測試
插入三條數(shù)據(jù):
創(chuàng)建索引時(shí)候我沒有沒有添加索引mapping,也沒有規(guī)定字段,在Elasticsearch中,如果你創(chuàng)建一個(gè)索引但沒有顯式定義映射(mapping)或字段(mapping),Elasticsearch會使用動(dòng)態(tài)映射(dynamic mapping)來處理你插入的文檔數(shù)據(jù)。動(dòng)態(tài)映射允許Elasticsearch根據(jù)插入的文檔數(shù)據(jù)自動(dòng)推斷字段的數(shù)據(jù)類型。
當(dāng)你插入文檔時(shí),Elasticsearch會檢查文檔的字段,并根據(jù)字段值的類型自動(dòng)創(chuàng)建相應(yīng)的字段映射。例如,如果你插入一個(gè)包含字符串的字段,Elasticsearch會自動(dòng)將其識別為文本字段,如果插入一個(gè)整數(shù),它會將其識別為整數(shù)字段,以此類推。
測試可以看到,三條數(shù)據(jù)分別在不同分片,查詢?nèi)我饨Y(jié)點(diǎn)的數(shù)據(jù)
結(jié)果:
另一接待你查詢
3.4.2.分片存儲原理
elasticsearch會通過hash算法來計(jì)算文檔應(yīng)該存儲到哪個(gè)分片:
說明:
)_routing默認(rèn)是文檔的id) 算法與分片數(shù)量有關(guān),因此索引庫一旦創(chuàng)建,分片數(shù)量不能修改!
新增文檔的流程如下:
解讀:
1)新增一個(gè)id=1的文檔2)對id做hash運(yùn)算,假如得到的是2,則應(yīng)該存儲到shard-23)shard-2的主分片在node3節(jié)點(diǎn),將數(shù)據(jù)路由到node34)保存文檔5)同步給shard-2的副本replica-2,在node2節(jié)點(diǎn)6)返回結(jié)果給coordinating-node節(jié)點(diǎn)
3.4.3集群分布式查詢
elasticsearch的查詢分成兩個(gè)階段:
scatter phase:分散階段,coordinating node會把請求分發(fā)到每一個(gè)分片(查詢檢索一般是根據(jù)text來查詢,不知道具體數(shù)據(jù)id,所以會給每個(gè)結(jié)點(diǎn)發(fā)送查詢)
所以之前查詢?nèi)我唤Y(jié)點(diǎn),都會查詢到全部數(shù)據(jù),因?yàn)檎埱蟠虻搅怂袛?shù)據(jù)
gather phase:聚集階段,coordinating node匯總data node的搜索結(jié)果,并處理為最終結(jié)果集返回給用戶
3.5.集群故障轉(zhuǎn)移
集群的master節(jié)點(diǎn)會監(jiān)控集群中的節(jié)點(diǎn)狀態(tài),如果發(fā)現(xiàn)有節(jié)點(diǎn)宕機(jī),會立即將宕機(jī)節(jié)點(diǎn)的分片數(shù)據(jù)遷移到其它節(jié)點(diǎn),確保數(shù)據(jù)安全,這個(gè)叫做故障轉(zhuǎn)移。
1)例如一個(gè)集群結(jié)構(gòu)如圖:
現(xiàn)在,node1是主節(jié)點(diǎn),其它兩個(gè)節(jié)點(diǎn)是從節(jié)點(diǎn)。
2)突然,node1發(fā)生了故障:
宕機(jī)后的第一件事,需要重新選主,例如選中了node2:
node2成為主節(jié)點(diǎn)后,會檢測集群監(jiān)控狀態(tài),發(fā)現(xiàn):shard-1、shard-0沒有副本節(jié)點(diǎn)。因此需要將node1上的數(shù)據(jù)遷移到node2、node3:
所以故障轉(zhuǎn)移主要是進(jìn)行了倆布,
主結(jié)點(diǎn)宕機(jī)后選擇新節(jié)點(diǎn)為主結(jié)點(diǎn)新的主節(jié)點(diǎn)為了保障宕機(jī)結(jié)點(diǎn)所存儲的數(shù)據(jù)安全,第一時(shí)間轉(zhuǎn)移到其他安全結(jié)點(diǎn)
這是es集群的默認(rèn)策略 這里進(jìn)行演示即可
現(xiàn)在三個(gè)結(jié)點(diǎn)正常
關(guān)閉虛擬機(jī)的任一結(jié)點(diǎn)
等待一會后 集群自動(dòng)遷移
當(dāng)es01重新啟動(dòng)后 數(shù)據(jù)均衡又會把數(shù)據(jù)分給掛掉的結(jié)點(diǎn)
到此這篇關(guān)于springcloud檢索中間件 ElasticSearch 分布式場景的運(yùn)用的文章就介紹到這了,更多相關(guān)springcloud檢索中間件 ElasticSearch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis攔截器實(shí)現(xiàn)公共字段填充的示例代碼
本文介紹了使用Spring Boot和MyBatis實(shí)現(xiàn)公共字段的自動(dòng)填充功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測試的操作詳解
這篇文章主要介紹了SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測試的操作步驟,文中通過代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03Java生成指定范圍內(nèi)的一個(gè)隨機(jī)整數(shù)2種方式
本文主要介紹了Java生成指定范圍內(nèi)的一個(gè)隨機(jī)整數(shù)2種方式,主要使用Math.random()和Random.nextInt()這兩種,具有一定的參考價(jià)值,感興趣的可以了解一下2023-04-04利用Java多線程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟
這篇文章主要介紹了利用Java多線程技術(shù)導(dǎo)入數(shù)據(jù)到Elasticsearch的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07springboot中的Application.properties常用配置
這篇文章主要介紹了springboot中的Application.properties常用配置,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05