這也許是你看到過的最通俗易懂的ElasticSearch文章了(理論篇)

本周在數(shù)據(jù)庫研發(fā)和運營組做了關(guān)于ELK的分享,這個分享主要是居于ES部分做的相關(guān)理論和測試的結(jié)論。下面是對此次分享的文字版整理,希望對研究學(xué)習(xí)ElasticSearch的朋友們有幫助。

分享的主要內(nèi)容如下:

先來說一下去調(diào)研ES的初衷,是為了確認ElasticSearch是否能比較好地解決目前監(jiān)控DB遇到的幾個問題,如下圖所示:

監(jiān)控DB目前面臨的三個問題分別是:

容量瓶頸

監(jiān)控DB的數(shù)據(jù)量越來越大,單個表壓縮后有的已經(jīng)接近100G(一天的數(shù)據(jù)),目前采用的是MySQL來存儲,使用的TokuDB引擎。MySQL的擴容型并不好,因此無法快速的進行數(shù)據(jù)的擴容,目前的做法更多的是對過期的歷史數(shù)據(jù)進行清理。但是需要保留月初、月末以及節(jié)假日的數(shù)據(jù)。

性能瓶頸

監(jiān)控有很多聚合的查詢,在單表特別大的情況下,一個聚合SQL需要很長時間才能查詢出結(jié)果。無法很好展現(xiàn)監(jiān)控的實時效果。給業(yè)務(wù)的體驗也很糟糕。

穩(wěn)定性

如果監(jiān)控DB出現(xiàn)問題,會導(dǎo)致線上監(jiān)控曲線掉底,業(yè)務(wù)側(cè)會以為是自己線上出現(xiàn)了問題,這會給業(yè)務(wù)帶來很大的困擾,因此對監(jiān)控DB的穩(wěn)定性要求很高??雨犛训氖虑楸O(jiān)控DB還是盡量少干。

下面就來單獨介紹各個部分的內(nèi)容:

一、ELK簡介

(一)ELK的涵義

ELK其實是由三個組建組成,分別是ElasticSearch、Logstash以及Kibana。

1、E代表ElasticSearch,如下圖所示:

正上圖說的那樣,ELasticSearch是整個ELK的心臟,它負責(zé)索引的創(chuàng)建、搜索、分析以及數(shù)據(jù)的存儲等工作,這個組將在后面做詳細介紹。

2、L代表Logstash,如下圖所示:

Logstash是用來做數(shù)據(jù)采集、接收、處理和轉(zhuǎn)發(fā)的工具,它講采集來的數(shù)據(jù)經(jīng)過分析和處理以后,將數(shù)據(jù)發(fā)送到ElasticSearch存儲。它本身支持非常多的數(shù)據(jù)源。

3、K代表Kibana,如下圖所示:

Kibana的主要功能是負責(zé)將ES中數(shù)據(jù)進行炫酷的展示。

整理概括一下整個ELK就是:

Logstash負責(zé)數(shù)據(jù)采集、分析和處理,然后將數(shù)據(jù)發(fā)送給ElasticSearch做進一步的存儲、分析和搜索,最后Kibana講ElasticSearch中的數(shù)據(jù)炫酷地展示出來。

(二)ELk常用架構(gòu)

ELK的常用架構(gòu)如下圖所示(偷懶盜個圖):

使用Logstash Shipper來在機器上采集相關(guān)的數(shù)據(jù)或者日志,你可以理解為logstash的一個agent

中間使用redis做隊列,也有很多的公司使用kafka來代替redis。

(三)ELK在業(yè)界的使用情況

目前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ù)。

二、ES技術(shù)細節(jié)

ES技術(shù)細節(jié)部分主要介紹如下幾個方面:

(一)、ES的特性

1、Base on Apache Lucense

Lucense是高性能的搜索引擎庫,提供了查詢引擎、搜索引擎和文本分析引擎。但是使用Lucense成本很高,需要掌握很多關(guān)于搜索的知識。而ES使用Lucense作為底層架構(gòu),在其上做了大量的易用性、擴展性、容災(zāi)以及性能方面的工作,使得用戶經(jīng)過很少的配置就可以快速ES進行數(shù)據(jù)存儲和檢索。

2、Distributed and horizontally scalable

ES是分布式的,可以水平擴展,比如添加節(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

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)的。

(二)、ES集群組成和名詞解析

1、名稱解析

a、Cluster

ES由個data節(jié)點和1個master節(jié)點構(gòu)成ES 集群,ES集群具有容災(zāi)能力,官方建議的也是使用ES集群的方式來運維ES。

b、Node

Node是ES的節(jié)點,一般集群會有1個master節(jié)點,多個data節(jié)點,ES節(jié)點有如下幾種類型:

master節(jié)點

master的功能是維護ES集群的元數(shù)據(jù),比如創(chuàng)建刪除索引;監(jiān)控其他的節(jié)點,比如對故障節(jié)點進行剔除和協(xié)調(diào)故障恢復(fù)工作;此外master節(jié)點還負責(zé)分片具體分配給哪些節(jié)點。因此在擴容和這故障的時候,分片遷移到哪臺機器上也需要master來協(xié)調(diào)。

需要注意的是所有的涉及到路由變化的操作都必須master來做。

建議:master非常重要,比較大的集群建議講master獨立部署

data節(jié)點

data節(jié)點負責(zé)數(shù)據(jù)的存儲和檢索。

Coordinating節(jié)點

Coordinating節(jié)點不負責(zé)數(shù)據(jù)的存儲,只負責(zé)請求的轉(zhuǎn)發(fā),有點類似于負載均衡器

Tribal節(jié)點

tribal節(jié)點成為部落節(jié)點,通過它能夠查詢不通集群的ES數(shù)據(jù),有點類似于spider的功能。

c、Shard

Shard是分片的意思,一般一個很大的表為了保證其擴展能力都會水平切分為多個分片,類似于mysql的水平分表的概念。每個分片只存儲自己那部分的數(shù)據(jù)和索引信息,全部的分片數(shù)據(jù)的集合就是全量的數(shù)據(jù)。

因為分片建立以后,如果后面要增加分片,需要全量導(dǎo)入數(shù)據(jù),因此分片必須在創(chuàng)建索引之前就規(guī)劃好。具體的可以從索引的數(shù)據(jù)量、集群節(jié)點的個數(shù)和預(yù)計集群的規(guī)模等方面進行合理的評估。

d、Replica

Replica副本,ES官方建議至少1副本,否則容易出現(xiàn)數(shù)據(jù)丟失的風(fēng)險。在ES中副本主要有2個作用:

其一是提供數(shù)據(jù)安全性保障,其二副本也能夠分擔(dān)讀的請求,提高ES的性能。

e、Index

Index是索引的意思,和關(guān)系型數(shù)據(jù)庫中的索引很不一樣。ES中Index的概念類似于關(guān)系型數(shù)據(jù)庫中的database。

f、Type

Type是分類的意思,和關(guān)系型數(shù)據(jù)庫中table的概念比較類似。為提高性能,建議最好是一個Index就存儲一個Type的數(shù)據(jù)就好。

g、Mapping

Mapping的概念和關(guān)系型數(shù)據(jù)庫中的字段類型比較類似,如下ES中定義的Type字段類型:

h、Document

ES是文檔型的組建,Document類似于關(guān)系型數(shù)據(jù)庫的一行。在ES中就是一個文檔。

2、集群組成

從上圖中可以看到,ES集群是由多個節(jié)點組成,上圖中有1個master節(jié)點和2個data節(jié)點組成,并且創(chuàng)建了1個索引,索引有4個數(shù)據(jù)分片和1個副本組成。Translog為ES提供高性能以及數(shù)據(jù)安全保障。

(三)、ES的寫邏輯

ES的寫入簡圖如下:

ES的寫操作分為兩類,一類是涉及到路由變更的索引創(chuàng)建和刪除(簡稱為索引的寫入),另一類是基于文檔的創(chuàng)建、更新和刪除(簡稱為文檔的寫入)。

下面單獨來進行介紹:

1、索引的寫入

無論是索引的創(chuàng)建還是刪除,都必須在master上進行。因此,如果寫入的請求是發(fā)到了非master節(jié)點,該節(jié)點會講對應(yīng)的創(chuàng)建或者刪除的請求轉(zhuǎn)發(fā)給master,master會創(chuàng)建并修改元數(shù)據(jù)和路由信息,并將對應(yīng)的修改同步到其他的候選的master機器上,至少需要需要一半以上的候選master返回后才算寫入成功。

2、文檔的寫入

文檔的寫入的前提是所有的寫入都必須先發(fā)送到主分片上,大致的步驟為:

a、文檔寫入請求發(fā)送到任意的一個節(jié)點

b、節(jié)點根據(jù)shard = hash(routing) % number_of_primary_shards確定數(shù)據(jù)所在的分片以及根據(jù)元數(shù)據(jù)確認主分片是在哪臺機器

c、在主分片上執(zhí)行寫入操作和translog寫入操作,并且將請求發(fā)送到副本上進行寫入和translog寫入

d、默認是同步操作,必須主分片和副本分片都些成功財返回結(jié)果,也可以人為調(diào)整為異步操作,不過會有數(shù)據(jù)安全性問題。

注意:默認ES提供近實時的搜索,也就是說文檔寫入或者更新后不是馬上就能搜索出最新的變更,默認需要過1秒reflush后才能看到,如果業(yè)務(wù)對實時性要求非常高,也可以將reflush的相關(guān)的參數(shù)設(shè)置為request,即有新的請求就執(zhí)行reflush的操作,這種方式性能會比較差。此外你還可以調(diào)用reflush的API手動進行reflush的操作。

(四)、ES的讀邏輯

ES的讀邏輯如下圖所示:

ES查詢的時候如果指定了routing相關(guān)的值,就會只掃描確定的1個或者少數(shù)文檔,如果沒有指定routing相關(guān)的值就需要掃描所有的分片。因此還會涉及到查詢的拆分和合并的步驟。詳情如下:

a、查詢請求發(fā)送到任意一個節(jié)點

b、如果指定了routing的相關(guān)值,根據(jù)shard = hash(routing) % number_of_primary_shards公式就能直接計算出請求的數(shù)據(jù)所在的分片,然后將請求發(fā)送到對應(yīng)的分片就OK。如果指定routing的相關(guān)值,那么會發(fā)送到對應(yīng)查詢涉及到的所有分片(這就是請求拆分)。

c、如果查詢只涉及到1個分片,查詢的分片所在的機器返回查詢結(jié)果到初始請求的節(jié)點,初始請求節(jié)點再將數(shù)據(jù)返回給業(yè)務(wù)。而如果查詢涉及到多個分片,初始節(jié)點就會將請發(fā)送給多個分片并發(fā)查詢,此時查詢的分片所在的機器返回查詢結(jié)果到初始請求的節(jié)點后,初始節(jié)點還需要再進行結(jié)果的合并。初始節(jié)點將合并后的數(shù)據(jù)返回個業(yè)務(wù)。

(五)、ES的容災(zāi)

ES有很完善的容災(zāi)機制,候選master一般有多個,data節(jié)點也有多個,因此節(jié)點異常的時候通過將訪問切換到別的節(jié)點來容災(zāi)。具體流程包含如下幾個流程:

1、故障發(fā)現(xiàn)

故障發(fā)現(xiàn)如下圖所示:

從上圖中可以看出,Master會去ping各個其他的節(jié)點,圖中只畫了datanode節(jié)點。而其他的節(jié)點也會去ping master節(jié)點,確認master節(jié)點是否正常。默認ping規(guī)則如下:

Discovery.zen.fd.ping_interval=1s ?默認每隔1秒探測1次

Discovery.zen.fd.ping_timeout=30s 默認ping探測的超時時間為30秒

Discovery.zen.fd.ping_retry=3 ?默認重試3次

#備注,以上參數(shù)可以根據(jù)自己的網(wǎng)絡(luò)情況和業(yè)務(wù)需求進行調(diào)整。

2、節(jié)點切換

master節(jié)點切換

當(dāng)其他節(jié)點探測到master異常并達到重試次數(shù)后,候選節(jié)點會進行競爭,選master的具體規(guī)則如下:

a、每次選舉每個節(jié)點會把自己所知道的候選master節(jié)點根據(jù)nodeid進行一次排序,然后選出第1個節(jié)點,暫且人為它是master節(jié)點;

b、如果對某個節(jié)點的投票數(shù)達到 候選master數(shù)/2+1 個并且該節(jié)點也選舉自己為master,那么這個節(jié)點即為master。否則重新選舉;

備注:之所以節(jié)點的投票數(shù)需要達到候選master數(shù)/2+1,是為了防止腦裂的問題發(fā)生。

data節(jié)點切換

當(dāng)master節(jié)點檢測到某個data節(jié)點有異常的時候,做的操作大致如下:

a、master剔除該data節(jié)點,如果ES數(shù)據(jù)配置了1份副本保存,此時不存在數(shù)據(jù)丟失的風(fēng)險,集群狀態(tài)為yelllow。如果數(shù)據(jù)沒有配置副本保存,則存在數(shù)據(jù)丟失,集群狀態(tài)為red。

b、master對找出異常的data節(jié)點對應(yīng)的所有的數(shù)據(jù)分片,如果是主分片,則將其他節(jié)點上的副本分片提升為主分片,全部主分片恢復(fù)后,異常data節(jié)點涉及的數(shù)據(jù)讀寫都恢復(fù)正常。

c、業(yè)務(wù)恢復(fù)正常以后,master會將異常節(jié)點的數(shù)據(jù)遷移到正常的節(jié)點

d、全部數(shù)據(jù)遷移完成后,集群狀態(tài)恢復(fù)為green

(六)、ES的擴容

ES設(shè)計成能讓你靈活地擴縮容模型,當(dāng)你添加或者減少data節(jié)點的時候,ES會自動的對數(shù)據(jù)進行均衡。如下幾個簡圖能讓你幾秒鐘了解ES的擴容問題,下面幾個圖的索引設(shè)置為number_of_shards=3 &&?number_of_replicas=1,即索引為3個分片并且每個分片有1個副本。

1、一個節(jié)點的ES Cluster

從上圖中可以看到雖然設(shè)置了1個副本,但是datanode1只分配了3個主分片。這是因為ES認為如果副本和主分片在1臺機器上和沒有副本的效果一樣,當(dāng)那臺機器異常的時候,數(shù)據(jù)一樣丟失。因此ES沒有在那臺機器上分配副本分片。

2、擴容一個節(jié)點后的ES Cluster

從上圖中,可以看到添加1個節(jié)點后,data節(jié)點2分配了2個副本。

3、再擴容一個節(jié)點后的ES Cluster

從上圖中可以看到,data節(jié)點1上的P1被移動到了data節(jié)點3,data節(jié)點2上的R3被移動到了data節(jié)點3,這是因為添加節(jié)點后,ES會自動均衡數(shù)據(jù)。

三、ES讓人驚喜的功能

做為一個運維人員,在學(xué)習(xí)ES的時候,遇到了很多讓人驚喜的功能,整理出來和大家共享:

(一)、ES的GROUP功能

ES的group功能和HBase的group功能類似,可以將某些節(jié)點放到某一個GROUP中,從而實現(xiàn)業(yè)務(wù)之間的隔離。比如想講重點業(yè)務(wù)和普通業(yè)務(wù)隔離開來,就可以將重點業(yè)務(wù)放到指定的某個組,這個組不存在過保的設(shè)備,負載也比較低。而將普通業(yè)務(wù)放到普通的組中,這各組的設(shè)備由于比較老,故障率會比較搞,組內(nèi)的機器負載也會高一些。如下圖所示:

圖中有兩個組,分別是GroupA和GroupB,其中GroupA中保存這某些索引,GroupB中也保存著某些分片。ES有專門的參數(shù)控制索引可以存儲在某個Group或則節(jié)點,具體的參數(shù)如下:

cluster.routing.allocation.awareness.attributes

cluster.routing.allocation.include

cluster.routing.allocation.require

cluster.routing.allocation.exclude

(二)、ES部落節(jié)點功能

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é)點進行數(shù)據(jù)寫入。但是不支持創(chuàng)建索引的操作。注意:如果部落節(jié)點對應(yīng)后端的ES集群含有相同的索引名稱就會出現(xiàn)莫名其妙的問題,因為ES的默認行為是從中選擇一個。也就是說如果后端2個集群含有相同的索引名字,那么知會有一個索引會被訪問到。部落節(jié)點的圖解如下:

(三)、ES的IO流控功能

ES還有個比較好的功能就是IO流控的功能,這個功能對于分布式存儲是非常必要的,比如可以限制文件合并的時候的IO,從而使系統(tǒng)更平穩(wěn)地運行。ES主要有節(jié)點級和索引級兩個限流機制。分別介紹如下:

節(jié)點級別限流

Indices.store.throttle.type(none/merge/all)

可以選擇為none/merge/all三個值,意義分別如下:

none為不流控

merge為對合并做IO流控

all為對所有的操作做IO流控

Indices.store.throttle.max_bytes_per_sec

索引級別限流

Index.store.throttle.type(none/merge/all/node)

Index.store.throttle.max_bytes_per_sec

(四)、ES的慢日志功能

ES有類似于MySql的慢查詢功能,可以記錄下慢的操作,從而讓運維人員能通過慢的操作找到問題所在。默認情況下,慢日志是不開啟的,有三種動作可以定義,分別是query、fetch、index三類,如下是一個query的慢日志定義:

PUT /my_index/_settings

{

"index.search.slowlog.threshold.query.warn" : "10s",

"index.search.slowlog.threshold.fetch.debug": "500ms",

"index.indexing.slowlog.threshold.index.info": "5s"

}

上面設(shè)置的意思如下:

查詢慢于 10 秒輸出一個 WARN 日志。

獲取慢于 500 毫秒輸出一個 DEBUG 日志。

索引慢于 5 秒輸出一個 INFO 日志。

(五)、ES的發(fā)現(xiàn)熱點功能

ES有個查詢集群熱點線程的功能,這個功能在集群突然變慢的場景下特別有用,它將幫助你找到消耗資源最多的線程。熱點線程的使用方法如下:

curl 'http://localhost:9200/_nodes/hot_threads'

返回的結(jié)果中含有線程所在的節(jié)點信息、線程消耗資源的情況、線程名稱以及相關(guān)的堆棧信息,如下圖所示:

四、ES的性能

ES的性能主要從兩個維度來評估

(一)、ES VS InfluxDB

1、單節(jié)點ES和InfluxDB寫入性能對比(數(shù)據(jù)來自:http://km.oa.com/articles/show/334237?kmref=search&from_page=1&no=1

結(jié)論:ES單節(jié)點寫入性能最高在19w,InfluxDB在15w。在并發(fā)數(shù)超過20時,ES與InfluxDB的寫入性能均呈現(xiàn)出下降趨勢。

2、單節(jié)點ES和InfluxDB讀性能對比(數(shù)據(jù)來自:http://km.oa.com/articles/show/334237?kmref=search&from_page=1&no=1

結(jié)論:ES查詢性能整體比InfluxDB好很多,當(dāng)并發(fā)數(shù)較高時(40),ES查詢性能比InfluxDB高出近4倍,在2w左右。在并發(fā)線程數(shù)達到50時,InfluxDB出現(xiàn)鏈接錯誤,拒絕查詢請求。

備注:測試結(jié)果只所以和influxDB官方測試數(shù)據(jù)比較大,我因為TEG側(cè)對es本身和influx的測試工具都做了很多優(yōu)化,主要的優(yōu)化如下:

es優(yōu)化:關(guān)閉不必要的字段,routing,調(diào)整刷盤策略、shard數(shù)量等

influxDB測試工具優(yōu)化:支持routing、在保證查詢結(jié)果一致的情況下盡量優(yōu)化查詢語句

(二)、ES VS MySQL

這部分的測試是采用人工寫的SQL以及線上慢的SQL像結(jié)合的方式,測試結(jié)果如下:

備注:MySQL測試數(shù)據(jù)采用的是innodb引擎,并采用50%的壓縮比。

從性能來看ES要比MySQL要好,尤其在聚合的場景下。

五、ES替代監(jiān)控DB評估

1、性能評估

從線上實際SQL評估,ES的性能要比MySQL的性能好100倍以上,性能方面應(yīng)該不是瓶頸。

2、容量評估

優(yōu)化前ES實際占用容量和MySQL差不多,優(yōu)化后ES占用的容量為MySQL的40%左右。

3、可用性評估

ES本身有很好的伸縮機制和容災(zāi)機制,從目前的容災(zāi)測試來看,可用性能達到要求。

4、成本評估

目前監(jiān)控DB的瓶頸主要是在容量瓶頸,因此存儲量下降50%的情況下,設(shè)備量能下降到原來的50%,即成本下降50%。

5、研發(fā)評估

ES目前無權(quán)限認證(TEG已經(jīng)添加了ES的權(quán)限認證功能)

不支持事務(wù)目前監(jiān)控側(cè)也暫時沒問題。此外還有很大的部分需要研發(fā)側(cè)的評估,因為采用ES后如下兩個地方會有很大的變動:

數(shù)據(jù)上報部分需要改寫

查詢部分SQL以及格式處理需要改寫

六、感謝

特別感謝TEG同事@johngqjiang的指點,順便廣告一下,TEG基于ES上開發(fā)的時序數(shù)據(jù)庫CTSDB已經(jīng)開始大規(guī)模試用,需要試用的同事可以找johngqjiang進一步溝通。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容