为什么需要ELK:
一般大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。
简介:
ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。
Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,近实时(1s)文件存储、检索、分析,零配置,集群自动发现,自动分片索引,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。
Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。
Elastic Search
数据大致可以分为结构化数据和非结构化数据,结构化数据由于相互间具有一定的联系和固定的结构,对其进行查找时容易利用其结构编写算法加速其搜索速度。但是对于非结构化数据,只能采取顺序扫描的方法进行搜索,这种搜索方式耗时太久。因此自然的想到将非结构化的数据转换为结构化的数据,即将抽象的联系具体化,称之为索引。
Elastic Search采取Lucene全文搜索引擎架构,将数据通过Tokenize分词器划分为不同的字符串并过滤掉出现频率较高的停词(stop word),例如is a an等等。这些字符串将会以一定的形式重新组织起来,以字符串、频率、文档链表的结构建立起字符串到文档数据的映射,称之为反向索引。这里的文档链表称之为倒排表。
(英文中存在同一词的多种形式,在分词器处理的过程中可以分为三大步骤,分别是:1)去除标点符号与停词 2)将不同的词元去除其形式归为一般形式的词 3) 将词与索引组件结合,形成词字典 4)按词的字母进行排序,合并相同的词,形成文档倒排链表)
某单词的倒排索引项主要包含如下信息:
1.文档id用于获取原始信息
2.单词频率(TF,Term Frequency),记录该单词在该文档中出现的次数,用于后续相关性算分
3.位置(Posting),记录单词在文档中的分词位置(多个),用于做词语搜索(Phrase Query)
4.偏移(Offset),记录单词在文档的开始和结束位置,用于高亮显示
基本概念
索引(Index)
ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。
类型(Type)
类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。
文档(Document)
文档是索引和搜索的原子单位,它是包含了一个或多个域(Field)的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。
Elastic Search 是分布式搜索引擎系统,实现了近乎实时的数据存储、检索、分析功能。运作过程可以分为三部分:1.数据的录入与更新(索引的建立与更新) 2. 数据的查找与分析 3.集群的增减容
一、数据的录入与更新
(1)分片存储与副本机制
首先,ES是一个分布式的系统,一个索引在被创建时需要定义切片数目,不同分片(segment)存储在不同的datanode中,而每一个datanode都是一个完整的lucene搜索引擎。一堆文件将会通过负载均衡算法被相对均匀的分布到不同的分片中。数据会在分片中自动产生索引,也就是自动分片索引。ES默认一个索引有5个主分片,在创建索引时完成创建且不可更改,而副本分片的数量会随时变化。集群数量健康的状态下时,主分片必须与副本分片存储在不同的datanode上,降低数据丢失的风险。
(2)存储过程:
任意节点接收到了客户端请求,成为协调结点,根据hash算法得到路由值再对分片数取模,得到数据应该存储的分片位置,然后将请求转发到该主分片,主分片获得请求后写入数据,并且同步更新数据到副本分片。
这里需要注意的时,上面完成的操作并未落实到磁盘上。ES每一秒完成一次刷新操作,这个时间内录入的数据会被写入到文件缓存区中,而操作将会被记录到transactionLog文件中。这时新写入的数据可以被搜索到,但是未写入到磁盘。transactionLog文件每5秒将被写入到磁盘中一次,同时每30分种或者transactionLog文件过大的时候,文件缓冲区中的文件将被写入到磁盘。
二、数据的查找
1.任意节点接收到了客户端请求,成为协调结点。
2.协调结点将请求转发给所有的分片(节点)(包括p和r)
3.每个分片都进行搜索,并向协调结点返回自己的搜索结果(文档ID)
4.协调结点对返回的结果进行合并排序分页等操作
5.协调结点根据索引从分片中拉取真正的数据,最终返回给客户端
完成倒排索引得文档ID,再由正排索引由文档ID取得完整文档数据
三、集群的增减容(主节点丢失、协调结点) 待补充
(1)节点
主节点:处理与集群操作相关的内容,如创建或删除索引,跟踪集群节点状态,决定分片在结点上的分布。一般与数据结点分离。
数据节点:存储索引数据的节点,一个完整的lucene引擎,主要对文档进行增删该查操作
协调节点:只处理路由请求,处理搜索,广播索引等操作。
LogStash
LogStash主要用于从非结构化数据中提取关键数据并结构化,其工作步骤可以分为,读入=>解码=>过滤分析=>再编码=>输出。因此Logstash与之相对应的拥有三个模块:input、filter、output,每个模块又有众多可拔插的组件支持,每个模块可以同时支持多个插件。由此实现了功能的多样和复杂性。
elastic.co 官网提供了众多插件的API
一、数据的输入
1)**从文件读入**
file{
path=>"/root/logstash/mylog"
start_position=>"beginning"
sincedb_path=>"/dev/null"
codec=”json”
}
2)**从Sql数据库**
jdbc {
type => "logs_20171206"
jdbc_connection_string => "jdbc:mysql://192.168.9.80:3306/kgc_behivour_log"
jdbc_user => "root"
jdbc_password => "123456"
jdbc_driver_library => "/root/workspace/downloads/jdbc_mysql_5.1.44-dependencies.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_paging_enabled => "true"
jdbc_page_size => "1000"
statement => "select * from logs_20171206"
schedule => "* * * * *"
}
二、数据过滤分析
grok {
patterns_dir => ["./patterns"]
match => {
"message" => "%{USERUID}"
}
}
grok {
patterns_dir => ["./patterns"]
match => {
"message" => "%{EQUIPMENT}"
}
}
grok {
match => {
"message" => "%{TIMESTAMP_ISO8601:time} %{DATA:request} %{WORD:method} %{NUMBER:status} %{IP:uip} (?:-|%{IP:sip}) (?:-|%{URI:prepend}) (?:-|(?[^ ]+))"
}
}
三、数据的输出
1)elasticsearch
elasticsearch {
hosts => ["192.168.9.80:9200"]
index => "behivour-logs"
document_type => "logs_20171206"
document_id => "%{id}"
}
2)Stdout
stdout{
codec=”rubydebug”
}
Kibana
创建index pattern
Management>Index Patterns>Create Index Pattern
数据可视化Visualize