天天看點

基于ELK的資料分析實踐——滿滿的幹貨送給你

很多人剛剛接觸ELK都不知道如何使用它們來做分析,經常會碰到下面的問題:

安裝完ELK不知從哪下手

拿到資料樣本不知道怎麼分解資料

導入到elasticsearch中奇怪為什麼搜不出來

搜到結果後,不知道它還能幹什麼

在利用ELK做資料分析時,大緻為下面的流程:

1 基于logstash分解字段

2 基于字段建立Mapping

3 檢視分詞結果

4 檢索

5 聚合

6 高亮

可能會根據第4步重複第2步的工作,調整分詞等規則。

我需要統計一個url對應的pv和uv,這個url需要支援全文檢索。每天同一個url都會産生一條資料。最後會按照特定的日期範圍對資料進行聚合。

下面就開始資料分析之路吧~

在使用logstash前,需要對它有一定的了解。logstash的元件其實很簡單,主要包括input、filter、output、codec四個部分。

input 用于讀取内容,常用的有stdin(直接從控制台輸入)、file(讀取檔案)等,另外還提供了對接redis、kafka等的插件

filter 用于對輸入的文本進行處理,常用的有grok(基于正規表達式提取字段)、kv(解析鍵值對形式的資料)、csv、xml等,另外還提供了了一個ruby插件,這個插件如果會用的話,幾乎是萬能的。

output 用于把fitler得到的内容輸出到指定的接收端,常用的自然是elasticsearch(對接ES)、file(輸出到檔案)、stdout(直接輸出到控制台)

codec 它用于格式化對應的内容,可以再Input和output插件中使用,比如在output的stdout中使用rubydebug以json的形式輸出到控制台

了解上面的内容後,再看看logstash的使用方法。

首先需要定義一個配置檔案,配置檔案中配置了對應的input,filter,output等,至少是一個input,output。

如我的配置檔案:

上面的配置最不容易了解的就是Grok,其實它就是個正規表達式而已,你可以把它了解成是一段正規表達式的占位。至于grok都有哪些關鍵字,這些關鍵字對應的正則都是什麼,可以直接參考logstash的源碼,目錄的位置為:

基于ELK的資料分析實踐——滿滿的幹貨送給你

另外一個技巧就是,如果開啟stdout并且codec為rubydebug,會把資料輸出到控制台,是以使用<code>.</code>代替,即可省略輸出,又能檢測到現在是否有資料正在處理。而且每個.是一個字元,如果把它輸出到檔案,也可以直接通過檔案的大小,判斷處理了多少條。

這樣,資料的預處理做完了.....

雖然說Es是一個文檔資料庫,但是它也是有模式的概念的。文檔中的每個字段仍然需要定義字段的類型,使用者經常會遇到明明是數字,在kibana卻做不了加法;或者明明是IP,kibana裡面卻不認識。這都是因為Mapping有問題導緻的。

在Elasticsearch中其實是有動态映射這個概念的,在字段第一次出現時,ES會自動檢測你的字段是否屬于數字或者日期或者IP,如果滿足它預定義的格式,就按照特殊格式存儲。一旦格式設定過了,之後的資料都會按照這種格式存儲。舉個例子,第一條資料進入ES時,字段檢測為數值型;第二條進來的時候,卻是一個字元串,結果可能插不進去,也可能插進去讀不出來(不同版本處理的方式不同)。

是以,我們需要事先就設定一下字段的Mapping,這樣之後使用的時候才不會困惑。

另外,Mapping裡面不僅僅有字段的類型,還有這個字段的分詞方式,比如使用标準standard分詞器,還是中文分詞器,或者是自定義的分詞器,這個也是很關鍵的一個概念,稍後再講。

建立Mapping有兩種方式:

建立索引時,可以直接指定它的配置和Mapping:

比如我們上面的URL場景,可以這麼建立索引:

PS,在上面的例子中,url需要有兩個用途,一個是作為聚合的字段;另一個是需要做全文檢索。在ES中全文檢索的字段是不能用來做聚合的,是以使用嵌套字段的方式,新增一個url.keyword字段,這個字段設定成keyword類型,不采用任何分詞(這是5.0的新特性,如果使用以前版本,可以直接設定string對應的index屬性即可);然後本身的url字段則采用預設的标準分詞器進行分詞。

這樣,以後在搜尋的時候可以直接以<code>query string</code>的方式檢索<code>url</code>,聚合的時候則可以直接使用<code>url.keyword</code>

如果字段為<code>https://www.elastic.co/guide/en/elasticsearch/reference/5.2</code>,使用standard标準分詞器,輸入<code>elastic</code>卻收不到任何結果,是不是有點懷疑人生。

我們做個小例子,首先建立一個空的索引:

然後查詢這個字段被分解成了什麼鬼?

得到的内容如下:

那麼你可能很郁悶,我就是要搜elastic怎麼辦!沒關系,換個分詞器就行了~比如elasticsearch為我們提供的<code>simple</code>分詞器,就可以簡單的按照符号進行切分:

得到的結果為:

這樣你就可以搜尋<code>elastic</code>了,但是前提是需要在Mapping裡面為該字段指定使用simple分詞器,方法為:

修改Mapping前,需要先删除索引,然後重建索引。删除索引的指令為:

不想删除索引,隻想改變Mapping?想得美....你當ES是孫悟空會72變?不過,你可以建立一個新的索引,然後把舊索引的資料導入到新索引就行了,這也不失為一種辦法。如果想這麼搞,可以參考reindex api,如果版本是5.0之前,那麼你倒黴了!自己搞定吧!

ES裡面檢索是一個最基礎的功能了,很多人其實這個都是一知半解。由于内容太多,我就結合Kibana講講其中的一小部分吧。

很多人安裝完kibana之後,登陸後不知道該幹啥。如果你的elasticsearch裡面已經有資料了,那麼此時你需要在Kiban建立對應的索引。

基于ELK的資料分析實踐——滿滿的幹貨送給你

如果你的es的索引是<code>name-2017-03-19</code>,<code>name-2017-03-20</code>這種名字+時間字尾的,那麼可以勾選1位置的選項,它會自動聚合這些索引。這樣在這一個索引中就可以查詢多個索引的資料了,其實他是利用了索引的模式比對的特性。如果你的索引僅僅是一個簡單的名字,那麼可以不勾選1位置的選項,直接輸入名字,即可。

基于ELK的資料分析實踐——滿滿的幹貨送給你

然後進入Kibana的首頁,在輸入框裡面就可以任意輸入關鍵字進行查詢了。

另外,這個輸入框,其實也可以輸入ES的DSL查詢文法,隻不過寫法過于蛋疼,就不推薦了。

如果不使用kibana,想在自己的程式裡面通路es操作,也可以直接以rest api的方式查詢。

比如查詢某個索引的全部内容,預設傳回10個:

再比如,增加一個特殊點的查詢:

在es中一個很重要的亮點,就是支援很多的聚合文法,如果沒有它,我想很多人會直接使用lucene吧。在ES中的聚合,大體上可以為兩類聚合方法,metric和bucket。metic可以了解成avg、sum、count、max、min,bucket可以了解為group by 。有了這兩種聚合方法,就可以對ES中的資料做很多處理了。

比如在kibana中,做一個最簡單的餅圖:

基于ELK的資料分析實踐——滿滿的幹貨送給你

其實它在背景發送的請求,就是這個樣子的:

如果不适用kibana,自己定義聚合請求,那麼可以這樣寫:

另外,聚合也支援嵌套聚合,就是跟terms或者sum等agg并列寫一個新的aggs對象就行。

如果是自己使用elasticsearch,高亮也是一個非常重要的内容,它可以幫助最後的使用者快速了解搜尋的結果。

基于ELK的資料分析實踐——滿滿的幹貨送給你

背景的原理,是利用ES提供的highlight API,針對搜尋的關鍵字,傳回對應的字段。該字段中包含了一個自定義的标簽,前端可以基于這個标簽高亮着色。

舉個簡單的例子:

上面的請求會針對content字段搜尋kimchy。并且傳回對應的字段,比如原來的字段内容時<code>hello kimchy</code>,經過高亮後,會再搜尋結果的hits中傳回:

這樣就可以直接利用highlight中的字段做前端的顯示了。

另外,上面的<code>&lt;em&gt;</code>标簽可以自定義,比如:

繼續閱讀