1. 程式人生 > 實用技巧 >DevOps元素週期表—2號元素Kibana

DevOps元素週期表—2號元素Kibana

Kibana 是一款開源的資料分析和視覺化平臺,它是 Elastic Stack 成員之一,設計用於和 Elasticsearch 協作。您可以使用 Kibana 對 Elasticsearch 索引中的資料進行搜尋、檢視、互動操作。您可以很方便的利用圖表、表格及地圖對資料進行多元化的分析和呈現。

目錄

  1. 引子
  2. ELK快速安裝
  3. Elasticsearch快速入門
  4. SpringBoot整合ELK日誌中心

ELK是Elastic公司提供的一套完整的日誌收集以及展示的解決方案,也就是我們常說的日誌中心,其中E代表Elasticsearch,L代表Logstash,K就是本文的中心Kibana。

Elasticsearch在其中擔當了資料來源的作用,用於對資料快速搜尋定位,這也是Github搜尋使用的解決方案。

在超大資料規模的情況下,能夠將查詢條件匹配然後返回,高亮顯示,你應該知道Elasticsearch的強大了。

Logstash的作用是日誌收集器,可以將不同來源的日誌資料進行處理輸出。下圖是我的Logstash配置檔案logstash.conf,配置分為兩個核心模組,input和output,input中是logstash開放的埠5000,用於應用將日誌提交給logstash,在output中是logstash處理完日誌後將日誌輸出的地方,可以看到是輸出到Elasticsearch,至於下面的使用者名稱密碼,如果你的Elasticsearch有設定即填,沒有設定則忽略。

Kibana的作用是對Elasticsearch中儲存的資料進行資料分析和視覺化處理。

Kibana主要的作用是對日誌進行視覺化處理,同樣的還有Grafana,不過Grafana可以指定多種資料來源,比如Prometheus,Mysql,Elasticsearch等

一. ELK快速安裝

​需要了解的ELK開放埠

  • 5000: Logstash TCP input
  • 9200: Elasticsearch HTTP
  • 9300: Elasticsearch TCP transport
  • 5601: Kibana
  • 方式一:

    使用docker安裝,克隆改倉庫https://github.com/deviantony/docker-elk

    在目錄下執行docker-compose up

  • 方式二:

    使用同版本的包,此處ELK三個包版本必須相同,以免使用出現問題,我本地都是7.1.0。

    我已經將三個同版本的包打包上傳好了,公眾號回覆【ELK】獲得網盤下載地址

    將包解壓後,在各個bin目錄下執行相應程式即可。

    # ..\elasticsearch-7.1.0\bin  .\elasticsearch.bat
    
    # E:\kibana-7.1.0\bin  .\kibana.bat
    

    類似這樣,先啟動elasticsearch。

    瀏覽器訪問 localhost:9200,可以看到elasticsearch的啟動狀態,然後啟動kibana,瀏覽器訪問 localhost:5601。

二. Elasticsearch快速入門

Ⅰ. 索引,文件和REST API

1. 文件
  • Elasticsearch是面向文件的,文件是所有可搜尋資料的最小單位。
    • 日誌檔案中的日誌項
    • 一部電影的具體資訊 / 一張唱片的詳細資訊
    • MP3播放器中的一首歌 / 一篇PDF文件中的具體內容
  • 文件會被序列化成JSON格式,儲存在ElasticSearch中
    • JSON物件由欄位組成
    • 每個欄位都有對應的欄位型別(字串/數值/布林/日期/二進位制/範圍型別)
  • 每個文件都有一個Unique ID
    • 你可以自己指定ID
    • 或者通過Elasticsearch自動生成
2. JSON文件
  • 一篇文件包含了一系列欄位。類似資料庫表中一條記錄

  • JSON文件,格式靈活,不需要預先定義格式

    • 欄位的型別可以指定或者通過ElasticSearch自動推算
    • 支援陣列/支援巢狀

3. 文件的元資料
  • 元資料,用於標註文件的相關資訊
    • _index 文件所屬的索引名
    • _type 文件所屬的型別名
    • _id 文件唯一id
    • _source 文件的原始Json資料
    • _all 整合所有欄位內容到該欄位,已被廢除
    • _version 文件的版本資訊
    • _score 相關性打分

4. 索引
  • Index — 索引是文件的容器,是一類文件的結合

    • Index體現了邏輯空間的概念:每個索引都有自己的Mapping定義,用於定義包含的文件的欄位名和欄位型別
    • Shard體現了物理空間的概念:索引中資料分散在Shard上
  • 索引的Mapping與Setting

    • Mapping定義文件欄位的型別
    • Setting定義不同的資料分佈
  • 索引的不同語義

索引(動詞)文件到ElasticSearch的索引(名詞)中

  • 名詞:一個ElasticSearch叢集中,可以建立很多個不同的索引
  • 動詞:儲存一個文件到ElasticSearch的過程也叫索引(Indexing)
    • ES中建立一個倒排索引的過程
  • 名詞: 一個B樹索引,一個倒排索引
5. Type

  • 在7.0之前,一個Index可以設定多個Types
  • 6.0開始,Type已經被Deprecated。7.0開始,一個索引只能有一個Type—"_doc"
6. 與關係型資料庫類比
RDBMS ElasticSearch
Table Index
Row Document
Column Filed
Schema Mapping
SQL DSL
  • 傳統關係型資料庫與ElasticSearch的區別
    • ElasticSearch — Schemaless / 相關性高 / 高效能全文檢索
    • RDMS — 事物性 / Join
7. REST API — 很容易被各種語言呼叫

8. 一些基本的API
  • Indices
    • 建立Index
      • PUT Movies
    • 檢視所有Index
      • _cat/indices
// 檢視指定索引的相關資訊   Mapping/Setting的設定
GET index_name
// 檢視指定索引的文件總數
GET index_name/_count
// 檢視指定索引的前10條文件
POST index_name/_search

// _cat indices API
// 對索引名稱進行萬用字元查詢
GET /_cat/indices/kibana*v&s=index
// 檢視索引狀態為綠的索引
GET /_cat/indices/v&health=green
// 按照文件個數排序
GET /_cat/indices/v&s=docs.count:desc

Ⅱ. 節點,叢集,分片和副本

1. 分散式系統的可用性與擴充套件性
  • 高可用性
    • 服務可用性 — 允許有節點停止服務
    • 資料可用性 — 部分節點丟失,不會丟失資料
  • 可擴充套件性
    • 請求量提示 / 資料的不斷增長 (將資料分佈到所有節點上)
2. 分散式特性
  • ElasticSearch的分散式架構的好處

    • 儲存的水平擴容
    • 提升系統的可用性,部分節點停止服務,整個叢集的服務不受影響
  • Elasticsearch的分散式架構

    • 不同的叢集通過不同的名字來區分,預設名字"elasticsearch"
    • 通過配置檔案修改,或者在命令列中 -E cluster.name=clustername 進行設定
    • 一個叢集可以有一個或多個節點
3. 節點
  • 節點是一個Elasticsearch的例項
    • 本質上就是一個JAVA程序
    • 一臺機器上可以執行多個Elasticsearch程序,但生產環境一個一機一個
  • 每個節點都有名字,通過配置檔案,或者啟動時通過 -E node.name=nodename進行設定
  • 每個節點在啟動之後,會分配一個UID,儲存在data目錄下
4. Master-ekigible nodes 和 Master Node
  • 每個節點啟動後,預設就是一個Master eligible節點
    • 可以設定node.master: false 禁止
  • Master-eligible節點可以參與選主流程,成為Master節點
  • 當第一個節點啟動時,他會將自己選舉為Master節點
  • 每個節點上都儲存了叢集的狀態,只有Master節點才能修改叢集的狀態資訊
    • 叢集狀態,維護了一個叢集中,必要的資訊
      • 所有的節點資訊
      • 所有的索引和其相關的Mapping與Setting資訊
      • 分片的路由資訊
    • 任意節點都能修改資訊會導致資料的不一致性
5. Data Node & Coordinating Node
  • Data Node
    • 可以儲存資料的節點,叫做Data Node。負責儲存分片資料。在資料擴充套件上起到了至關重要的作用
  • Coordinating Node
    • 負責接收Client的請求,將請求發到合適的節點,最終把結果匯聚到一起
    • 每個節點預設都起到Coordinating Node的職責
6. 其他的節點型別
  • Hot & Warm Node
    • 不同硬體配置的Data Node,用來實現Hot & Warm架構,降低叢集部署的成本
  • Machine Learning Node
    • 負責跑機器學習的Job,用來做異常檢測
  • Tribe Node
    • Tribe Node連線到不同的Elasticsearch叢集,並且支援將這些叢集當成一個單獨的叢集處理
7. 配置節點型別

8. 分片(Primary Shard & Replica Shard)
  • 主分片,用以解決資料水平擴充套件的問題。通過主分片,可以將資料釋出到叢集內所有節點上
    • 一個分片是一個執行的Lucene例項
    • 主分片在索引建立時指定,後續不允許修改,除非Reindex
  • 副本,用以解決資料高可用的問題。分片是主分片的拷貝
    • 副本分片數,可以動態調整
    • 增加副本數,還可以在一定程度上提高服務的可用性(讀取的吞吐)
9. 分片的設定
  • 對於生產環境中分片的設定,需要提前做好容量規劃
    • 分片數設定過小
      • 導致後續無法增加節點實現水品擴充套件
      • 單個分片的資料量太大,導致資料重新分配耗時
    • 分片數設定過大,7.0開始,預設主分片設定成1,解決了over- sharding的問題
      • 影響搜尋結果的相關性打分,影響統計結果的準確性
      • 單個節點上過多的分片,會導致資源浪費,同時也會影響效能
10. 檢視叢集狀態
  • 使用REST API

    • _cat/nodes
    • _cat/shard
  • 使用cerebro

    • 啟動訪問localhost:9000

Ⅲ. 文件的基本CRUD與批量操作

1. 文件的CRUD
  • Index (如果ID不存在,建立新的文件,如果存在,刪除原有的再建立,版本會增加)

    PUT my_index/_doc/1
    {
    	"user": "mike",
    	"comment": "hello"
    }
    
  • Create

    PUT my_index/_create/1
    {
    	"user": "mike",
    	"comment": "hello"
    }
    POST my_index/_doc(不用指定ID,自動生成)
    {
    	"user": "mike",
    	"comment": "hello"
    }
    
  • Read

    GET my_index/_doc/1
    
  • Update 文件必須存在,更新欄位

    POST my_index/_update/1
    {
    	"user": "mike",
    	"comment": "hello es"
    }
    
  • Delete

    DELETE my_index/_doc/1
    
2. Bulk API

支援在一次API呼叫中,對不同的索引進行操作

  • 支援四種類型操作
    • Index
    • Create
    • Update
    • Delete
  • 可以在URL中指定Index,也可以在請求的Payload中進行
  • 操作中單個操作失敗,不影響其他操作
  • 返回結果包括了每一條操作執行的結果
POST _bulk
{"index": {"_index": "test", "_id": "1"}}
{"field1": "value1"}
{"delete": {"_index": "test", "_id":"2"}}
3. 批量讀取 mget

批量操作,可以減少網路連線所產生的開銷,提高效能

GET _mget
{
	"docs": [
	{
		"_index": "user",
		"_id": 1
	},
	{
		"_index": "comment",
		"_id": 1
	}
	]
}
4. 批量查詢 msearch
POST my_index/_msearch
{}
{"query": {"match_all":{}, "from":0, "size":10}}
{}
{"query": {"match_all":{}}
{"index": "twitter2"}
{"query": {"match_all":{}}

Ⅳ. 倒排索引

1. 正排與倒排索引
  • 目錄頁,根據目錄頁索引,正排索引,章名稱+頁碼號
  • 根據關鍵字進行索引到目錄頁,倒排索引

在搜尋引擎中

  • 正排索引 — 文件ID到文件內容和單詞的關聯
  • 倒排索引 — 單詞到文件ID的關係

2. 倒排索引的核心組成
  • 倒排索引包含兩個部分
    • 單詞詞典,記錄所有文件的單詞,記錄單詞到倒排列表的關聯關係
      • 單詞詞典一般比較大,可以通過B+樹或者雜湊拉鍊法實現,以滿足高效能的插入與查詢
    • 倒排列表,記錄了單詞對應的文件結合,由倒排索引項組成
      • 倒排索引項
        • 文件ID
        • 詞頻TF
        • 位置 — 單詞在文件中分詞的位置。用於語句搜尋
        • 偏移 — 記錄單詞的開始結束位置,實現高亮顯示

3. Elasticsearch的倒排索引
  • Elasticsearch的JSON文件中的每個欄位,都有自己的倒排索引
  • 可以指定對某些欄位不做索引
    • 優點: 節省儲存空間
    • 缺點:欄位無法被搜尋

Ⅴ. 通過Analyzer進行分詞

1. Analysis與Analyzer
  • Analysis — 文字分析是把全文字轉換為一系列單詞(term/token)的過程,也叫分詞

  • Analysis是通過Analyzer來實現的

    • 可使用Elasticsearch內建的分析器/或者按需定製分析器
  • 除了在資料寫入時轉換詞條,匹配Query語句時也需要用相同的分析器對查詢語句進行分析

2. Analyzer的組成
  • 分詞器是專門處理分詞的元件,Analyzer由三部分組成

    • Character Filter,針對原始文字處理,例如去除html / Tokenizer 按照規則切分為單詞 / Token Filter 將切分的單詞進行加工,小寫,刪除stopwords,增加同義詞

3. Elasticsearch內建分詞器

4. 使用_analyzer API
  • 直接指定Analyzer進行測試

    GET /_analyze
    {
    	"analyzer": "standard",
    	"text": "Mastering Elasticsearch, elasticsearch in Action"
    }
    
  • 指定索引欄位進行測試

    POST books/_analyze
    {
    	"field": "title",
    	"text": "Mastering Elasticsearch"
    }
    
  • 自定義分詞進行測試

POST /_analyze
{
	"tokenizer": "standard",
	"filter": ["lowercase"],
	"text": "Mastering Elasticsearch"
}
5. 中文分詞
  • 中文句子,切分成一個一個詞,而不是字

  • 英文中,單詞有自然空格分隔

  • 一句中文,不同上下文有不同理解

    • 這個蘋果,不大好吃 / 這個蘋果,不大,好吃!
  • 安裝ICU Analyzer

在elasticsearch的bin目錄下執行

elasticsearch-plugin install analysis-icu

提供了Unicode的支援,更好的支援亞洲語言

6. 更多好用的中文分詞器
  • LK
    • 支援自定義詞庫,支援熱更新分詞字典
  • THULAC
    • THU Lexuacal Analyzer for Chinese,清華大學自然語言處理和社會人文計算實驗室的一套中文分詞器

Ⅵ. Search API概覽

1. Search API
  • URI Search
    • 在URL中使用查詢引數
  • Request Body Search
    • 使用Elasticsearch提供的,基於JSON格式的更加完備的Query Domain Specific Language(DSL)
2. 指定查詢的索引
  • /_search 叢集上所有的索引
  • /index1/_search 索引index1
  • /index1,index2/_search 索引index1和2
  • /index*/_search 查詢index開頭的索引
3. Request Body

4. 搜尋Response

1. 通過URI query實現搜尋
GET /movies/_search?q=2012&df=title&sort=year:desc&from=0&size=10&timeout=1s
{
	"profile": true
}
  • q 指定查詢語句,使用Query String Syntax
  • df 預設欄位,不指定時,會對所有欄位進行查詢
  • sort 排序 / from和size用於分頁
  • profile 可以檢視查詢是如何被執行的
2. Query String Syntax
  • 指定欄位 v.s 範查詢

    • q=title:2012 / q=2012

      查詢title存在2012的,查詢存在2012的

  • Term v.s Phrase

    • Beautiful Mind 等效於Beautiful OR Mind
    • "Beautiful Mind",等效於Beautiful AND Mind。Phrase查詢,要求前後順序一致
  • 分組與引號

    • title:(Beautiful AND Mind) ---> title:Beautiful title:Mind
    • title="Beautiful Mind" ---> title:Beautiful Mind
  • 布林操作

    • AND / OR / NOT 或者 && / || / !
      • 必須大寫
      • title:(matrix NOT reloaded)
  • 分組

    • + 表示must
    • -表示must_not
    • title:(+matrix -reloaded)
  • 萬用字元查詢(不建議使用,佔用記憶體大,查詢效率低)

    • ? 代表1個字元,*代表0或者多個
      • title:mi?d
      • title:be*
  • 正則表達

    • title:[bt]oy 匹配boy / toy
  • 模糊匹配與近似匹配

    • title:befutifl~1 允許輸入錯一個
    • title:"lord rings"~2 可以不用相鄰,挨著兩個

Ⅷ. Request Body Search與Query DSL

  • 將查詢語句通過HTTP Request Body傳送給Elasticsearch

  • Query DSL

    POST /movies,404_idx/_search?ignore_unavailable=true
    {
    	"profile": true,
    	"query": {
    		"match_all": {}
    	}
    }
    
2. 使用查詢表示式 Match
GET /comments/_doc/_search
{
	"query": {
		"match": {
			"comment": "Last Christmas"
		}
	}
}

GET /comments/_doc/_search
{
	"query": {
		"match": {
			"comment": {
				"query":"Last Christmas",
				"operator": "AND"
			}
		}
	}
}
3. Query String Query

類似URI Query

POST users/_search
{
	"query": {
		"query_string": {
			"default_field": "name",
			"query": "Ruan AND Ming"
		}
	}
}

三. SpringBoot整合ELK日誌中心

SpringBoot整合ELK的核心在於將日誌傳送給logstash的開放埠,常用的方案就是使用logstash提供好的日誌上傳包。

<dependency>
 <groupId>net.logstash.logback</groupId>
 <artifactId>logstash-logback-encoder</artifactId>
 <version>5.1</version>
</dependency>

新增該依賴,該依賴提供了一個appender類LogstashTcpSocketAppender,是logback日誌框架的上報日誌需要的類的實現,在logback.xml中新增相應的appender規則即可,指定輸出到logstash埠。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />

    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>127.0.0.1:5000</destination>
        <!-- 上述埠為elk-docker預設 -->
        <!-- 日誌輸出編碼 -->
        <encoder charset="UTF-8"
                 class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        "logLevel": "%level",
                        "serviceName": "${springAppName:-}",
                        "pid": "${PID:-}",
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="LOGSTASH" />
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>

記得將logstash的配置檔案也進行修改。

input {
    tcp {
    port => 5000
    codec => json_lines # 上傳使用json_lines外掛格式化
    }
}

output {
    elasticsearch {
        hosts => "elasticsearch:9200"
    }
}

啟動ELK三個應用,然後啟動你的SpringBoot應用,就可以在索引管理中看到應用的日誌索引了。

然後在管理中建立索引模式,將你的應用索引新增進去,就可以在儀表盤中對日誌進行搜尋服務了。