ELK Stack

简介

  ELK stack 是以Elasticsearch、Logstash、Kibana三个开源软件为主的数据处理工具链,在于实时数据检索和分析场合,三个通常是配合使用,而且又先后归于Elastic.co公司名下,故有此简称。在5.0版本之后又加入Elastic公司的Beats工具,改名叫Elastic Stack。

ELK Stack有如下几个优点:

  • 处理方式灵活。Elasticsearch 是实时全文索引,不需要像 storm 那样预先编程才能使用;
  • 配置简易上手。Elasticsearch 全部采用 JSON 接口,Logstash 是 Ruby DSL 设计,都是目前业界最通用的配置语法设计;
  • 检索性能高效。虽然每次查询都是实时计算,但是优秀的设计和实现基本可以达到全天数据查询的秒级响应;
  • 集群线性扩展。不管是 Elasticsearch 集群还是 Logstash 集群都是可以线性扩展的;
  • 前端操作炫丽。Kibana 界面上,只需要点击鼠标,就可以完成搜索、聚合功能,生成炫丽的仪表板。
  • 而ELK Stack加入Beats中的filebeat之后更加优秀,filebeat是一个轻量级的日志收集处理工具,Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。
ELK Stack组成

通常情况下的ELK是由Elasticsearch、Logstash和Kibana组成。

ELK之间的合作机制:

  • L(logstash)作为作为信息收集者,主要是用来对日志的搜集、分析、过滤,支持大量的数据获取方式,一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。
  • E(Elasticsearch)作为数据的保存者,保存来自L(Logstash)收集的系统日志数据,并建立索引,以及提供之后对数据的检索。
  • K(Kibana)作为展示者,主要是将ES上的数据通过页面可视化的形式展现出来。包括可以通过语句查询、安装插件对指标进行可视化等。

一、Logstash

  Logstash 项目诞生于 2009 年 8 月 2 日。其作者是世界著名的运维工程师乔丹西塞(JordanSissel)
  2013 年,Logstash 被 Elasticsearch 公司收购,ELK Stack 正式成为官方用语(随着 beats 的加入改名为 Elastic Stack)。Elasticsearch 本身 也是近两年最受关注的大数据项目之一,三次融资已经超过一亿美元。在 Elasticsearch 开发人员的共同努力下,Logstash 的发布机制,插件架构也愈发科学和合理。
  Logstash 是一个具有实时渠道能力的数据收集引擎。使用 JRuby 语言编写。logstash就像是一根具备实时数据传输能力的管道,负责将数据信息从管道的输入端传输到管道的输出端;与此同时这根管道还可以让根据需求在中间加上滤网,Logstash提供里很多功能强大的滤网以满足各种应用场景。

image.png
Logstash 安装

官方下载地址:https://www.elastic.co/downloads/logstash

1、安装JDK

[root@linux ~]# tar -xf jdk-8u211-linux-x64.tar.gz
[root@linux ~]# mv jdk-8u211 /usr/local/java
[root@linux ~]# vim /etc/profile.d/jdk.sh
JAVA_HOME=/usr/local/java
PATH=$PATH:JAVA_HOME/bin
export JAVA_HOME PATH
[root@linux ~]# java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)

2、安装Logstash

[root@linux ~]# tar -xf logstash-6.5.4.tar.gz
[root@linux ~]# mv logstash-6.5.4 /usr/local/logstash

① Logstash的stdin标准输入

标准输入(屏幕输入)
标准输出(输出屏幕)

[root@linux ~]# cd /usr/local/logstash/
[root@linux logstash]# mkdir -p etc/conf.d
[root@linux logstash]# vim etc/conf.d/stdin.conf
input {
    stdin {}
}
output {
    stdout {
        codec => rubydebug
    }
}
[root@linux logstash]# bin/logstash -f etc/conf.d/stdin.conf

image.png

image.png

② Logstash的file输入文件

logstash只有第一次读取文件的时候会读取整个文件的内容,而后只会读取更新的记录

vim etc/conf.d/file.conf
input {
    file {
        path => "var/log/message"
        start_position => beginning
    }
}
output {
    stdout {
        codec => rubydebug
    }
}

参数
• discover_interval
logstash每隔多久去检查一次被监听的目录下是否有新文件,默认是15秒
• exclude
可以排除不想监听的文件
• sincedb_write_interval
logstash 每隔多久写一次 sincedb 文件,默认是 15 秒。
• stat_interval
logstash 每隔多久检查一次被监听文件状态(是否有更新),默认是 1 秒。
• start_position
logstash 从什么位置开始读取文件数据,默认是结束位置,也就是说 logstash 进程会以类似 tail -F 的形式运行。如果你是要导入原有数据,把这个设定改成 "beginning",logstash 进程就从头开始读取,有点类似 cat,但是读到最后一行不会终止,而是继续变成 tail -F。

start_position 仅在该文件从未被监听过的时候起作用。如果 sincedb 文件中已经有这个文件的 inode 记录了,那么 logstash 依然会从记录过的 pos 开始读取数据。所以重复测试的时候每回需要删除 sincedb 文件

③ Logstash的tcp读取网络数据

[root@linux logstash]vim etc/conf.d/tcp.conf
input {
    tcp {
        port => 666
    }
}
output {
    stdout {
        codec => rubydebug
    }
}
[root@linux ~]# nc 127.0.0.1 666 < a.txt
image.png

根据logstash这个特性,可以通过配置接受filebeat传的数据

④ Logstash过滤器之grok正则匹配

Grok是logstash最重要的插件

grok模式的语法如下:
%{SYNTAX:SEMANTIC}
SYNTAX: 代表匹配值的类型,例如3.44可以用NUMBER类型所匹配,127.0.0.1可以 使用IP类型匹配
SEMANTIC:代表存储该值的一个变量名称,例如 3.44 可能是一个事件的持续时间,127.0.0.1可能是请求的client地址。所以这两个值可以用 %{NUMBER:duration} %{IP:client} 来匹配。

begin 123.456 end

%{WORD} %{NUMBER:request_time:float} %{WORD}

logstach 预定义字段

filter {
    grok {
        match => {"message" => "%{COMBINEDAPACHELOG} %{QS:x_forwarded_for}"}
    }
}

⑤ Logstash过滤器之mutate数据修改

filters/mutate 插件是 Logstash 另一个重要插件。它提供了丰富的基础类型数据处理能力。包括类型转换,字符串处理和字段处理等。

类型转换
可以设置的转换类型包括:"integer","float" 和 "string"。示例如下:

filter {
    mutate {
        convert => ["request_time", "float"]
    }
}

⑥ Logstash过滤器之mutate数据处理

字符串处理
split

filter {
   mutate {
       split => ["message", "|"]
   }
}

随意输入一串以|分割的字符,比如 "123|321|adfd|dfjld*=123"

image.png

join
仅对数组类型字段有效

filter {
    mutate {
        split => ["message", "|"]
    }
    mutate {
        join => ["message", ","]
    }
}

filter 区段之内,是顺序执行的。所以最后看到的输出结果是:

image.png

字段处理
rename

重命名某个字段,如果目的字段已经存在,会被覆盖掉:

filter {
    mutate {
        rename => ["host", "host_name"]
    }
}
image.png

update
更新某个字段的内容。如果字段不存在,不会新建。
replace
作用和 update 类似,但是当字段不存在的时候,它会起到 add_field 参数一样的效果,自动添加新的字段。

⑦ Logstash过滤器之GeoIP地址查询

GeoIP 是最常见的免费 IP 地址归类查询库,同时也有收费版可以采购。GeoIP 库可以根据 IP 地址提供对应的地域信息,包括国别,省市,经纬度等,对于可视化地图和区域统计非常有用。

配置示例

filter {
    geoip {
        source => “message”    
    }
}

GeoIP 库数据较多,如果不需要这么多内容,可以通过 fields 选项指定自己所需要的。下例为全部可选内容:

filter {
    geoip {
        fields => ["city_name", "continent_code", "country_code2", "country_code3", "country_name", "dma_code", "ip", "latitude", "longitude", "postal_code", "region_name", "timezone"]
    }
}

⑧ Logstash过滤器之useragent匹配归类

可以获取浏览器版本、型号以及系统版本

配置示例

filter {
    useragent {
        target => "ua"
        source => "useragent"
    }
}

⑨ Logstash过滤器之split拆分事件

split 拆分事件
可以把一行数据,拆分成多个事件
配置示例

filter {
    split {
        field => "message"
        terminator => "#" 
    }
}

在 intputs/stdin 的终端中输入一行数据:"test1#test2",输出结果如下


image.png

⑩ Logstash的output配置

标准输出(stdout)
配置示例

output {
    stdout {
        codec => rubydebug
    }
}

保存成文件(file)
配置示例

output {
    file {
        path => "/path/to/%{+yyyy/MM/dd/HH}/%{host}.log.gz"
        message_format => "%{message}"
        gzip => true    
    }
}

output/file 插件首先需要注意的就是message_format参数。插件默认是输出整个event的json形式数据。所以需要定义为%{message},前提是在之前的filter插件中,没有使用remove_field或者update等参数删除或修改%{message}字段的内容

保存进elasticsearch

配置示例

output {
    elasticsearch {
        host => “IP”
        index => “logstash-%{type}-%{+YYYY.MM.dd}” 
        index_type => “%{type}”
    }
}

index => "索引名” 写入的elasticsearch索引的名称,可以使用变量。还提供了%{+YYYY.MM.dd}这种写法。此外,索引名中不能有大写字母。

输出到redis

配置示例

input { stdin {} }
output {
    redis {
        data_type => “channel” 
        key => “logstash-chan-%{+yyyy.MM.dd}”   
    }
}

Logstash的配置文件

image.png

二、Elasticsearch

Elasticsearch 来源于作者 Shay Banon 的第一个开源项目 Compass 库,而这个 Java 库最初的目的只是为了给 Shay 当时正在学厨师的妻子做一个菜谱的搜索引擎。2010 年,Elasticsearch 正式发布。至今已经成为 GitHub 上最流行的 Java 项目,不过 Shay 承诺给妻子的菜谱搜索依然没有面世……
2015 年初,Elasticsearch 公司召开了第一次全球用户大会 Elastic{ON}15。诸多 IT 巨头纷纷赞助,参会,演讲。会后,Elasticsearch 公司宣布改名 Elastic,公司官网也变成 http://elastic.co/。这意味着 Elasticsearch 的发展方向,不再限于搜索业务,也就是说,Elastic Stack 等机器数据和 IT 服务领域成为官方更加注意的方向。随后几个月,专注监控报警的 Watcher 发布 beta 版,社区有名的网络抓包工具 Packetbeat、多年专注于基于机器学习的异常探测 Prelert 等 ITOA 周边产品纷纷被 Elastic 公司收购。

Elasticsearch核心概念

cluster

代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。

node

代表集群中的一个节点,节点也有一个名称(默认是随机分配的),默认节点会去加入一个名称为“elasticsearch”的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群,集群中一个节点会被选举为主节点(master),它将临时管理集群级别的一些变更,例如新建或删除索引、增加或移除节点等。主节点不参与文档级别的变更或搜索,这意味着在流量增长的时候,该主节点不会成为集群的瓶颈。

document&field

一个文档是一个可被索引的基础信息单元,比如:一个document可以是一条客户数据,一条商品分类数据,一条订单数据等。通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。

index

一个索引就是一个拥有几分相似特征的文档的集合。比如可以有一个客户索引,商品分类索引,订单索引等。一个index包含很多document,一个index就代表了一类类似的或者相同的document。

type

每个索引里都可以有一个或多个type,type是index中的一个逻辑数据分类,一个type下的document,都有相同的field

shards

代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。

replicas

代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。

recovery

代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。

discovery.zen

代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。

Transport

代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协(通过插件方式集成)。

ES数据架构(与关系型数据库mysql对比)
image.png

(1)关系型数据库中的数据库(DataBase),等价于ES中的索引(Index)
(2)一个数据库下面有N张表(Table),等价于1个索引Index下面有N多类型(Type),
(3)一个数据库表(Table)下的数据由多行(ROW)多列(column,属性)组成,等价于1个Type由多个文档(Document)和多Field组成。
(4)在一个关系型数据库里面,schema定义了表、每个表的字段,还有表和字段之间的关系。 与之对应的,在ES中:Mapping定义索引下的Type的字段处理规则,即索引如何建立、索引类型、是否保存原始索引JSON文档、是否压缩原始JSON文档、是否需要分词处理、如何进行分词处理等。
(5)在数据库中的增insert、删delete、改update、查search操作等价于ES中的增PUT/POST、删Delete、改_update、查GET.

Elasticsearch的配置
#设置集群名字
 cluster.name: cswuyg_qa_pair_test
#设置node名字
 node.name: xxx-node
# 允许一个节点是否可以成为一个master节点,es是默认集群中的第一台机器为master,如果这台机器停止就会重新选举master. 
node.master: true 
# 允许该节点存储数据(默认开启) 
node.data: true 
# 数据存储位置
path.data: /data1/es-data/
#设置节点域名
 network.host: x.x.x.x
#设置内部传输端口和外部HTTP访问端口
 transport.tcp.port: 9300
 http.port: 9200
#设置集群其它节点地址
 discovery.zen.ping.unicast.hosts: ["xxxhost:yyyport"]

三、Kibana

简介:

Logstash 早期曾经自带了一个特别简单的 logstash-web 用来查看 ES 中的数据。其功能太过简单,于是 Rashid Khan 用 PHP 写了一个更好用的 web,取名叫 Kibana。这个 PHP 版本的 Kibana 发布时间是 2011 年 12 月 11 日。

Kibana 迅速流行起来,不久的 2012 年 8 月 19 日,Rashid Khan 用 Ruby 重写了 Kibana,也被叫做 Kibana2。因为 Logstash 也是用 Ruby 写的,这样 Kibana 就可以替代原先那个简陋的 logstash-web 页面了。

目前看到的 angularjs 版本 kibana 其实原名叫 elasticsearch-dashboard,但跟 Kibana2 作者是同一个人,换句话说,kibana 比 logstash 还早就进了 elasticsearch 名下。这个项目改名 Kibana 是在 2014 年 2 月,也被叫做 Kibana3。全新的设计一下子风靡 DevOps 界。随后其他社区纷纷借鉴,Graphite 目前最流行的 Grafana 界面就是由此而来,至今代码中还留存有十余处 kbn 字样。

2014 年 4 月,Kibana3 停止开发,ES 公司集中人力开始 Kibana4 的重构,在 2015 年初发布了使用 JRuby 做后端的 beta 版后,于 3 月正式推出使用 node.js 做后端的正式版。

Kibana是一个为Elasticsearch平台分析和可视化的开源平台,使用Kibana能够搜索、展示存储在Elasticsearch中的索引数据。使用它可以很方便用图表、表格、地图展示和分析数据。
Kibana能够轻松处理大量数据,通过浏览器接口能够轻松的创建和分享仪表盘,通过改变Elasticsearch查询时间,可以完成动态仪表盘。

Kibana模块功能

discover

Discover标签页用于交互式探索数据,可以访问到匹配得上的索引模式的每个索引的每条记录
设置时间过滤器
时间过滤器限制搜索结果在一个特定的时间周期内。
搜索数据
在discover页提交一个搜索,可以搜索匹配当前索引模式的索引数据
保存搜索
可以在discover页保存已加载的搜索,也可以用作可视化的基础
自动刷新页面
可以配置一个刷新间隔自动刷新页面的最新索引数据
按字段过滤
可以过滤搜索结果,只显示在某字段中包含了特定值的文档,可以创建过滤器。

Visualize

visualize用来设计可视化,保存的可视化可以添加合并到dashboard里。

visualize类型

Area chart (面积图) 使用面积图来可视化各种不同类型的总作用
Data table (数据表) 使用数据表来展示组合聚集的原始数据。
Line chart (线图) 用来比较不同的类型
Markdown widget 用 Markdown 显示自定义格式的信息或和仪表盘有关的用法说明
Metric (计数) 统计数目
Pie (饼图) 用饼图显示每个数据源的总体占比
Tile map (地图) 用地图将聚合结果和经纬度结合
Vertical bar chart (垂直条状图) 用垂直条形图作为计数图形

Dashboard

一个 Kibana dashboard 能自由排列一组已保存的可视化。然后可以保存这个仪表板,用来分享或者重载。

Timelion

Timelion是一个时间序列数据的可视化,可以结合在一个单一的可视化完全独立的数据源。它是由一个简单的表达式语言驱动的,可以用来检索时间序列数据,进行计算,找出复杂的问题的答案,并可视化的结果。

APM

弹性应用程序性能监视(APM)自动从应用程序内部收集深入的性能指标和错误。
Kibana中的APM页面随X-Pack基本许可证一起提供。它使开发人员能够深入了解其应用程序的性能数据,并快速找到性能瓶颈。

Dev Tools

原先的交互式控制台Sense,使用户方便的通过浏览器直接与Elasticsearch进行交互。从Kibana 5开始改名并直接内建在Kibana,就是Dev Tools选项。

Monitoring

kibana中的X-Pack监控,可以实时查看Elasticsearch,Logstash和Beats的运行状况和性能数据。

Management

管理应用程序是执行Kibana的运行时配置的地方,包括索引模式的初始设置和持续配置,调整Kibana本身行为的高级设置,以及可以在整个Kibana中保存的各种“对象”,例如搜索,可视化和仪表板。

四、Beats

image.png

Filebeat是基于原先 logstash-forwarder 的源码改造出来的。换句话说:filebeat 就是新版的 logstash-forwarder,也会是 Elastic Stack 在 shipper 端的第一选择。
Metricbeat是一个轻量级的采集器,不但可以监控服务器的性能指标,还可以监控运行在服务区之上的应用信息(eg.Apache、MongoDB、MySQL、Ngnix、PostgreSQL、Redis、Zookeeper、System)。
Packetbeat 是一个实时网络数据包分析工具,与elasticsearch一体来提供应用程序的监控和分析系统。
winlogbeat 通过标准的 windows API 获取 windows 系统日志,常见的有 application,hardware,security 和 system 四类。
Auditbeat是一个轻量级的传输器,以审核系统上用户和进程的活动。例如检测关键文件(如二进制文件和配置文件)的更改,并识别潜在的安全策略违规。
Heartbeat是一个轻量级守护程序,可以安装在远程服务器上,定期检查服务状态并确定它们是否可用。

image.png

filebeat的收集日志配置,可以收集多个日志文件,配置多个type模块,enabled的值默认设置是false,需要改成true,paths指定日志文件的绝对路径,tags是为了后续logstash对其进行筛选。
filebeat的输出配置,因为这里输出到logstash了,需要把elasticsearch的配置注释,在logstash的模块添加logstash的IP以及端口

Elastic Stack的架构

image.png

数据收集的工作由filebeat完成,因为它是个轻量级的logstash,安装简单,占用资源少,不会占用jvm内存;数据的处理交由logstash;数据的存储和数据的检索是由elasticsearch完成的,最后数据的各种聚合和可视化的工作是kibana的。

理想的Elastic Stack架构
image.png

这里多了个kafka消息队列,kafka作为消息队列解耦了处理过程,同时提高了可扩展性。具有峰值处理能力,使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

Redis、Kafka和Rabbitmq的对比

  • Kafka是一种分布式的,基于发布/订阅的消息系统。它遵从一般的MQ结构,producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。Kafka开发语言为Scala,支持跨平台。

  • Kafka的优点:
    分布式高可扩展。Kafka 集群可以透明的扩展,增加新的服务器进集群;
    高性能。Kafka 的性能大大超过传统的ActiveMQ、RabbitMQ等MQ 实现,尤其是Kafka 还支持batch 操作;
    容错。Kafka每个Partition的数据都会复制到几台服务器上。当某个Broker故障失效时,ZooKeeper服务将通知生产者和消费者,生产者和消费者转而使用其它Broker。
    高吞吐量。kafka内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高。
    kafka的设计初衷是一个日志系统,其队列中的数据能够持久化一段时间。因此后来的consumer能够通过自定义offset来实现获取之前的消息,而redis就不具备这样的能力。

  • RabbitMQ是一个Advanced Message Queuing Protocol(AMQP)的开源实现,由以高性能、可伸缩性出名的Erlang写成。RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制。RabbitMQ Server适用的OS有:Windows、Linux/Unix和Mac OS X。

  • AMQP协议主要有3个组件:
    交换器(Exchange):它是发送消息的实体
    队列(Queue):它是接收消息的实体
    绑定器(Bind):将交换器和队列连接起来,并且封装消息的路由信息
    rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。

推荐阅读更多精彩内容