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