ES作為一個分布式系統(tǒng),需要多個節(jié)點(diǎn)協(xié)同,來管理集群,處理用戶請求。那么很自然有個問題,ES的集群是如何組建起來的?
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、嘉黎網(wǎng)站維護(hù)、網(wǎng)站推廣。
所謂集群,就是多臺計算機(jī)一起協(xié)同工作。 既然是協(xié)同工作,那么就必須步調(diào)一致,步調(diào)一致才能得解放。需要有領(lǐng)導(dǎo)這個角色來協(xié)調(diào)資源, 這個角色在ES中命名為Master。 Master這個角色,不是ES的獨(dú)有的,基本上所有的分布式系統(tǒng)都有這個角色的存在,比如Zookeeper, Mongo等。
Master的產(chǎn)生機(jī)制也很有意思: 選舉。既然是選舉,那么必然會出現(xiàn)一個問題:怎么選舉? 這就是所謂的“選舉算法”。 “選舉算法”中最有名的就是Paxos算法,也是最難理解的算法。好在ES用的不是這么復(fù)雜的算法,ES用的是Bully算法。ES需要解決的問題是節(jié)點(diǎn)的選舉, 而Paxos算法除了選舉,還解決了一致性的問題,殺雞焉用牛刀。
基于Bully算法,ES實(shí)現(xiàn)ZenDiscovery。 順便說一句,ES的節(jié)點(diǎn)發(fā)現(xiàn)由統(tǒng)一的模塊處理,就是DiscoveryModule
。有興趣了解ES源碼,可以作為一個入口。
ZenDiscovery的流程相當(dāng)簡潔, 就兩步:
1. 每個節(jié)點(diǎn)和其他的節(jié)點(diǎn)通信,獲取其他節(jié)點(diǎn)的nodeId, 從中選取nodeId最小的那個作為自己的投票。
2. 每個節(jié)點(diǎn)接收其他節(jié)點(diǎn)的投票,如果有一個節(jié)點(diǎn)得到足夠多的選票,則接受自己成為Leader的事實(shí),開始分發(fā)節(jié)點(diǎn)狀態(tài)到整個集群的其他節(jié)點(diǎn)。
下面通過具體的代碼來理解這一個流程。既然是理解ES集群的組建過程,那么就從ES的進(jìn)程啟動開始,以elasticsearch-2.4.5為例。
我們知道,ES的啟動命令是bin/elasticsearch
,這個命令會調(diào)用org.elasticsearch.bootstrap.Elasticsearch.java
的main方法。
啟動elasticsearch后, 通過使用如下的命令可以確定:
$ jps
13201 Elasticsearch
$$ cat /proc/13201/cmdline | strings
/opt/jdk1.8.0_51/bin/java
-Xms256m
-Xmx1g
-Djava.awt.headless=true
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
-XX:+HeapDumpOnOutOfMemoryError
-XX:+DisableExplicitGC
-Dfile.encoding=UTF-8
-Djna.nosys=true
-Des.path.home=/opt/elasticsearch-2.4.5-SNAPSHOT
/opt/elasticsearch-2.4.5-SNAPSHOT/lib/elasticsearch-2.4.5-SNAPSHOT.jar:/opt/elasticsearch-2.4.5-SNAPSHOT/lib/*
org.elasticsearch.bootstrap.Elasticsearch
start
接下來,會實(shí)例化一個Node對象,代表這個ES節(jié)點(diǎn)。然后start這個node.
Bootstrap.init(args); // Elasticsearch.java line 45
INSTANCE.start(); // Bootstrap.java line 288
node.start(); // Bootstrap.java line 222
discoService.joinClusterAndWaitForInitialState(); // Node.java 286
如果在es的配置文件進(jìn)行如下的配置,那么可以debug這個過程.
// 當(dāng)前啟動節(jié)點(diǎn)的IP地址
network.host: 192.168.43.239
// 集群的IP列表
discovery.zen.ping.unicast.hosts: ["192.168.43.239", "192.168.43.239:9800","192.168.43.239:9900"]
我們忽略代碼間的跳轉(zhuǎn),直接到核心業(yè)務(wù)邏輯代碼ZenDiscovery.innerJoinCluster()
,具體的業(yè)務(wù)邏輯如下:
s1: 確定master ZenDiscovery.findMaster()
s2: 判斷master是否是當(dāng)前節(jié)點(diǎn),如果是則等待其他的節(jié)點(diǎn)加入;否則連接master, 然后發(fā)起狀態(tài)更新的請求到master.
關(guān)于集群節(jié)點(diǎn)間的通信,還有很多其他的細(xì)節(jié)。我們先拋開ES相關(guān)的知識,回到操作系統(tǒng)層面。 兩臺計算機(jī)通信,依賴的是計算機(jī)網(wǎng)絡(luò)方面的知識。 簡單來說就是TCP/IP協(xié)議。從Java語言的實(shí)現(xiàn)來說就是Socket編程。 Socket編程遵循的模式是C/S模式,即一臺計算機(jī)作為服務(wù)端,監(jiān)聽一個端口;另一臺計算機(jī)作為客戶端,連接該端口。
通常開發(fā)中不會自己使用原生的Socket編程,而是使用Netty框架。 Netty框架封裝了繁雜的底層操作,又在性能上做了很多工作。其基于異步/時間驅(qū)動的特性使其成為網(wǎng)絡(luò)編程的首選框架。
基于Netty框架, ES構(gòu)建了功能上類似于dubbo的RPC服務(wù),這個就是Transport。代碼的入口是`TransportModule`。關(guān)于Transport的細(xì)節(jié),需單獨(dú)寫博客說明,非本文關(guān)注的重點(diǎn),略過。
基于Transport模塊,ES構(gòu)建了DiscoveryModule,就是ES的節(jié)點(diǎn)發(fā)現(xiàn)。即本文試圖理解的核心點(diǎn)。
參考:
https://www.jianshu.com/p/9454ac19921d
https://www.elastic.co/blog/found-leader-election-in-general
本文名稱:ES學(xué)習(xí)筆記之--ES的集群是如何組建起來的
標(biāo)題URL:http://newbst.com/article22/jhsdcc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、企業(yè)建站、微信小程序、商城網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)