ELK Stack總結

ELK Stack

本文基於ELK 6.0,主要針對Elasticsearch和Kibana。node

介紹

Elasticsearch is a realtime, distributed search and analytics engine that is horizontally scalable and capable of solving a wide variety of use cases.mysql

優點git

  • Schemaless, document-oriented:存儲JSON documents,更加靈活(不規定每條數據的必須具有哪些列)
  • Searching:全文text檢索,日期、數字、地理位置、IP地址等均可以。
  • Analytics:尤爲是明細數據
  • Rich client library support and the REST API Easy to operate and easy to scale 部署簡單、外部依賴少
  • Near real time, Lightning fast, Fault tolerant

缺點:資源更多,須要更多機器。在數據量大時聚合統計方面查詢延遲與併發不如Druid。github

組成web

Elasticsearch:做爲核心,存儲全部數據,提供搜索和分析。sql

Logstash:集中數據,包括日誌、指標等(相似flume)。集中時能夠對數據進行各類轉換,定位爲ETL引擎。json

Logstash的Shipper、Broker、Indexer分別和Flume的Source、Channel、Sink各自對應!只不過是Logstash集成了,Broker能夠不須要,而Flume須要單獨配置,且缺一不可。整體來講Flume的配置比較繁瑣,偏向數據傳輸,Logstash更簡單且功能也更多,如解析預處理。bootstrap

Kibana:ES的可視化工具。數組

Elasticsearch

概念1(基礎)

Elasticsearch是文件導向型存儲,JSON文件是第一公民。

索引:含有相同屬性的文檔集合(小寫不含下劃線),至關於database。分結構化和非結構化

類型:索引能夠定義一個或多個類型,文檔必須屬於一個類型,至關於table

文檔:能夠被索引的基本數據單位,至關於record。

在6.0後,索引只能有一個類型。

分片:每一個索引都有不少個分片,每一個分片是一個Lucene索引。只能建立索引時指定數量,默認爲5。

備份:拷貝一份分片就完成了分片的備份

數據類型

text data, numbers, booleans, binary objects, arrays, objects, nested types, geo-points, geo-shapes, and many other specialized datatypes such as IPv4 and IPv6 addresses

6.0引入scaled_float,其存儲價格數據效率高,例如10.05在內部其實是1005的integer。

elasticsearch採用倒排索引的數據結構,分爲Term,Frequency和Documents (Postings)三列。其中term爲詞,Documents列也可能存儲改詞在文本中的位置。默認elasticsearch會對全部field建立倒排索引。當插入document時,elasticsearch就會解析這個document全部的filed,並添加到倒排索引中。

CRUD基本用法

Restful API基本格式:http://<ip>:<port>/ <索引> / <類型> / <文檔id>

經常使用的四種請求方式:GET、PUT、POST、DELETE

PUT: 建立索引和文檔增長

POST: 文檔增長、查詢索引和文檔修改

GET: 查詢文檔

DELETE: 刪除文檔和刪除索引

若是不想本身設置文檔id,那就須要用post而不是put

建立結構化索引

若是不建立而直接put來插入數據,elasticsearch會自動建立索引和類型,但一些默認設置可能不會符合預期。因此這裏就直接放手動建立index的例子了。另外,若是put的數據包含新的field,elasticsearch也會自動建立新的field。

在postman中put下面json到localhost:9200/index_name

例子1,下面的json會建立索引和類型(名爲man)
{
    "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1
    },
    "mappings": {
        "man": { // 類型
            "properties": {
                "country": {
                    "type": "keyword"
                },
                "age": {
                    "type": "integer"
                },
                "date": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd||epoch_millis"
                }
            }
        }
    }
}
// 添加新類型。下面假設已經建立了catalog index,那麼執行下面語句就會新增一個category類型。若是第二次執行下面代碼,換成不一樣的field,那麼就是添加新field
PUT /catalog/_mapping/category
{
  "properties": {
    "name": {
      "type": "text"
    }
  }
}

例子2
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 5, // 通常將分片限制在10~20G
    "index.store.type": "niofs" ,// 性能更好
    "index.query.default_field": "title", // 默認查詢字段
    "index.unassigned.node_left.delayed_timeout": "5m" // 當某個節點掛掉時,不立刻回覆分片
     "analysis": { // 解析器,看下面概念2
        "analyzer": {
            "std": {
                "type": "standard",
                "stopwords": "_english_"
            }
        }
     }
  },
  "mappings": {
    "house": {
      "dynamic": false, // 用"strict"就徹底不讓結構變化
      "_all": {
      "enabled": false // 6已經廢除,默認爲true。會將所有字段拼接爲總體做全文索引
      },
      "properties": {
        "houseId": {
          "type": "long"
        },
        "title": {
          "type": "text", // text類型都會在創建索引前會被分詞來支持全文搜索
          "index": "analyzed" // 須要分詞
        },
        "price": {
          "type": "integer"
        },
        "createTime": {
          "type": "date",
          "format": "strict_date_optional_time||epoch_millis"
        },
        "cityEnName": {
          "type": "keyword" // 內部使用keyword解析器(noop tokenizer),即做爲總體不須要分詞,支持sorting, filtering, and aggregations
        },
        "regionEnName": {
          "type": "keyword"
        },
        "tags": { // 這個filed內部還有一個fields,名爲raw,實際上這個field的全稱爲type.raw結果tags會以兩種方式存儲。text和keyword。
          "type": "text",
          "fields": {
            "raw": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

插入數據

在postman用put + http://<ip>:<port>/ <索引> / <類型> / <文檔id> + json代碼便可

自動生成id的話,用post + 去掉<文檔id>

讀取數據

用get

修改

直接修改:post + http://<ip>:<port>/ <索引> / <類型> / <文檔id> /_update

  • json{"doc":{"屬性": "值"}}

  • 腳本修改(painless是內置語言)

{
    "script": {
        "lang": "painless",
        "inline": "ctx._source.age = params.age",
        "params": {
            "age": 100
        }
    }
}

Elasticsearch內部實現是針對原數據添加一個新版本。

刪除

在postman用delete,或者在插件中操做。

概念2(文本解析器)

文本分析基礎

Elasticsearch的解析器會將分本分割成詞,這會發生在indexing和searching兩個階段。以後還需根據這些詞創建索引。每一個field能夠用不一樣的解析器。

解析器按順序分爲三個部分:

  • 0個或多個Character filters:能夠增長、刪除或修改character,例如過濾掉無心義的詞,替換詞,使得某些詞的意義更明顯(表情變爲文字)。

  • 1個Tokenizer:生成標記/詞。另外它產出每一個token在輸入流中的位置。

    POST _analyze
    {
    "tokenizer": "standard",
    "text": "Tokenizer breaks characters into tokens!"
    }

    上面使用Standard Tokenizer對文本進行分析,結果之一以下

    {
    "token": "Tokenizer",
    "start_offset": 0,
    "end_offset": 9,
    "type": "<ALPHANUM>",
    "position": 0
    }

  • 0個或多個連續的Token filters:能夠增長、刪除或修改tokens,例如lowercase、stop token

查詢

在postman用post + http://<ip>:<port>/ <索引> /_search

  • Searching all documents in all indices: GET /_search
  • Searching all documents in one index: GET /catalog/_search
  • Searching all documents of one type in an index: GET /catalog/product/_search
  • Searching all documents in multiple indices: GET /catalog,my_index/_search
  • Searching all documents of a particular type in all indices: GET /_all/product/_search

子條件查詢

特定字段查詢所指特定值。分爲Query context和Filter context。

  • Query context:除了判斷文檔是否知足條件外,還會計算_score來標識匹配度。
    • 全文本查詢full-text query:針對文本類型數據。分模糊匹配、習語匹配、多個字段匹配、語法查詢。match, match phrase, mulit match。若是針對keyword類型,並不會在查詢時進行分詞,即變成term query。全文本查詢的流程以下:

      能夠添加的選項:

      • match:operator,默認or;minimum_should_match;fuzziness
      • match_phrase:slop,默認0,能夠有多少個字不一樣
    • 字段級別查詢term query:針對結構化數據,如數字、日期等。這種級別在查詢階段不會像上面那樣進行分詞和重寫查詢。range, term
  • Filter context:返回準確的匹配,比Query快。這類查詢還有助於elasticsearch緩存結果(01數組)exists
// 模糊查詢,下面匹配會返回含有China或Country的數據。改成match_phrase就是準確匹配(China Country做爲一個詞組)。
// from是從哪一行開始search,size是返回多少條符合的數據。
{
    "query": {
        "match": { // 默認排序得分:China和Country按正確順序且相鄰的分數會比「正確順序不相鄰」或」不正確順序相鄰」高,只有其中之一的分數更低。默認operator是or
            "country": "China Country"
        }
    },
    "from": 0,
    "size": 2,
    "sort": [ 
        {"age": {"order": "desc"}}
    ]
}
{// 多字段查詢,下面address和country列中有apple的都會查詢出來
    "query": {
        "multi_match": {
            "query": "apple",
            "fields": ["address", "country^2"] // 表示country的權重更大
        }
    }
}
{// 語法查詢
    "query": {
        "query_string": {
            "query": "apple OR pear"
        }
    }
}
{// 字段查詢,準確匹配(和習語的區別?)。下面有兩種選擇,term和constant_score,前者Query context會算分,後者Filter context不會
    "query": {
        "term": {
            "author": "apple"
        }
        "constant_score": {
            "filter": {
                "term": {
                    "manufacturer.raw": "victory multimedia"
                }
            }
        }
    }
}
{ // range能夠用於數值、日期、 score boosting的數據(即讓經過range的數據得到更高的分數,默認爲1,從而在混合查詢中設置權重)
    "query": {
        "range": {
            "age": {
                "gte": 10, // "01/09/2017", "now-7d/d", "now"等針對日期,其中加上"/d"表示round
                "lte": 50,
                "boost": 2.2,
                "format": "dd/MM/yyyy" // 針對日期
            }
        }
    }
}

{
    "query": {
        "exists": {
            "field": "description"
        }
    }
}

filter
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "age": 20
                }
            }
        }
    }
}

複合查詢

以必定邏輯組合子條件查詢。經常使用的分爲固定分數查詢、布爾查詢等

// 固定分數查詢,這裏把查詢的分數固定爲2,即filter中返回yes的數據分數爲2
{
    "query": {
        "constant_score": {
            "filter": {
                "match": {
                    "title": "apple"
                }
            },
            "boost": 2
        }
    }
}

// 布爾查詢,這裏should表示知足一個條件就夠了。must就是都要知足。must和should在query context中執行子句,除非整個bool查詢包含在filter context。must not和filter屬於filter context。
{
    "query": {
        "constant_score": { // 整個bool查詢包含在filter context。
            "filter": {
                "bool": {
                    "should": [{ // 至關於or複合
                            "range": {
                                "price": {
                                    "gte": 10,
                                    "lte": 13
                                }
                            }
                        },
                        {
                            "term": {
                                "manufacturer.raw": {
                                    "value": "valuesoft"
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}
{ // 這個查詢一樣是整個bool查詢包含在filter context。
    "query": {
        "bool": {
            "must_not": {
                ....original query to be negated...
            }
        }
    }
}
{
    "query": {
        "bool": {
            "should": [
                {
                    "match": {
                        "author": "apple"
                    }
                },
                {
                    "match": {
                        "tittle": "fruit"
                    }
                }
            ],
            "filter": [
                {
                    "term": {
                        "age": 20
                    }
                }
            ]
        }
    }
}

其餘複合查詢還有:Dis Max query, Function Score query, Boosting query, Indices query

分析/聚合

POST / / /_search

聚合類型

  • Bucket aggregations:相似group by,group的數量能夠是自定義規則的一個或多個,能夠固定數量,能夠動態增長。group能夠根據固定數值、時間間隔、自定義範圍、基數(cardinality)、filter(自定義條件)、GeoHash Grid進行劃分。
    • Bucketing on string data: terms,若是get的結尾是_search?size=0,那麼只返回count排第一的。這和terms內部的size參數不同,後者是考慮的bucket的數量,下面「返回結果指標」中說起默認爲10。

    • Bucketing on numeric data

      • histogram:設置"interval": 1000表示每隔1000爲一個bucket,而後返回每一個bucket的所含document的數量。另外可設置min_doc_count,規定能劃分爲bucket的最小document數量。

      • range:更靈活地設置範圍。下面key可選。

        "ranges": [
            { "key": "Upto 1 kb", "to": 1024},
            { "key": "1 kb to 100 kb", "from": 1024, "to": 102400 },
            { "key": "100 kb and more", "from": 102400 }
        ]
    • Aggregating filtered data:agg前添加query/filter

    • Nesting aggregations:在Bucket agg內部進行Metric agg。參考下面的閱讀理解

    • Bucketing on custom conditions:

      • filter,建立根據自定義filter規則一個bucket

      • filters,建立多個bucket

        "aggs": {
          "messages": {
              "filters": {
                  "filters": {
                      "chat": {"match": {"category": "Chat"}},
                      "skype": {"match": {"application": "Skype"}},
                      "other_than_skype": {
                        "bool": {
                              "must": {"match": {"category": "Chat"}},
                              "must_not": {"match": {"application": "Skype"}}
                          }
                      }
                  }
              }
          }
        }
    • Bucketing on date/time data:可參考下面閱讀理解

      "aggs": {
          "counts_over_time": {
              "date_histogram": {
                  "field": "time",
                  "interval": "1d",
                  "time_zone": "+05:30"
              }
          }
      }
    • Bucketing on geo-spatial data(略)

    返回結果指標:

    • doc_count_error_upper_bound表示
    • sum_other_doc_count:total count of documents that are not included in the buckets returned 默認10個,因此若是bucket少於10個,就會是0。若是多於10個,那麼該指標表示的就是排10以後的類別的數據總量。
  • Metric aggregations:sum, average, minimum, maximum等,裏面不能包含其餘agg。

  • Matrix aggregations:5.0的新特徵

  • Pipeline aggregations:(略)

// 較爲完整的json
{
    "aggs": {
        ...type of aggregation...
    },
    "query": { // optional query part
        ...type of query...
    },
    "size": 0 // 搜索返回的數量,若是隻須要聚合,能夠把這個設置爲0
}
{ // 下面得出各個年齡的數據行數。terms可改成stats(若是同時須要sum, avg, min, max, and count,這個效率更高), extended stats(更多指標),min, max, sum,cardinality等
    "query": { // 縮小聚合範圍
      "term": {
         "customer": "Linkedin"
      }
    },
    "aggs": {
        "group_by_age": { // 本身起的名字
            "terms": {
                "field": "age"
            }
        },
        "group_by_xxx": {
            //...
        }
    }
}

// 閱讀理解Nesting aggregations。考慮特定時段和公司的每一個用戶消耗的總帶寬,每一個部門中排名前兩位的用戶
// GET /bigginsight/usageReport/_search?size=0
{
    "query": {
        "bool": {
            "must": [{
                    "term": {
                        "customer": "Linkedin"
                    }
                },
                {
                    "range": {
                        "time": {
                            "gte": 1506257800000,
                            "lte": 1506314200000
                        }
                    }
                }
            ]
        }
    },
    "aggs": {
        "by_departments": {
            "terms": {
                "field": "department"
            },
            "aggs": {
                "by_users": {
                    "terms": {
                        "field": "username",
                        "size": 2,
                        "order": {
                            "total_usage": "desc"
                        }
                    },
                    "aggs": {
                        "total_usage": {
                            "sum": {
                                "field": "usage"
                            }
                        }
                    }
                }
            }
        }
    }
}
// 閱讀理解Bucketing on date/time data
// GET /bigginsight/usageReport/_search?size=0
{
    "query": {
        "bool": {
            "must": [
              {"term": {"customer": "Linkedin"}},
              {"range": {"time": {"gte": 1506277800000}}}
            ]
        }
    },
    "aggs": {
        "counts_over_time": {
            "date_histogram": {
                "field": "time",
                "interval": "1h",
                "time_zone": "+05:30"
            },
            "aggs": {
                "hourly_usage": {
                    "sum": {"field": "usage"}
                }
            }
        }
    }
}

概念3(架構原理的補充)

數據存儲

一個分片實際指一個單機上的Lucene索引。Lucene索引由多個倒排索引文件組成,一個文件稱爲一個segment。Lucene經過commit文件記錄全部的segment。每當有信息插入時,會把他們寫到內存buffer,達到時間間隔便寫到文件系統緩存,而後文件系統緩存真正同步到磁盤上,commit文件更新。固然,這裏也會有translog文件來防治commit完成前的數據丟失(translog也有更新間隔、清空間隔參數)。與Hbase相似,segment也有merge過程,也能夠設置各類歸併策略。

數據存儲到哪一個shard取決於shard = hash(routing) % number_of_primary_shards.rounting默認狀況下爲_id值。

請求處理

elasticsearch收到請求時,其實是master節點收到,它會做爲coordinator節點,經過上面提到的公式,告訴其餘相關node處理請求,當處理結束後會收集響應併發回給client。這個處理過程與Kafka相似,也有寫完主分片返回仍是等備份完成才返回。因此分片的數量會影響並行度。

Logstash基礎

log做用:troubleshoot、監控、預測等

log的挑戰:格式不統1、非中心化、時間格式不統1、數據非結構化

Logstash:構建一個管道,從各類輸入源收集數據,並在到達各類目的地前解析,豐富,統一這些數據。

架構:datasource - inputs(create events) - filters(modify the input events) - outputs - datadestination。中間三個組成logstash管道,每一個組成之間使用in-memory bounded queues,也能夠選擇persistent queues。

簡單運行例子:logstash -e 'input { stdin { } } output {stdout {} }'

logstash -f simple.conf -r # -r能夠在conf更新時自動重置配置
#simple.conf
#A simple logstash configuration
input {
    stdin {}
}
filter {
    mutate {
        uppercase => ["message"]
    }
}
output {
    stdout {
        codec => rubydebug # codec is used to encode or decode incoming or outgoing events from Logstash
    }
}

Overview of Logstash plugins

./bin/logstash-plugin list --verbose:list of plugins that are part of the current installation,verbose版本,--group filter屬於filter的。

input

file{
    path => ["D:\es\app*","D:\es\logs*.txt"]
    start_position => "beginning"
    exclude => ["*.csv]
    discover_interval => "10s"
    type => "applogs"
}

beats {
  host => "192.168.10.229"
  port => 1234
}

JDBC

input {
    jdbc { # 一個jdbc只能一個sql查詢
        # path of the jdbc driver
        jdbc_driver_library => "/path/to/mysql-connector-java-5.1.36-bin.jar "
        # The name of the driver class
        jdbc_driver_class => "com.mysql.jdbc.Driver"
        # Mysql jdbc connection string to company database
        jdbc_connection_string => "jdbc:mysql://localhost:3306/company"
        # user credentials to connect to the DB
        jdbc_user => "user"
        jdbc_password => "password"
        # when to periodically run statement, cron format(ex: every 30 minutes)
        schedule => "30 * * * *"
        # query parameters
        parameters => {
            "department" => "IT"
        }
        # sql statement。能夠用statement_filepath
        statement => "SELECT * FROM employees WHERE department=: department AND
        created_at >=: sql_last_value "
        # 其餘參數
        jdbc_fetch_size =>
        last_run_metadata_path => # 存儲sql_last_value的位置,這個配置是按照這個元數據來schedule的。能夠設置根據某column值來schedule。
    }
    jdbc { ... }
}
output {
    elasticsearch {
        index => "company"
        document_type => "employee"
        hosts => "localhost:9200"
    }
}

output

elasticsearch {
    ...
}
csv {
    fields => ["message", "@timestamp","host"]
    path => "D:\es\logs\export.csv"
}
kafka {
    bootstrap_servers => "localhost:9092"
    topic_id => 'logstash'
}

Ingest node(略)

用Logstash構建數據管道(略)

Kibana的數據可視化

測試數據來源:https://github.com/elastic/elk-index-size-tests/blob/master/logs.gz

經過Logstash加上下面的conf把數據導入elasticsearch

input {
    file {
        path => ".../Elastic_Stack/data/logs"
        type => "logs"
        start_position => "beginning"
    }
}
filter {
    grok {
        match => {
            "message" => "%{COMBINEDAPACHELOG}"
        }
    }
    mutate {
        convert => {
            "bytes" => "integer"
        }
    }
    date {
        match => ["timestamp", "dd/MMM/YYYY:HH:mm:ss Z"]
        locale => en
        remove_field => "timestamp"
    }
    geoip {
        source => "clientip"
    }
    useragent {
        source => "agent"
        target => "useragent"
    }
}
output {
    stdout {
        codec => dots
    }
    elasticsearch {}
}

curl -X GET http://localhost:9200/logstash-*/_count如無心外有300,000條。

使用Kibana進行分析的前提是數據已經加載到Elasticsearch,而後在management處指定index。index一般有兩類:time-series indexes:(一般有多個index,其名字以時間結尾)、regular index。若是第一次使用Logstash加載數據到elasticsearch,把Index Name or Pattern設置爲logstash-*,Time Filter field name設置爲@timestamp便可。

Discover

指定index後在Discover Page處設置時間段,2014-05-28 00:00:00.0002014-07-01 00:00:00.000

這份數據是www.logstash.net的網站log,訪問這個網站的top1中國城市無疑是北京,但以後的竟然是廣州、廈門、福州、深圳...

搜索欄

使用與Google、百度有點相似。

  • a b:只要有a或b的document都返回
  • "a b":精確搜索
  • field1: a:在field1中搜索
  • AND, OR, - (must not match):boolean搜索。注意「-」與value之間沒有空格
  • (...):grouping搜索
  • field1:[start_value TO end_value]:用{}則不包含邊界
  • 通配符:即使是Elasticsearch也不推薦前綴模糊
  • 正則:至關耗CPU
  • 以前提到的elasticsearch查詢

其餘本身摸索基本都知道怎麼用。

Visualization

  • Analyzing the response codes over time
    1. Click on New and select Vertical Bar
    2. Select Logstash-* under From a New Search, Select Index
    3. In the X axis, select Date Histogram and @timestamp as the field
    4. Click Add sub-buckets and select Split Series
    5. Select Terms as the sub aggregation
    6. Select response.keyword as the field

  • Finding the top 10 URLs requested

    新建,選擇Data Table,index選擇同上。buckets type選擇Split Rows,Aggregation選擇Terms,field選擇request.keyword,size選擇10,結果以下:

  • Analyzing the bandwidth usage of the top five countries over time

    新建,選擇Area,index選擇同上。Y軸選擇sum, bytes;X軸選擇DateHistogram, @timestamp;sub-buckets選擇Split Series, Terms, geoip.country_name.keyword。最後要把sub-buckets拉到X軸前面。這樣纔是先找到前5的國家,而後對時間軸進行劃分。

  • Finding the most used user agent

    新建,選擇Coordinate Map,index選擇同上。bucket選擇Geo Coordinates,Geohash,geoip.location, Options處選擇Map類型爲Heatmap

  • Analyzing the web traffic originating from different countries

    新建,選擇Tag Cloud,index選擇同上。bucket選擇Tags,Terms,useragent.name.keyword

Dashboards(略)

Timelion

中美比較
.es(q='geoip.country_code3:US',metric='avg:bytes').label('United States'), .es(q='geoip.country_code3:CN',metric='avg:bytes').label('China')

與以後一週的比較
.es(q='geoip.country_code3:CN',metric='sum:bytes').label('Current Week'),
.es(q='geoip.country_code3:CN',metric='sum:bytes',
offset=-1w).label('Previous Week')

Metricbeat

metricbeat由modules和metricsets組成。modules定義收集指標的基本邏輯,如鏈接方式、收集頻率、收集哪些指標。每一個modules有一到多個metricsets。metricsets是經過給監控對象發送單個請求來收集其列指標的組件,它構建event數據並把數據轉移到output。metricbeat的result guarantees是at least once。

好處:

  • 即使所監控的對象不能訪問,也會返回錯誤事件
  • 整合多個相關指標到單一事件數據
  • 會發送元數據,這有利於數據的mapping、確認、查詢、過濾等。
  • 沒有數據轉換功能,返回的都是raw data

event structure

{ // 下面@timestamp,metricset,beat的信息是每條常規event都有的。
    "@timestamp": "2017-11-25T11:48:33.269Z",
    "@metadata": {
        "beat": "metricbeat",
        "type": "doc",
        "version": "6.0.0"
    },
    "system": {
        // metric 信息
    },
    "metricset": {
        "name": "xxx", // Name of the metricset that the data is from
        "rtt": 2000, // Round trip time of the request in microseconds
        "module": "system"
    },
    "beat": {
        "version": "6.0.0",
        "name": "SHMN-IN",
        "hostname": "SHMN-IN"
    }
}

配置metricbeat

  • Module configuration

    6.0開始有modules.d目錄,裏面各個服務都有各自的yml,如mysql.yml,相關配置在裏面設置。樣式參考system.yml。

  • General settings :name、tags、max_procs

  • Output configuration

    output.elasticsearch:
     enabled: true
     hosts: ["localhost:9200"]
     username: "elasticuser" # 若是設置了權限
     password: "password"
     pipeline: "ngnix_log_pipeline" # 若是要用ingest node的話
     index: "metricbeat-%{[beat.version]}-%{+yyyy.MM.dd}" # 默認index格式
     # 下面是index的另外一種實現。當index被重寫時注意要設置setup.dashboards.enabled: false和setup.template.enabled: false,除非提供 setup.template.name 和 setup.template.pattern
     index: "logs-%{+yyyy.MM.dd}"
     indices:
       - index: "debug-%{+yyyy.MM.dd}"
         when.contains:
           message: "DEBUG"
       - index: "error-%{+yyyy.MM.dd}"
         when.contains:
           message: "ERR"
    
    output.logstash:
     hosts: ["localhost:5045", "localhost:5046"]
     loadbalance: true
    
    # 測試
    output.console:
     enabled: true
     pretty: true

    在metricbeat.yml中開啓dashboard功能。這樣打開kibana的dashboard就會有默認提供的dashboard模版了。

運行

./metricbeat -e

在Kibana中查看

下圖爲6.0以上的dashboard,須要elasticsearch和kibana都是6.0以上才能夠。比5.0的好看很多。

下面是system overview

下面是host overview部分信息,注意若是metricbeat.yml的general setting中的那麼改變了,要在搜索上寫上本身設置的名字。

部署和配置

備份與恢復

在全部節點的elasticsearch.yml文件配置hdfs存儲備份的位置path.repo: ["/mount/es_backups"]

而後在此註冊文件夾下注冊命名存儲庫,名字下面用backups。
curl -XPUT 'http://localhost:9200/_snapshot/backups' -H 'Content-Type:
application/json' -d '{
 "type": "fs",
 "settings": {
 "location": "/mount/es_backups/backups",
 "compress": true
 }
}'

快照(參考,到時候寫進腳本),默認是incremental的。
curl -XPUT
'http://localhost:9200/_snapshot/backups/backup_201710101930?pretty' -H
'Content-Type: application/json' -d'
{
 "indices": "bigginsight,logstash-*",
 "ignore_unavailable": true,
 "include_global_state": false
}'

查看快照
curl -XGET 'http://localhost:9200/_snapshot/backups/_all?pretty'

恢復
curl -XPOST 'http://localhost:9200/_snapshot/backups/backup_201710101930/_restore'

index aliases

生產環境一般是爲production index建立連接,並讓應用使用這些連接而不是直接使用production index

POST /_aliases
{
 "actions" : [
 { "remove" : { "index" : "index1", "alias" : "current_index" } },
 { "add" : { "index" : "index2", "alias" : "current_index" } }
 ]
}

index templates

設置下面index模版後,每當插入的數據採用新的index,且匹配reading,就會自動執行模版建立index。

PUT _template/readings_template 
{
    "index_patterns": ["readings*"], // 任何新索引若是匹配到這個模式就會使用這個模版
    "settings": {
        "number_of_shards": 1
    },
    "mappings": {
        "reading": {
            "properties": {
                "sensorId": {
                    "type": "keyword"
                },
                "timestamp": {
                    "type": "date"
                },
                "reading": {
                    "type": "double"
                }
            }
        }
    }
}

時間序列數據

一個index存儲大量時間序列數據並不是好事,一般以時間,如天、周做爲單位新增索引。這主要考慮到shard數量、mapping的變化、過期數據的處理:

shard數量

須要根據當前業務的數據量來估計,但shard一旦設定就不能修改了。不合理的shard數量會影響相關評分和聚合準確度:

  • 評分:相對頻率是基於各個分片內而不是基於全部分片。
  • 聚合:聚合一樣是基於各個分片,例如top10則取個分片的top10。若是某個bucket位於其中一個分片返回的前n個bucket中,而且該bucket不是任何其餘分片的前n個bucket之一,則協調節點聚合的最終計數會忽略這個bucket。

mapping的變化

隨着業務的變化,fields可能會增長,有些fields會過期,過多deprecated field耗費資源

其餘

client.transport.sniff爲true來使客戶端去嗅探整個集羣的狀態,把集羣中其它機器的ip地址自動加到客戶端中

當ES服務器監聽使用內網服務器IP而訪問使用外網IP時,不要使用client.transport.sniff爲true,在自動發現時會使用內網IP進行通訊,致使沒法鏈接到ES服務器,而直接使用addTransportAddress方法進行指定ES服務器。

// 一些優化說明

post
localhost:9200/index_name/type_name/_search?explain=true
    
禁止刪除索引時使用通配符
put + http://<ip>:<port>/_cluster/settings 動態方式改設置
{
    "transient": {
        "action.destructive_requires_name": true
    }
}

put + http://<ip>:<port>/_all/_settings?preserve_existing=true
{
    index.refresh_interval: "30s"
}

非動態改設置,即在config文件中改
discovery.zen.fd.ping_interval: 10s
discovery.zen.fd.ping_timemout: 120s
discovery.zen.fd.ping_retries: 3

master節點通常不存儲數據
node.master: true
node.data: false
針對數據節點,關閉http功能。從而減小一些插件安裝到這些節點,浪費資源。
http.enable: false

負載均衡節點:master和data都爲false,但通常不用自帶的

內存設定:JVM針對內存小於32G纔會優化,因此每一個節點不要大於這個值。另外堆內存至少小於可用內存的50%,留空間給Apache Lucene。

寫入數據從index改成bulk

參考:

Learning Elastic Stack 6.0

相關文章
相關標籤/搜索