淺析ElasticSearch原理
啟動過程
獲取叢集node列表
在UnicastZenPing建構函式中,向discovery.zen.ping.unicast.hosts配置的節點列表傳送請求,獲取到DiscoveryNode列表。
選主流程
通過UnicastZenPing傳送ping,從response資訊中找到master,如果沒有master,進入選主流程。
啟動任務
選為master節點後,會啟動計劃任務。
叢集管理
叢集啟動後可以根據API介面進行管理監控。
新節點加入流程
當ElasticSearch的節點啟動後,它會利用多播(multicast)或者單播(如果使用者更改了配置)尋找叢集中的其它節點,並與之建立連線。這個過程如下圖所示:
New ElasticSearch Node (新節點)
新節點加入後,會通過多播Multicast request(發出請求),尋找叢集其他節點並和叢集建立連線。
需要注意的是,從使用者的角度來看,主節點在ElasticSearch中並沒有佔據著重要的地位,這與其它的系統(比如資料庫系統)是不同的。實際上使用者並不需要知道哪個節點是主節點;所有的操作需求可以分發到任意的節點,ElasticSearch內部會完成這些讓使用者感到不明覺歷的工作。在必要的情況下,任何節點都可以併發地把查詢子句分發到其它的節點,然後合併各個節點返回的查詢結果。最後返回給使用者一個完整的資料集。所有的這些工作都不需要經過主節點轉發(節點之間通過P2P的方式通訊)。
探測失效節點
在正常工作時,主節點會監控所有的節點,檢視各個節點是否工作正常。如果在指定的時間裡面,節點無法訪問,該節點就被視為出故障了,接下來錯誤處理程式就會啟動。叢集需要重新均衡——由於該節點出現故障,分配到該節點的索引分片丟失。其它節點上相應的分片就會把工作接管過來。換句話說,對於每個丟失的主分片,新的主分片將從剩餘的分片副本(Replica)中選舉出來。 以3個Node為例:
說明:Node1 是master節點,P 為primary 主分片的縮寫,R 為replica 副本分片。
當Node1 掛掉的時候,如下:
由於一個叢集必須要有一個主節點才能使其功能正常,所以叢集做的第一件事就是各節點選舉了一個新的主節點:Node 2。
主分片1和2在我們殺掉Node 1時已經丟失,我們的索引在丟失主分片時不能正常工作。如果此時我們檢查叢集健康,我們將看到狀態red:不是所有主節點都可用!
幸運的是丟失的兩個主分片的完整拷貝存在於其他節點上,所以新主節點做的第一件事是把這些在Node 2和Node 3上的複製分片升級為主分片,這時叢集健康回到yellow狀態。這個提升是瞬間完成的。
叢集管理和監控
通過管理和監控部分的API,使用者可以更改叢集的設定。比如調整節點發現機制(discovery mechanism) 或者更改索引的分片策略。使用者可以檢視叢集狀態資訊,或者每個節點和索引和統計資訊。
如:獲取叢集健康資訊 GET /cluster/health 獲取叢集配置資訊 GET /cluster/settings 下圖為chrome head外掛的叢集展示結果:
可以看到叢集有多少個節點,叢集健康值等。
ElasticSearch讀寫原理
寫操作原理
Coordinating Node
協調節點預設使用文件ID參與計算(也支援通過routing),以便為路由提供合適的分片。
shard = hash(document_id) % (num_of_primary_shards)
Shard
當分片所在的節點接收到來自協調節點的請求後,會將請求寫入到Memory Buffer,然後定時(預設是每隔1秒)寫入到Filesystem Cache,這個從Momery Buffer到Filesystem Cache的過程就叫做refresh。
Memory Buffer | Filesystem Cache
當然在某些情況下,存在Momery Buffer和Filesystem Cache的資料可能會丟失,ES是通過translog的機制來保證資料的可靠性的。其實現機制是接收到請求後,同時也會寫入到translog中,當Filesystem cache中的資料寫入到磁碟中時,才會清除掉,這個過程叫做flush。
Transaction Log
在flush過程中,記憶體中的緩衝將被清除,內容被寫入一個新段,段的fsync將建立一個新的提交點,並將內容重新整理到磁碟,舊的translog將被刪除並開始一個新的translog。
flush觸發的時機是定時觸發(預設30分鐘)或者translog變得太大(預設為512M)時。
讀操作原理
搜尋被執行成一個兩階段過程,我們稱之為 Query Then Fetch;
Coordinating Node
在初始查詢階段時,查詢會廣播到索引中每一個分片拷貝(主分片或者副本分片)。 每個分片在本地執行搜尋並構建一個匹配文件的大小為 from + size 的優先佇列。PS:在搜尋的時候是會查詢Filesystem Cache的,但是有部分資料還在Memory Buffer,所以搜尋是近實時的。
Shard
每個分片返回各自優先佇列中 所有文件的 ID 和排序值 給協調節點,它合併這些值到自己的優先佇列中來產生一個全域性排序後的結果列表。
Coordinating Node
接下來就是 取回階段,協調節點辨別出哪些文件需要被取回並向相關的分片提交多個 GET 請求。每個分片載入並 豐富 文件,如果有需要的話,接著返回文件給協調節點。一旦所有的文件都被取回了,協調節點返回結果給客戶端。
補充:Query Then Fetch的搜尋型別在文件相關性打分的時候參考的是本分片的資料,這樣在文件數量較少的時候可能不夠準確,DFS Query Then Fetch增加了一個預查詢的處理,詢問Term和Document frequency,這個評分更準確,但是效能會變差。
總結以上主要介紹了ES的工作原理,ES的魅力遠不止如此,同時ES的開源特性也使得它社群活躍,版本迭代更新迅速,目前已經更新到6.x版本,如有興趣可到ES官網瞭解最新的特性。
PS:關注360linker公眾號,加入官方社群獲取免費視訊教程、知名單位招聘資訊。交流分享IT圈學習經驗。