目录
1、ELK日志协议栈
2、ELK日志协议栈整体架构
3、Elasticsearch
3.1、Elasticsearch核心概念
3.2、管理索引
3.2.1、PUT命令(创建、插入和更新)
3.2.2、GET命令
3.2.3、DELETE命令
3.3、查询条件查询
3.3.1、使用match_all做查询
3.3.2、通过关键字段进行查询
3.3.3、bool的复合查询
3.3.4、bool的复合查询中的should
3.3.5、term匹配
3.3.6、使用terms匹配多个值
3.3.7、Range过滤
3.3.8、exists和 missing过滤
3.3.9、bool的多条件过滤
3.3.10、查询与过滤条件合并
3.4、定义字段类型mappings
3.4.1、使用mappings来提前定义字段类型
3.5、分页解决方案
3.5.1、size+from浅分页
3.5.2、scroll深分页
3.5.3、浅分页与深分页的对比
3.6、ES的中文分词器IK
ELK是三个软件产品的首字母缩写,Elasticsearch,Logstash 和 Kibana。
Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(如,搜索)。
Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。
Elasticsearch是面向文档(document oriented)的,它可以存储整个对象或文档(document)。并可以对文档(而非成行成列的数据)进行索引、搜索、排序、过滤。
(1)索引 index
索引:相似特征的文档的集合。
一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。
(2)类型 type
类型:索引的一个逻辑上的分类/分区。通常,会为具有一组共同字段的文档定义一个类型。
(3)字段Field
相当于是数据表的字段,对文档数据根据不同属性进行的分类标识。
(4)映射 mapping
mapping是对处理数据的方式和规则方面做一些限制;
其他如处理es数据的使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。
(5)文档 document
文档是一个可被索引的基础信息单元。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。
(6)接近实时 NRT
Elasticsearch是一个接近实时的搜索平台。从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒以内)。
(7)集群 cluster
集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由一个唯一的名字标识,这个名字默认就是“elasticsearch”。
(8)节点 node
节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果启动了若干个节点,且它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。
(9)分片和复制 shards&replicas
一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。故引入分片的概念来解决这一问题。
分片:将索引划分成多份的能力,这些份就叫做分片。每个分片本身也是一个功能完善并且独立的“索引”,它可以被放置到集群中的任何节点上。
分片的重要性:
复制:在网络/云的环境里,失败随时都可能发生,在某个分片/节点处于离线状态时,或者消失了,这种情况下,故障转移机制是非常有用。因此,Elasticsearch允许创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制的重要性:
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制。
curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求。
curl
(1)创建索引
在kibana的dev tools当中执行以下语句:curl -XPUT http://node01:9200/blog01/?pretty
(2)插入文档
使用 PUT 动词将一个文档添加到 /article(文档类型),并为该文档分配 ID 为1。URL 路径显示为index/doctype/ID(索引/文档类型/ID)。
curl -XPUT http://node01:9200/blog01/article/1?pretty -d '{"id": "1", "title": "What is lucene"}'
(3)更新文档
curl -XPUT http://node01:9200/blog01/article/1?pretty -d '{"id": "1", "title": " What is elasticsearch"}'
(1)查询文档
curl -XGET http://node01:9200/blog01/article/1?pretty
(2)搜索文档
curl -XGET "http://node01:9200/blog01/article/_search?q=title:elasticsearch"
(1)删除文档
curl -XDELETE "http://node01:9200/blog01/article/1?pretty"
(2)删除索引
curl -XDELETE http://node01:9200/blog01?pretty
GET /school/student/_search?pretty
{
"query": {
"match_all": {}
}
}通过match_all匹配后,会把所有的数据检索出来。对于es集群来说,直接检索全部的数据,很容易造成GC现象。
GET /school/student/_search?pretty
{
"query": {
"match": {"about": "travel"
"sex":"girl"}
}
}注意:一个match下,不能出现多个字段值。如上文中match花括号里还有字段如:"sex":"girl",则会报[match] query doesn't support multiple fields的错误,必须使用bool复合查询。
当出现多个查询语句组合的时候,可以用bool来包含。bool合并聚包含:must,must_not或者should, should表示or的意思.
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": { "match": {"about": "travel"}},
"must_not": {"match": {"sex": "boy"}}
}
}
}
should表示可有可无的(如果should匹配到了就展示,否则就不展示)。
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": { "match": {"about": "travel"}},
"should": {"match": {"sex": "boy"}}
}
}
}
使用term进行精确匹配(比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型))。
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": { "term": {"about": "travel"}},
"should": {"term": {"sex": "boy"}}
}}
}
term主要是用于精确的过滤比如说:”我爱你”;
在match下面匹配可以为包含:我、爱、你、我爱等等的解析器;
在term语法下面就精准匹配到:”我爱你”。
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": { "terms": {"about": ["travel","history"]}}
}
}
}
Range过滤允许我们按照指定的范围查找一些数据;操作范围:gt表示大于,gae表示大于等于,lt表示小于,lte表示小于等于
GET /school/student/_search?pretty
{
"query": {
"range": {
"age": {"gt":20,"lte":25}
}
}
}
exists和missing过滤可以找到文档中是否包含某个字段或者是没有某个字段;
GET /school/student/_search?pretty
{
"query": {
"exists": {
"field": "age"
}
}
}
用bool也可以像之前match一样来过滤多行条件:
must :多个查询条件的完全匹配,相当于 and 。
must_not :多个查询条件的相反匹配,相当于 not 。
should:至少有一个查询条件匹配, 相当于 or。
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": [
{"term": {
"about": {
"value": "travel"
}
}},{"range": {
"age": {
"gte": 20,
"lte": 30
}
}}
]
}
}
}
通常复杂的查询语句,用filter过滤语句可以来实现实现缓存;
GET /school/student/_search?pretty
{
"query": {
"bool": {
"must": {"match": {"about": "travel"}},
"filter": [{"term":{"age": 20}}]
}
}
}
在es当中,每个字段都会有默认的类型,根据我们第一次插入数据进去,es会自动帮我们推断字段的类型,当然我们也可以通过设置mappings来提前自定义我们字段的类型。
使用mapping的映射管理,提前指定字段的类型,防止后续的程序问题;
(1)添加索引:school,文档类型类logs,索引字段为message ,字段的类型为text;
PUT school
{
"mappings": {
"logs" : {
"properties": {"messages" : {"type": "text"}}
}
}}
GET /school/_mapping/logs
(2)继续添加字段
POST /school/_mapping/logs
{
"properties": {"number" : {"type": "text"}}
}
GET /school/_mapping/logs
(3)获取映射字段:
GET /school/_mapping/logs/field/number
(4)管理索引库分片数以及副本数settings:
settings就是用来修改索引分片和副本数的;通过setting来添加副本数。
PUT document
{
"mappings": {
"article" : {
"properties":
{
"title" : {"type": "text"} ,
"author" : {"type": "text"} ,
"titleScore" : {"type": "double"}
}
}
}
}
GET /document/_settings
把副本数改成2
PUT /document/_settings
{
"number_of_replicas": 2 (副本)
}
副本可以改,分片不能改
PUT /document/_settings
{
"number_of_shards": 3 (分片)
}
按照一般的查询流程来说,如果我想查询前10条数据:
from定义了目标数据的偏移值,size定义当前返回的事件数目。
GET /us/_search?pretty
{
"from" : 0 , "size" : 5
}
GET /us/_search?pretty
{
"from" : 5 , "size" : 5
}
浅分页只适合少量数据,因为随from增大,查询的时间就会越大,而且数据量越大,查询的效率指数下降;且Elasticsearch响应请求时必须确定docs的顺序,排列响应结果。
优点:from+size在数据量不大的情况下,效率比较高。
缺点:在数据量非常大的情况下,from+size分页会把全部记录加载到内存中,这样做不但运行速递特别慢,而且容易让es出现内存不足而挂掉。
scroll维护了当前索引段的一份快照信息--缓存(这个快照信息是执行这个scroll查询时的快照)。
scroll 分为初始化和遍历两步:
初始化:初始化的时候就像是普通的search一样
GET us/_search?scroll=3m
{
"query": {"match_all": {}},
"size": 3
}
scroll=3m代表当前查询的数据缓存3分钟
Size:3 代表当前查询3条数据
遍历:在遍历时候,拿到上一次遍历中的scrollid,然后带scroll参数,重复上一次的遍历步骤,直到返回的数据为空,就表示遍历完成。
GET /_search/scroll
{
"scroll" : "1m",
"scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAAPXFk0xN1BmSnlVUldhYThEdWVzZ19xbkEAAAAAAAAAIxZuQWVJU0VSZ1JzcVZtMGVYZ3RDaFlBAAAAAAAAA9oWTVZOdHJ2cXBSOU9wN3c1dk5vcWd4QQAAAAAAAAPYFk0xN1BmSnlVUldhYThEdWVzZ19xbkEAAAAAAAAAIhZuQWVJU0VSZ1JzcVZtMGVYZ3RDaFlB"
}
【注意】:每次都要传参数scroll,刷新搜索结果的缓存时间,另外不需要指定index和type(不要把缓存的时时间设置太长,占用内存)。
浅分页,每次查询都会去索引库(本地文件夹)中查询pageNum*page条数据,然后截取掉前面的数据,留下最后的数据。 这样的操作在每个分片上都会执行,最后会将多个分片的数据合并到一起,再次排序,截取需要的。
深分页,可以一次性将所有满足查询条件的数据,都放到内存中。分页的时候,在内存中查询。相对浅分页,就可以避免多次读取磁盘。
第一步:创建索引库并配置IK分词器
在创建索引库的时候,我们指定分词方式为ik_max_word,会对我们的中文进行最细粒度的切分;
PUT /iktest?pretty
{
"settings" : {
"analysis" : {
"analyzer" : {
"ik" : {
"tokenizer" : "ik_max_word"
}
}
}
},
"mappings" : {
"article" : {
"dynamic" : true,
"properties" : {
"subject" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
第二步:查看分词效果
在kibana当中执行以下查询,并验证分词效果:
GET _analyze?pretty
{
"analyzer": "ik_max_word",
"text": "特娘补是美国总统"
}
第三步:自定义配置热词更新
(1)查看分词效果
GET _analyze?pretty
{
"analyzer": "ik_max_word",
"text": "小老弟,你怎么肥事,老铁你来了!!!"
}
随着时间的推移和发展,有些网络热词我们并不能进行分词,因为网络热词并没有定义在我们的词库里面,这就需要我们经常能够实时的更新我们的网络热词,我们可以通过tomcat来实现远程词库来解决这个问题。
(2)在节点3上配置Tomcat
tar -zxf apache-tomcat-8.5.34.tar.gz -C /install/
(3)tomcat当中添加配置hot.dic
cd /install/apache-tomcat-8.5.34/webapps/ROOT
vi hot.dic,添加如下内容:
老铁
肥事
(4)启动tomcat
cd /install/apache-tomcat-8.5.34/
bin/startup.sh
(5)页面查看
http://node03:8080/hot.dic
(6)修改配置文件(每台机器都要改)
cd /kkb/install/elasticsearch-6.7.0/plugins/analysis-ik/config
vim IKAnalyzer.cfg.xml 修改如下内容:
IK Analyzer 扩展配置
http://node03:8080/hot.dic
(7)重启es,再再kibana中执行第一步的分词效果,注意比较两者的不同