E代 表 ElasticSearch,是整個ELK的心臟,它負(fù)責(zé)索引的創(chuàng)建、搜索、分析以及數(shù)據(jù)的存儲等工作,這個組將在后面做詳細(xì)介紹。
L代表Logstash,是用來做數(shù)據(jù)采集、接收、處理和轉(zhuǎn)發(fā)的工具,它講采集來的數(shù)據(jù)經(jīng)過分析和處理以后,將數(shù)據(jù)發(fā)送到ElasticSearch存儲。它本身支持非常多的數(shù)據(jù)源。
K代表Kibana,作用是負(fù)責(zé)將ES中數(shù)據(jù)進(jìn)行炫酷的展示。
整理概括一下整個ELK就是:
Logstash負(fù)責(zé)數(shù)據(jù)采集、分析和處理,然后將數(shù)據(jù)發(fā)送給ElasticSearch做進(jìn)一步的存儲、分析和搜索,最后Kibana講ElasticSearch中的數(shù)據(jù)炫酷地展示出來。
ELK的常用架構(gòu)如圖1所示,使用Logstash Shipper在機(jī)器上采集相關(guān)的數(shù)據(jù)或日志,你可以理解為Logstash的一個agent,中間使用Redis做隊列,也有很多的公司使用Kafka來代替Redis。
目前ELK比較活,社區(qū)也很活躍,有很業(yè)務(wù)都在使用,主要分為三類應(yīng)用:
1.全文檢索
如GitHub和維基百科。
2.日志監(jiān)控類
比如騰訊云監(jiān)控、斗魚日志分析平臺。
3.數(shù)據(jù)分析和查詢
比如 :DELL,Sprint。
此外國外還有一些公司用ES來存儲地理位置數(shù)據(jù),如Foursquare公司,結(jié)合搜索和地理位置兩者提供更優(yōu)質(zhì)的服務(wù)。
圖1 ELK的常用架構(gòu)
ES技術(shù)細(xì)節(jié)部分主要介紹如下幾個方面。
1.Base on Apache Lucense
Lucense是高性能的搜索引擎庫,提供了查詢引擎、搜索引擎和文本分析引擎。但使用Lucense成本很高,需要掌握很多關(guān)于搜索的知識。而ES使用Lucense作為底層架構(gòu),在其上做了大量的易用性、擴(kuò)展性、容災(zāi)及性能方面工作,使得用戶經(jīng)過很少的配置就可以快速ES進(jìn)行數(shù)據(jù)存儲和檢索。
2.Distributed and horizontally scalable
ES是分布式的,可以水平擴(kuò)展,比如添加節(jié)點的時候能自動均衡數(shù)據(jù)。
3.Full-text search and powerful search
ES支持前文支持全文索引,并且搜索功能非常強大。
4.Document & Json
ES是基于文檔的強大組件,交互數(shù)據(jù)全部采用Json標(biāo)準(zhǔn)格式。
5.Restful API
圖2 ES集群組成
圖3 ES的寫入簡圖
6.Open Source
7.Query DSL
ES提供了基于JSON的query DSL查詢語言,傳統(tǒng)的SQL語句很容易轉(zhuǎn)化成query DSL。后面做的關(guān)于MySQL和ES的性能比對也是將標(biāo)準(zhǔn)SQL改寫成query DSL實現(xiàn)的。Translog為ES提供高性能以及數(shù)據(jù)安全保障。
從圖2中可以看到,ES集群是由多個節(jié)點組成,上圖中有1個master節(jié)點和2個data節(jié)點組成,并且創(chuàng)建了1個索引,索引有4個數(shù)據(jù)分片和1個副本組成。
如圖3所示,ES的寫操作分為兩類,一類是涉及到路由變更的索引創(chuàng)建和刪除(簡稱為索引的寫入),另一類是基于文檔的創(chuàng)建、更新和刪除(簡稱為文檔的寫入)。
下面單獨來進(jìn)行介紹:
1.索引的寫入
無論是索引的創(chuàng)建還是刪除,都必須在master上進(jìn)行。因此,如果寫入的請求是發(fā)到了非master節(jié)點,該節(jié)點會講對應(yīng)的創(chuàng)建或者刪除的請求轉(zhuǎn)發(fā)給master,master會創(chuàng)建并修改元數(shù)據(jù)和路由信息,并將對應(yīng)的修改同步到其他的候選的master機(jī)器上,至少需要需要一半以上的候選master返回后才算寫入成功。
2.文檔的寫入
文檔的寫入的前提是所有的寫入都必須先發(fā)送到主分片上,大致的步驟為:
(1)文檔寫入請求發(fā)送到任意的一個節(jié)點。
(2)節(jié)點根據(jù)shard =hash(routing) % number_of_primary_shards確定數(shù)據(jù)所在的分片及根據(jù)元數(shù)據(jù)確認(rèn)主分片是在哪臺機(jī)器。
(3)在主分片上執(zhí)行寫入操作和translog寫入操作,并將請求發(fā)送到副本上進(jìn)行寫入和translog寫入。
(4)默認(rèn)是同步操作,必須主分片和副本分片都些成功財返回結(jié)果,也可以人為調(diào)整為異步操作,不過會有數(shù)據(jù)安全性問題。
注意:默認(rèn)ES提供近實時的搜索,也就是說文檔寫入或更新后不是馬上就能搜索出最新的變更,默認(rèn)需要過1秒reflush后才能看到,如果業(yè)務(wù)對實時性要求非常高,也可將reflush的相關(guān)的參數(shù)設(shè)置為request,即有新的請求就執(zhí)行reflush的操作,這種方式性能會較差。此外還可調(diào)用reflush的API手動進(jìn)行reflush操作。
ES的讀邏輯如圖4所示。
ES查詢時如果指定了routing相關(guān)的值,就會只掃描確定的1個或少數(shù)文檔,如果沒有指定routing相關(guān)的值,就需要掃描所有分片。因此還會涉及到查詢的拆分和合并的步驟。詳情如下:
(1)查詢請求發(fā)送到任意一個節(jié)點。
(2)如果指定了routing相關(guān)值,根據(jù)shard = hash(routing) % number_of_primary_shards公式就能直接計算出請求的數(shù)據(jù)所在的分片,然后將請求發(fā)送到對應(yīng)的分片就OK。如果指定routing的相關(guān)值,那么會發(fā)送到對應(yīng)查詢涉及到的所有分片(這就是請求拆分)。
圖4 ES的讀邏輯
(3)如果查詢只涉及到1個分片,查詢的分片所在的機(jī)器返回查詢結(jié)果到初始請求的節(jié)點,初始請求節(jié)點再將數(shù)據(jù)返回給業(yè)務(wù)。而如果查詢涉及到多個分片,初始節(jié)點就會將請發(fā)送給多個分片并發(fā)查詢,此時查詢的分片所在的機(jī)器返回查詢結(jié)果到初始請求的節(jié)點后,初始節(jié)點還需要再進(jìn)行結(jié)果的合并。初始節(jié)點將合并后的數(shù)據(jù)返回個業(yè)務(wù)。
ES有很完善的容災(zāi)機(jī)制,候選master一般有多個,data節(jié)點也有多個,因此節(jié)點異常的時候通過將訪問切換到別的節(jié)點來容災(zāi)。具體流程包含如下幾個流程:
1.故障發(fā)現(xiàn)
故障發(fā)現(xiàn)如圖5所示。從圖中可以看出,Master會去ping各個其他的節(jié)點,圖中只畫了datanode節(jié)點。而其他的節(jié)點也會去ping master節(jié)點,確認(rèn)master節(jié)點是否正常。默認(rèn)ping規(guī)則如下:
Discovery.zen.fd.ping_interval=1s 默認(rèn)每隔1秒探測1次
Discovery.zen.fd.ping_timeout=30s 默認(rèn)ping探測的超時時間為30秒
Discovery.zen.fd.ping_retry=3 默認(rèn)重試3次
備注:以上參數(shù)可以根據(jù)自己的網(wǎng)絡(luò)情況和業(yè)務(wù)需求進(jìn)行調(diào)整。
2.節(jié)點切換
master節(jié)點切換:
當(dāng)其他節(jié)點探測到master異常并達(dá)到重試次數(shù)后,候選節(jié)點會進(jìn)行競爭,選master的具體規(guī)則如下。
(1)每次選舉每個節(jié)點會把自己所知道的候選master節(jié)點根據(jù)nodeid進(jìn)行一次排序,然后選出第1個節(jié)點,暫且認(rèn)為它是master節(jié)點。
(2)如果對某個節(jié)點的投票數(shù)達(dá)到候選master數(shù)/2+1個并且該節(jié)點也選舉自己為master,那么這個節(jié)點即為master。否則重新選舉。
備注:之所以節(jié)點的投票數(shù)需要達(dá)到候選master數(shù)/2+1,是為了防止腦裂的問題發(fā)生。
data節(jié)點切換:
當(dāng)master節(jié)點檢測到某個data節(jié)點有異常時,操作大致如下。
(1)master剔除該data節(jié)點,如果ES數(shù)據(jù)配置了1份副本保存,此時不存在數(shù)據(jù)丟失的風(fēng)險,集群狀態(tài)為yelllow。如果數(shù)據(jù)沒有配置副本保存,則存在數(shù)據(jù)丟失,集群狀態(tài)為red。
(2)master對找出異常的data節(jié)點對應(yīng)的所有的數(shù)據(jù)分片,如果是主分片,則將其他節(jié)點上的副本分片提升為主分片,全部主分片恢復(fù)后,異常data節(jié)點涉及的數(shù)據(jù)讀寫都恢復(fù)正常。
(3)業(yè)務(wù)恢復(fù)正常以后,master會將異常節(jié)點的數(shù)據(jù)遷移到正常的節(jié)點。
(4)當(dāng)全部數(shù)據(jù)遷移完成后,集群狀態(tài)恢復(fù)為green。
圖5 故障發(fā)現(xiàn)
圖6 一個節(jié)點的ES Cluster
ES設(shè)計成能讓你靈活地擴(kuò)縮容模型,當(dāng)添加或減少data節(jié)點時,ES會自動對數(shù)據(jù)進(jìn)行均衡。如下幾個簡圖能讓你幾秒鐘了解ES的擴(kuò)容問題,下面幾個圖的索引設(shè)置為number_of_shards=3&& number_of_replicas=1,即索引為3個分片且每個分片有1個副本。
1.一個節(jié)點的ES Cluster
從圖6中可以看到雖然設(shè)置了1個副本,但是datanode1只分配了3個主分片。這是因為ES認(rèn)為如果副本和主分片在1臺機(jī)器上和沒有副本的效果一樣,當(dāng)那臺機(jī)器異常時,數(shù)據(jù)一樣丟失。因此ES沒有在那臺機(jī)器上分配副本分片。
2.擴(kuò)容一個節(jié)點后的ES Cluster
從圖7中,可以看到添加1個節(jié)點后,data節(jié)點2分配了2個副本。
3.再擴(kuò)容一個節(jié)點后的ES Cluster
如 圖 8,data節(jié) 點 1上的P1被移動到data節(jié) 點 3,data節(jié) 點 2上的R3被移動到了data節(jié)點3,這是因為添加節(jié)點后,ES會自動均衡數(shù)據(jù)。
圖7 擴(kuò)容一個節(jié)點后的ES Cluster
圖8 再擴(kuò)容一個節(jié)點后的ES Cluster
做為一個運維人員,在學(xué)習(xí)ES的時候,遇到了很多讓人驚喜的功能,整理出來和大家共享。
ES的group功 能 和HBase的group功能類似,可以將某些節(jié)點放到某一個group中,從而實現(xiàn)業(yè)務(wù)之間的隔離。
比如要將重點業(yè)務(wù)和普通業(yè)務(wù)隔離開來的話,就可以將重點業(yè)務(wù)放到指定的某個組,這個組不存在過保的設(shè)備,負(fù)載也比較低。而將普通業(yè)務(wù)放到普通的組中,這各組的設(shè)備由于比較老,故障率會比較高,組內(nèi)的機(jī)器負(fù)載也會高一些。
圖9 ES的group功能
如圖9所示,分別包含 groupA和 groupB,其 中g(shù)roupA中保存了某些索引,groupB中也保存著某些分片。ES有專門的參數(shù)控制索引可存儲在某個group或節(jié)點,具體參數(shù)如下:
ES從1.0版本開始支持使用部落節(jié)點(tribe node),所謂的部落節(jié)點,就是作為聯(lián)合客戶端提供訪問多個ElasticSearch集群的能力。業(yè)務(wù)只需要訪問部落節(jié)點,就可以獲取多個ES集群的數(shù)據(jù)。并且可以通過部落節(jié)點寫入數(shù)據(jù),寫入數(shù)據(jù)的時候部落節(jié)點會將寫入請求轉(zhuǎn)發(fā)到后端的集群節(jié)點進(jìn)行數(shù)據(jù)寫入。但是不支持創(chuàng)建索引的操作。
注意:如果部落節(jié)點對應(yīng)后端的ES集群含有相同的索引名稱就會出現(xiàn)莫名其妙的問題,因為ES的默認(rèn)行為是從中選擇一個。也就是說如果后端2個集群含有相同的索引名字,那么知會有一個索引會被訪問到。
部落節(jié)點的圖解如圖10所示。
ES還有個比較好的功能就是IO流控的功能,這個功能對于分布式存儲是非常必要的,比如可以限制文件合并的時候的IO,從而使系統(tǒng)更平穩(wěn)地運行。ES主要有節(jié)點級和索引級兩個限流機(jī)制。分別介紹如下:
1.節(jié)點級別限流sec
2.索引級別限流
圖10 ES部落節(jié)點功能
ES有類似于MySQL的慢查詢功能,可以記錄下慢的操作,從而讓運維人員能通過慢的操作找到問題所在。
默認(rèn)情況下慢日志是不開啟的,分別有query、fetch、index三類動作定義,如下是一個query的慢日志定義:
上面設(shè)置的意思如下:
查詢慢于10秒輸出一個WARN日志。
獲取慢于500毫秒輸出一個DEBUG日志。
索引慢于5秒輸出一個INFO日志。
ES有個查詢集群熱點線程的功能,這個功能在集群突然變慢的場景下特別有用,它將幫助你找到消耗資源最多的線程。熱點線程的使用方法如下:
返回的結(jié)果中含有線程所在的節(jié)點信息、線程消耗資源的情況、線程名稱以及相關(guān)的堆棧信息。