欢迎您光临本站,如有问题请及时联系我们。

民生银行:我们的 ELK 日志分析平台

  随着计算机技术的不断发展,现实生活中需要处理的数据量越来越大,越来越复杂,对实时性的要求也越来越高。为了适应这种发展,产生了很多大数据计算框架,例如:hadoop、spark等。

  尤其在运维监控领域,不同的计算机系统不断产生大量的指标数据,对于这些数据需要及时收集,实时分析,发现异常,为运维部门高效运维提供帮助。同时由于数据种类繁多、用于统计的维度也非常多样,这要求使用的统计工具要非常灵活,学习门槛要低,实施周期要短。

  ELK stack为我们提供了这样一种选择,使每个人都能够容易掌握,使需要专业技能才能开发的监控、运维系统不再遥不可及。大家都可以参与到运维监控系统的建设中,更好地监控、运维相关系统,真正实现高效、可视化运维。

  1.工作中的现实问题

  需要对系统运行的各种指标实时进行监控,及时发现各种异常

  需要对各类指标进行多维度分析展现(图、表)

  需要对各种数据进行长期有效存储用于后期分析(容量、性能、对比等)

  需要处理多种数据(结构化、非结构化)

  需要对日志文本数据进行全文检索(精确搜索、相似搜索)

  需要对大量数据进行处理,通常达到TB或PB级别

  需要根据各个系统不同特点满足各种个性化的需求

  需要比较低的开发成本,学习门槛。每个人都可以按照自己的需求进行开发,无需专业人员协助。开发周期短。

  需要有一定的机器学习功能,能够从大量的数据中发现规律,对于不符合规律的现象进行提示,从而实现提前预警。从一定程度上避免被动处理问题。

  推广开来,相似的方法同样适用于对任意有价值数据的分析。实时总结发现海量数据处理中的内在规律,为作出正确的决策提供依据。

  2. ELKstack解决方案

  2.1 介绍ELK Stack是Elastic的三个开源产品 – Elasticsearch,Logstash和Kibana的集合。 Elasticsearch是基于Lucene搜索引擎的NoSQL数据库。

  Logstash是一个日志管道工具,可接受来自各种来源的输入,执行不同的转换,进行一些数据预处理的工作,并将数据导出到各种目标。 Kibana是一个在Elasticsearch之上工作的可视化层。

  这三种不同的开放源代码产品最常用于IT环境中的日志分析(尽管ELK Stack有更多的用例,包括商业智能,安全性和合规性以及Web分析)。 Logstash收集和解析日志,然后Elasticsearch索引并存储信息。然后,Kibana在可视化中呈现数据,从而为自己的环境提供可行的思路。

  总而言之,Logstash负责数据收集、传输、预处理。Elasticsearch负责数据存储、分析。Kibana负责数据展现。这三者的有机结合为大数据实时、可视化处理提供了完整的解决方案。

 ELKstack

  2.2 特点检索性能高效。实时快速

  集群线性扩展。海量数据

  数据安全保障。安全可靠

  处理方式灵活。多种接口

  配置简易上手。敏捷开发

  对比

  VS Apache Hadoop,Spark

  Apache Hadoop,Spark和ElasticSearch在一些用法中确实有一些重叠。也就是说,基本上是每个框架都想要提供大数据的一瞥,结果是各种技术都模糊不清,也变得混乱。

  Hadoop / Spark可以在HDFS中存储JSON文件进行分析和处理,ElasticSearch还可以存储JSON文件进行搜索和多面搜索。每个工具仍然有一个适合他们的地方。

  Elasticsearch已经开始扩展超出搜索引擎,并添加了一些分析和可视化功能,但仍然是其核心,它仍然主要是全文搜索引擎,并且作为查询的一部分,为复杂的计算和聚合提供了较少的支持。虽然统计方面提供了一些能够检索计算的统计信息,但仅限于给定查询的范围。

  如果我们正在寻找一组文档并使用facet应用一些统计信息,那么Elasticsearch是更好的方法。 Elasticsearch在Web分析领域越来越受欢迎,其开源的Logstash用于服务器端日志采集和开源可视化工具Kibana。

  Apache Hadoop是灵活和强大的环境,Spark也源于Hadoop。例如,通过HDFS的Hadoop存储抽象,任何任意任务可以使用MapReduce API,Hive,HBase,Pig,Sizzle,Mahout,RHadoop等对数据进行运行。

  Elasticsearch提供了越来越多的聚合分析工具(Bucketing,Metric,Matrix,Pipeline),不需要通过专业的代码开发就可以实现对于大量数据的近实时分析。

  VS传统关系型数据库

  关系型数据库被明确设计—毫不意外—用来进行关联关系管理:

  每个实体(或行,在关系世界中)可以被主键唯一标识。

  实体规范化(范式)。唯一实体的数据只存储一次,而相关实体只存储它的主键。只能在一个具体位置修改这个实体的数据。

  实体可以进行关联查询,可以跨实体搜索。

  单个实体的变化是原子的,一致的,隔离的,和持久的。(可以在 ACID Transactions 中查看更多细节。)

  大多数关系数据库支持跨多个实体的 ACID 事务。

  但是关系型数据库有其局限性,包括对全文检索有限的支持能力。实体关联查询时间消耗是很昂贵的,关联的越多,消耗就越昂贵。特别是跨服务器进行实体关联时成本极其昂贵,基本不可用。但单个的服务器上又存在数据量的限制。

  Elasticsearch ,和大多数 NoSQL 数据库类似,是扁平化的。索引是独立文档的集合体。文档是否匹配搜索请求取决于它是否包含所有的所需信息。

  Elasticsearch 中单个文档的数据变更是 ACID 的,而涉及多个文档的事务则不是。当一个事务部分失败时,无法回滚索引数据到前一个状态。

  扁平化有以下优势:

  索引过程是快速和无锁的。

  搜索过程是快速和无锁的。

  因为每个文档相互都是独立的,大规模数据可以在多个节点上进行分布。

  但关联关系仍然非常重要。某些时候,我们需要缩小扁平化和现实世界关系模型的差异。通常都需要结合其中的某几个方法来得到最终的解决方案:全文检索;对海量数据的实时处理;线性扩展;高容错性。

  2.3 LogstashELK Stack的一个很好的用途是日志和其他时间序列数据的存储,可视化和分析。 Logstash是从源到Elasticsearch的数据工作流程的组成部分。它不仅允许您从各种来源中提取数据,还可以是为您提供过滤,预处理和规范化数据的工具,使其更易于使用。

  Logstash在安装完成好以后,主要工作就是编写配置文件。

  配置文件分为三个部分:input,filter,output。在每个部分都包含丰富的plugin可以满足不同的功能需要。

  input 定义输入,file为输入的文件,可以有多个。除file外,还有stdin、TCP、 syslog、collectd等。

  filter 过滤配置,可以将日志整理成自己想要的格式,在这个部分实现对于数据的预处理。logstash有丰富的过滤插件,date处理、grok正则捕获、mutate、GeoIP、JSON编码、key-value切分,对于复杂的操作可以借助ruby的强大处理等等。

  grok是logstash最重要的插件,在grok中定义好正在表达式,可以在其他地方引用它。语法这里不过多介绍,需要可以自己从网上学习。

  例如:

 Logstash

  对于grok的使用可以使用下来资源:

  https://raw.githubusercontent.com/logstash-plugins/logstash-patterns-core/master/patterns/grok-patterns

  https://github.com/logstash-plugins/logstash-patterns-core/blob/master/patterns/grok-patterns

  http://grokdebug.herokuapp.com/

  kibana 5自带grok debugger

  output 定义输出目的地。logstash的输出也有多种,标准输出,输出到elasticsearch,redis,kafka等等,可以同时指定多个输出,stdout方便调试,查看实时的日志。输出到es说明:hosts 为es的ip和端口;index为索引名称,按日期分方便管理。

  存在的问题:底层使用ruby实现,占用JVM较大,系统资源消耗较大,性能方面不是很好,调试、跟踪困难,异常处理困难等。

  为了解决上述问题ELKstack新版本(5.0以上)开发了大量专业的beat,以大量轻量级的beat部署在数据源端,只负责数据的ship,大量后续的数据解析、分析、预处理等工作放到统一的后端来处理。

  如果在不需要logstash完全、复杂处理功能的情况下,可以使用ingest node的processor来进行相关数据预处理,这种组合将极大地提高数据处理的效率,降低了对前端系统的影响。(在某些场景下ingest node的处理能力是logstash的十倍以上)

  Ingest node与logstash的对比:

  https://sematext.com/blog/2016/04/25/elasticsearch-ingest-node-vs-logstash-performance/

  2.4 ElasticSearchElasticsearch是一个NoSQL数据库。这意味着它以非结构化的方式存储数据,并且不能使用SQL来查询数据(为适应大量传统数据库用户,后续版本也会提供SQL解析层)。

  与大多数NoSQL数据库不同,Elasticsearch非常重视搜索功能 – 实际上,从Elasticsearch获取数据的最简单方法是使用REST API(Representational state transfer)进行搜索。

  Elasticsearch是整个ELK stack的核心,所有其他功能组件都是围绕着它来工作的。它对数据处理提供了丰富的接口API,可以轻松的实现对数据的CRUD(Create, Read, Update, and Delete)操作。

  对数据搜索提供了两大类搜索功能:精确搜索和全文检索(根据相似度、匹配度),在搜索功能中包含强大的数据分析、聚合功能。通过特有的数据查询语言DSL(Domain SpecificLanguage)可以满足各种查询需要。

  2.5 KibanaKibana是ELK Stack的可视化层,它是最流行的日志分析平台,建立在Elasticsearch,Logstash之上。

  Kibana是一个开源分析和可视化平台,旨在与Elasticsearch合作。它将您的处理请求转化为具体的DSL语句(降低对于DSL语言的使用门槛),发送给ES服务器获取查询结果,然后将查询结果以可视化的方式展现给你。通过这种方式您可以轻松地执行高级数据分析,并可在各种图表,表格和地图中直观地显示数据。

  Kibana可以轻松解析大量数据。其简单的基于浏览器的界面使您能够快速创建和共享动态仪表板,实时显示对于ES查询的变化。

  安装好Kibana后,您可以在几分钟内开始探索您的Elasticsearch索引 – 无代码,无需额外的基础架构。

  2.5.1 基本概念1、Discover

  在进行任何数据探索之前,需要首先了解你的数据:组成、类型、范围、数据分布等。所有这些操作你可以在discover页面上交互式地完成。

  你可以提交任何查询、过滤条件,你可以观察数据是如何匹配你所提供的条件的。 对于已经满足您要求的查询,你可以保存下来供下次使用,或供visualize使用。

  2、Visualize

  这是对基于ES所存储的数据,按照你所提供的查询条件和分析方法,用图形的方式对结果进行展现。

  通过各种直方图、折线图、饼图等图形能够直观地显示数据的变化趋势、组成占比、不同数据的对比等信息。

  3、Dashboard

  将已经生成好的单个visualization有机地组合成一个个看板,便于使用者更直观、快速地发现各个图表间的差异,快捷地根据信息作出正确判断。在这里还可以根据需要临时输入各种条件对各图表所展示的内容进行调整,以突出某个数据。

  2.5.2 基本操作Discover

  Visualize

  Dashboard

  2.5.3 Timelion对于时间序列数据的分析举例举例1:展示不同时段的CPU使用率数据对比

CPU

  过程如下:

  —显示用户cpu的平均使用率

  .es(index=metricbeat-*, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’)

  —同时显示一个小时之前的对比数据

  .es(index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’), .es(offset=-1h,index=metricbeat-,

  timefield=’@timestamp’, metric=’avg:system.cpu.user.pct’)

  —对不同的数据进行区别标识

  .es(offset=-1h,index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘last hour’),

  .es(index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘current hour’)

  —增加标题

  —改变系列类型

  —改变一系列的颜色和不透明度

  —修改图例

  —增加标题

  .es(offset=-1h,index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘last hour’),

  .es(index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘current hour’).title(‘CPU

  usage over time’)

  —设置填充和宽度

  .es(offset=-1h,index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘last

  hour’).lines(fill=1,width=0.5), .es(index=metricbeat-,

  timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘current hour’).title(‘CPU

  usage over time’)

  —设置不同的颜色

  .es(offset=-1h,index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘last

  hour’).lines(fill=1,width=0.5).color(gray), .es(index=metricbeat-,

  timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘current hour’).title(‘CPU

  usage over time’).color(#1E90FF)

  —设置图标显示的列数和位置

  .es(offset=-1h,index=metricbeat-, timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘last

  hour’).lines(fill=1,width=0.5).color(gray), .es(index=metricbeat-,

  timefield=’@timestamp’,

  metric=’avg:system.cpu.user.pct’).label(‘current hour’).title(‘CPU

  usage over time’).color(#1E90FF).legend(columns=2, position=nw)

  展示效果:

  举例2:展示网络流量变化

  过程如下:

  —网络流量增长量

  .es(index=metricbeat*, timefield=@timestamp,

  metric=max:system.network.in.bytes)

  —关注网络流量的变化量会更有价值,derivative

  es(index=metricbeat*, timefield=@timestamp,

  metric=max:system.network.in.bytes).derivative()

  —同时显示网络流入和流出量,通过算术运算获得,multiply()

  .es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.in.bytes).derivative(),

  .es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.out.bytes).derivative().multiply(-1)

  —为了更好地阅读,将字节转换为MB,divide

  es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.in.bytes).derivative().divide(1048576),

  .es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.out.bytes).derivative().multiply(-1).divide(1048576)

  —根据前面所学加上标题、填充、颜色、图标等信息

  .es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.in.bytes).derivative().divide(1048576).lines(fill=2,

  width=1).color(green).label(“Inbound traffic”).title(“Network traffic

  (MB/s)”), .es(index=metricbeat, timefield=@timestamp,

  metric=max:system.network.out.bytes).derivative().multiply(-1).divide(1048576).lines(fill=2,

  width=1).color(blue).label(“Outbound traffic”).legend(columns=2,

  position=nw)


来源:本文由E8运维原创撰写,欢迎分享本文,转载请保留出处和链接!