什么是ELK

ELK是三个开源软件的缩写,分别表示:

  1. Elasticsearch
  2. Logstash
  3. Kibana

Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作再一并发往elasticsearch上去。

Kibana也是一个开源和免费的工具,Kibana可以为Logstash和ElasticSearch提供的日志分析友好的Web界面,可以帮助汇总、分析和搜索重要数据日志。

新增了一个Beats系列组件,它是一个轻量级的日志收集处理工具(Agent),Beats占用资源少,适合于在各个服务器上搜集日志或信息后传输给Logstash。

为什么需要ELK

先来看一个应用场景,常见的WEB应用日志分析,一般我们会怎么做?登录到每台服务器上,直接在日志文件中grep、awk就可以获得自己想要的信息。但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。

这个时候我们希望集中化的日志管理,所有服务器上的日志收集汇总。常见解决思路是建立集中式日志收集系统,将所有节点上的日志统一收集,管理,访问。这样对于大型系统来说,都是一个分布式部署的架构,不同的服务模块部署
在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。

一个完整的集中式日志系统,需要包含以下几个主要特点:

  • 收集-能够采集多种来源的日志数据
  • 传输-能够稳定的把日志数据传输到中央系统
  • 存储-如何存储日志数据分析-可以支持
  • UI 分析警告-能够提供错误报告,监控机制

ELK就是这样一整套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用,而不仅仅是日志分析。

HelloWorld

打开:http://localhost:5601/,点击面板中的“Dev Tools”按钮,进入Dev工具,开始我们的Elasticsearch初次访问之旅。

创建索引

输入:
put test
输出:
{"acknowledged" : true,"shards_acknowledged" : true,"index" : "test"
}

查看索引

输入:
get test
输出:
{"test" : {"aliases" : { },"mappings" : { },"settings" : {"index" : {"routing" : {"allocation" : {"include" : {"_tier_preference" : "data_content"}}},"number_of_shards" : "1","provided_name" : "test","creation_date" : "1634041189082","number_of_replicas" : "1","uuid" : "Q6ja6kKDQ6-XUBQWcIzXxg","version" : {"created" : "7140199"}}}}
}

添加文档

输入:
put /test/_doc/1
{"msg": "hello elasticsearch"
}
输出:
{"_index" : "test","_type" : "_doc","_id" : "1","_version" : 2,"result" : "updated","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 1,"_primary_term" : 1
}

查看文档

输入:
get /test/_doc/1
输出:
{"_index" : "test","_type" : "_doc","_id" : "1","_version" : 2,"_seq_no" : 1,"_primary_term" : 1,"found" : true,"_source" : {"msg" : "hello elasticsearch"}
}

基本原理与概念

倒排索引

从上面的例子中,我们看到了很多熟悉又陌生的概念,比如索引、文档等等。这些概念和我们平时看到的数据库里的索引有什么区别呢?

举个例子,现在我们要保存唐宋诗词,数据库中我们们会怎么设计?诗词表我们可能的设计如下:

朝代 作者 标题 诗词全文
李白 静夜思 床前明月光,疑是地上霜。举头望明月,低头思故乡。
李清照 如梦令 常记溪亭日暮,沉醉不知归路,兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。
李白 蜀道难 蜀道之难难于上青天,侧身西望长咨嗟。
李隆基 春台望 暇景属三春,高台聊四望。

要根据朝代或者作者寻找诗,都很简单,比如“select 诗词全文 from 诗词表 where 作者=‘李白’”,如果数据很多,查询速度很慢,怎么办?我们可以在对应的查询字段上建立索引加速查询。

但是如果我们现在有个需求:要求找到包含“望”字的诗词怎么办?用“select 诗词全文 from 诗词表 where 诗词全文 like ‘%望%’”,这个意味着要扫描库中的诗词全文字段,逐条比对,找出所有包含关键词“望”字的记录。基本上,数据库中一般的 SQL优化手段都是用不上的。数量少,大概性能还能接受,如果数据量稍微大点,就完全无法接受了,更何况在互联网这种海量数据的情况下呢?

怎么解决这个问题呢,用倒排索引。

可以将上述诗词的中每个字都可以作为关键字,然后建立关键字和文档之间的对应关系,也就是标识关键字被哪些文档包含,于是我们可以这么保存:

序号 关键词 静夜思 如梦令 蜀道难 春台望
1
2

所以,倒排索引就是将文档中包含的关键字全部提取处理,然后再将关键字和文档之间的对应关系保存起来,最后再对关键字本身做索引排序。用户在检索某一个关键字是,先对关键字的索引进行查找,再通过关键字与文档的对应关系找到所在文档。

在存储在关系型数据库中的数据,需要我们事先分析将数据拆分为不同的字段,而在es这类的存储中,需要应用程序根据规则自动提取关键字,并形成对应关系。这些预先提取的关键字,在全文检索领域一般被称为term(词项),文档的词项提取在es中被称为文档分析,这是全文检索很核心的过程,必须要区分哪些是词项,哪些不是,比如很多场景下,apple和apples是同一个东西,望和看其实是同一个动作。

Elasticsearch基本概念

Elasticsearch中比较关键的基本概念有索引、文档、映射、映射类型、文档字段概念,为了方便理解,可以和关系数据库中的相关概念进行个比对:

关系数据库 ES
索引(Index)
映射类型(Mapping Type)
数据行 文档(Document)
字段 文档字段(Field)
表结构 映射(Mapping)

Elasticsearch索引

索引是映射类型的容器,一个Elasticsearch索引非常像关系型世界的数据库,是独立的大量文档集合。

当然在底层,肯定用到了倒排索引,最基本的结构就是“keyword”和“Posting List”,Posting list就是一个int的数组,存储了所有符合某个term的文档 id。

另外,这个倒排索引相比特定词项出现过的文档列表,会包含更多其它信息。它会保存每一个词项出现过的文档总数, 在对应的文档中一个具体词项出现的总次数,词项在文档中的位置(便于高亮显示),每个文档的长度,所有文档的平均长度等等相关信息。

文档 (Document)

文档是ES中所有可搜索数据的最小单位,比如日志文件中的日志项、一部电影的具体信息等等。

文档会被序列化JSON格式保存到ElasticSearch中,JSON对象由字段组成,每个字段都有对象的字段类型(字符串,数值,布尔,日期,二进制,范围类型)。同时每个文档都有一个Unique ID,可以自己指定ID,或者通过ElasticSearch自
动生成。

所以严格来说,es中存储的文档是一种半结构化的数据。

映射

映射(mapping)定义了每个字段的类型、字段所使用的分词器等。

可以显式映射,由我们在索引映射中进行预先定义;也可以动态映射,在添加文档的时候,由 es 自动添加到索引,这个过程不需要事先在索引进行字段数据类型匹配等等,es会自己推断数据类型。

文档字段

文档中的一个字段field就相当于关系型数据库中的一列column,那么它肯定有数据类型,es提供的数据类型有:

字符串类型:string,字符串类还可被分为text和keyword类型,如果我们让es自动映射数据,那么es会把字符串定义为 text,并且还加了一个keyword类型字段。

  • text:文本数据类型,用于索引全文值的字段。使用文本数据类型的字段,它们会被分词,在索引之前将字符串转换为单个术语的列表(倒排索引),分词过程允许ES搜索每个全文字段中的单个单词。什么情况适合使用text,只要不具备唯一性的字符串一般都可以使用text。
  • keyword:关键字数据类型,用于索引结构化内容的字段。使用keyword类型的字段,其不会被分析,给什么值就原封不动地按照这个值索引,所以关键字字段只能按其确切值进行搜索。什么情况下使用keyword,具有唯一性的字符串,例如:电子邮件地址、MAC 地址、身份证号、状态代码…等等。

数字型数据类型:long、integer、short、byte、double、float

日期类型:date

布尔类型:boolean

复杂数据类型

  • 数组:无需专门的数据类型
  • 对象数据类型:单独的 JSON 对象
  • 嵌套数据类型:nested,关于JSON对象的数组

地理数据类型:

  • 地理点数据类型
  • 地理形状数据类型

专门数据类型:

  • IPv4数据类型
  • 单词计数数据类型token_count

各种数据类型的使用

创建一个新的索引:

输入:
put base-test
输出:
{"acknowledged" : true,"shards_acknowledged" : true,"index" : "base-test"
}

显式映射,指定文档中各个字段的数据类型:

输入:
put /base-test/_mapping
{"properties": {"crop": {"type": "text"},"name": {"type": "text"},"lang": {"type": "text"}}
}
输出:
{"acknowledged" : true
}

假如我们在插入一个文档时,多了个star字段,会怎么样?

输入:
put /base-test/_doc/1
{"crop": "Apache","name": "ES","lang": "JAVA","star": 200
}
输出:
{"_index" : "base-test","_type" : "_doc","_id" : "1","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1
}

查询文档,可以发现star字段已经保存成功:

输入:
get /base-test/_doc/1
输出:
{"_index" : "base-test","_type" : "_doc","_id" : "1","_version" : 1,"_seq_no" : 0,"_primary_term" : 1,"found" : true,"_source" : {"crop" : "Apache","name" : "ES","lang" : "JAVA","star" : 200}
}

查询索引的映射,可以看到es自动帮我们新增了star这个字段:

输入:
get /base-test/_mapping
输出:
{"base-test" : {"mappings" : {"properties" : {"crop" : {"type" : "text"},"lang" : {"type" : "text"},"name" : {"type" : "text"},"star" : {"type" : "long"}}}}
}

修改映射,增加一个新的字段year:

输入:
put /base-test/_mapping
{"properties": {"year": {"type": "integer"}}
}
输出:
{"acknowledged" : true
}
输入:
get /base-test/_mapping
输出:
{"base-test" : {"mappings" : {"properties" : {"crop" : {"type" : "text"},"lang" : {"type" : "text"},"name" : {"type" : "text"},"star" : {"type" : "long"},"year" : {"type" : "integer"}}}}
}

数组

不需要特殊配置,一个字段如果被配置为基本数据类型,就是天生支持数组类型的。任何字段都可以有0个或多个值,但是在一个数组中数据类型必须一样。
比如:

输入:
put /base-test/_doc/2
{"name": ["Apache Activemq","Activemq Artemis"],"lang": "Java","corp": "Apache","stars": [500,200]
}
输出:
{"_index" : "base-test","_type" : "_doc","_id" : "2","_version" : 1,"result" : "created","_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 1,"_primary_term" : 1
}

是没问题的,但是如果:

输入:
put /base-test/_doc/3
{"name": ["Apache Kafka"],"lang": "Java","corp": "Apache","stars": [500,"java"]
}
输出:
{"error" : {"root_cause" : [{"type" : "mapper_parsing_exception","reason" : "failed to parse field [stars] of type [long] in document with id '3'. Preview of field's value: 'java'"}],"type" : "mapper_parsing_exception","reason" : "failed to parse field [stars] of type [long] in document with id '3'. Preview of field's value: 'java'","caused_by" : {"type" : "illegal_argument_exception","reason" : "For input string: \"java\""}},"status" : 400
}

对象

JSON文档是有层次结构的,一个文档可能包含其他文档,如果一个文档包含其他文档,那么该文档值是对象类型,其数据类型是对象。当然ElasticSearch中是没有所谓对象类型的,比如:

输入:put /base-test/_doc/4{  "name": [    "Apache ShardingSphere"  ],  "lang": "Java",  "corp": "JingDong",  "stars": 400,  "address": {    "city": "BeiJing",    "country": "亦庄"  }}输出:{  "_index" : "base-test",  "_type" : "_doc",  "_id" : "4",  "_version" : 1,  "result" : "created",  "_shards" : {    "total" : 2,    "successful" : 1,    "failed" : 0  },  "_seq_no" : 2,  "_primary_term" : 1}

对象类型可以在定义索引的映射关系时进行指定。

多数据类型

如果说数组允许你使用同一个设置索引多项数据,那么多数据类型允许使用不同的设置,对同一项数据索引多次。带来的好处就是可以同一文本有多种不同的索引方式,比如一个字符串类型的字段,可以使用text类型做全文检索,使用keyword 类型做聚合和排序。我们可以看到es的动态映射生成的字段类型里,往往字符串类型都使用了多数据类型。当然,我们一样也可以自己定义:

输入:
put /base-test/_mapping
{"properties": {"name": {"type": "text","fields": {"raw": {"type": "keyword"},"length": {"type": "token_count","analyzer": "standard"}}}}
}
输出:
{"acknowledged" : true
}

在上面的代码里,我们使用"fields"就把name字段扩充为多字段类型,为name新增了两个子字段raw和length,raw设置类型为keyword,length设置类型为token_count,告诉es这个字段在保存还需要做词频统计。

通过fields字段设置的子字段raw和length,在我们添加文档时,并不需要单独设置值,他们name共享相同的值,只是es 会以不同的方式处理字段值。同样在检索文档的时候,它们也不会显示在结果中,所以它们一般都是在检索中以查询条件的形式出现,以减少检索时的性能开销。

ELK入门与基本概念相关推荐

  1. Flink 基本原理与生产实践分享【入门必读,概念清晰】

    Flink 基本原理与生产实践分享[入门必读,概念清晰] https://zh.wikipedia.org/zh-hans/Apache_Flink Apache Flink是由Apache软件基金会 ...

  2. elk入门_ELK堆栈入门

    elk入门 朋友不允许朋友写用户身份验证. 厌倦了管理自己的用户? 立即尝试Okta的API和Java SDK. 数分钟之内即可在任何应用程序中对用户进行身份验证,管理和保护. 好的设计原则要求微服务 ...

  3. 日志服务器搭建及配置_[ELK入门到实践笔记] 一、通过rsyslog搭建集中日志服务器...

    ELK 是elastic公司提供的一套完整的日志收集以及展示的解决方案,这是我在ELK学习和实践过程写下的笔记,整理成了一个ELK入门到实践的系列文章,分享出来与大家共勉.本文为该系列文章的第一篇,通 ...

  4. JavaScript入门几个概念

    JavaScript入门几个概念 刚刚入门JavaScript的时候,搞懂DOM.BOM以及它们的对象document和window很有必要. DOM是为了操作文档出现的API,document是它的 ...

  5. mysql自动提交的概念_MySQL入门之事务概念

    MYSQL默认是自动提交的,也就是你提交一个QUERY,它就直接执行!我们可以通过 set autocommit=0 禁止自动提交 set autocommit=1开启自动提交 mysql中INNOD ...

  6. ELK入门(Elastic Stack)

    ELK入门(Elastic Stack) ELK入门(Elastic Stack) 开始之前 安装Elasticsearch 确保Elasticsearch启动和运行编辑 安装Kibana 启动Kib ...

  7. Kafka教程(一)基础入门:基本概念、安装部署、运维监控、命令行使用

    Kafka教程(一)基础入门 1.基本概念 背景 领英->Apache 分布式.消息发布订阅系统 角色 存储系统 消息系统 流处理平台-Kafka Streaming 特点 高吞吐.低延迟 cg ...

  8. 语音处理:音频入门之基础概念总结

    语音处理:音频入门之基础概念总结 基本概念 语音增强 基本概念 过采样:超过音频本身实际带宽的采样率,如音频带宽12kHz,用96kHz采样属于过采样,用24kHz采样则较为合理.上采样,也属于过采样 ...

  9. ELK入门——ELK详细介绍(ELK概念和特点、Elasticsearch/Logstash/beats/kibana安装及使用介绍、插件介绍)

    目录 主要参考链接 一.什么是ELK(端口9200) 主要特点: 1.存储:面向文档+JSON 2.检索:倒排+乐观锁 3.分析:监控+预警+可视化 4.支持集群 二.Logstash(端口5044) ...

最新文章

  1. 【FFmpeg】便捷函数汇总(持续更新中...)
  2. 【pytorch】nn.conv1d的使用
  3. class函数 python_python函数之classmethod()
  4. matlab碎纸拼接相似函数,基于蒙特卡洛算法构建能量函数的碎纸图片拼接方法
  5. 如何成为公司独当一面的工程师
  6. Oracle自定义函数(不断更新)
  7. 转:2016年崛起的js项目
  8. net 中viewstate的原理和使用
  9. Stata+R:一文读懂中介效应
  10. 修改echarts 3D柱状图柱子大小(粗细)的方法
  11. ssh 远程连接详解--(linux运维09)
  12. BeagleboneBlack上u-boot的MLO文件是哪里来的
  13. 评分卡Bad rate单调性问题
  14. 浅谈javascript面向对象理解
  15. Android连接WiFi再探索
  16. 0 嵌入式-ARM简介
  17. BC26电信云平台LWM2M接入指南
  18. 学人工智能需要什么配置的电脑?AI电脑配置需求
  19. Hugo 博客搭建教程
  20. deployment的yaml说明

热门文章

  1. 山洪径流过程模拟及洪水危险性评价
  2. 线缆直径载流量估算及其他
  3. 第六周周工作总结及计划表
  4. 关于区块链的助记词以及BTC地址,私钥,公钥,ETH地址获取的方法
  5. 感谢C语言吧吧友奉上的C语言小程序练习---初学者练手
  6. 解决Surface Pro 系列 TF卡掉卡问题
  7. go linux 开发工具,golang的基础语法和常用开发工具详解
  8. linux上安装两个anaconda,在Linux上安装Anaconda2时出现问题
  9. 服务器cpu虚拟化vt,聚焦五大虚拟化技术:CPU虚拟化居首
  10. LOOP GROUP BY 分组循环的使用方法小栗子