热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ELK之ElasticSearch

目录1、ELK日志协议栈2、ELK日志协议栈整体架构3、Elasticsearch3.1、Elasticsearch核心概念3.2、管理索引3.2.1、PUT命令(创建、插入和更新

目录

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


1、ELK日志协议栈

ELK是三个软件产品的首字母缩写,Elasticsearch,Logstash 和 Kibana。

Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash是一个完全开源的工具,他可以对你的日志进行收集、过滤,并将其存储供以后使用(如,搜索)。

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

2、ELK日志协议栈整体架构

ELK之ElasticSearch

3、Elasticsearch

3.1、Elasticsearch核心概念

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的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。故引入分片的概念来解决这一问题。

分片:索引划分成多份的能力,这些份就叫做分片。每个分片本身也是一个功能完善并且独立的“索引”,它可以被放置到集群中的任何节点上。

分片的重要性:

  • 1)允许水平分割/扩展内容容量。  
  • 2)允许在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。

复制:在网络/云的环境里,失败随时都可能发生,在某个分片/节点处于离线状态时,或者消失了,这种情况下,故障转移机制是非常有用。因此,Elasticsearch允许创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。

复制的重要性:

  • 在分片/节点失败的情况下,提供了高可用性。复制分片从不与原/主要(original/primary)分片置于同一节点上。
  • 扩展搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。

默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制。

3.2管理索引

curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求。

curl

  • -X 指定http的请求方法 有HEAD GET POST PUT DELETE
  • -d 指定要传输的数据
  • -H 指定http请求头信息

3.2.1、PUT命令(创建、插入和更新)

(1)创建索引

在kibana的dev tools当中执行以下语句:curl -XPUT http://node01:9200/blog01/?pretty

ELK之ElasticSearch

(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"}'

3.2.2、GET命令

(1)查询文档

curl -XGET http://node01:9200/blog01/article/1?pretty

(2)搜索文档

curl -XGET "http://node01:9200/blog01/article/_search?q=title:elasticsearch"

3.2.3、DELETE命令

(1)删除文档

curl -XDELETE "http://node01:9200/blog01/article/1?pretty"

(2)删除索引

curl -XDELETE http://node01:9200/blog01?pretty

3.3、查询条件查询

3.3.1、使用match_all做查询

GET /school/student/_search?pretty
{
    "query": {
        "match_all": {}
    }
}

通过match_all匹配后,会把所有的数据检索出来。对于es集群来说,直接检索全部的数据,很容易造成GC现象。

3.3.2、通过关键字段进行查询

GET /school/student/_search?pretty
{
    "query": {
         "match": {

                        "about": "travel"

                        "sex":"girl"

          }
     }
}

注意:一个match下,不能出现多个字段值。如上文中match花括号里还有字段如:"sex":"girl",则会报[match] query doesn't support multiple fields的错误,必须使用bool复合查询。

3.3.3、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"}}
     }
  }
}

3.3.4、bool的复合查询中的should

should表示可有可无的(如果should匹配到了就展示,否则就不展示)。

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "match": {"about": "travel"}},
      "should": {"match": {"sex": "boy"}}         
     }
  }
}

3.3.5、term匹配

使用term进行精确匹配(比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型))。

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "term": {"about": "travel"}},
      "should": {"term": {"sex": "boy"}}         
     }}
}

3.3.6、使用terms匹配多个值

term主要是用于精确的过滤比如说:”我爱你”;

在match下面匹配可以为包含:我、爱、你、我爱等等的解析器;

在term语法下面就精准匹配到:”我爱你”。

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "terms": {"about": ["travel","history"]}}          
     }
  }
}

3.3.7、Range过滤

Range过滤允许我们按照指定的范围查找一些数据;操作范围:gt表示大于,gae表示大于等于,lt表示小于,lte表示小于等于

GET /school/student/_search?pretty
{
"query": {
   "range": {
    "age": {"gt":20,"lte":25}
         }
      }
}

3.3.8、exists和 missing过滤

exists和missing过滤可以找到文档中是否包含某个字段或者是没有某个字段;

GET /school/student/_search?pretty
{
"query": {
   "exists": {
    "field": "age"  
         }
      }
}

3.3.9、bool的多条件过滤

用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
          }
        }}
      ]
    }
  }
}

3.3.10、查询与过滤条件合并

通常复杂的查询语句,用filter过滤语句可以来实现实现缓存;

GET /school/student/_search?pretty
{
  "query": {
   "bool": {
     "must": {"match": {"about": "travel"}},     
     "filter": [{"term":{"age": 20}}]
     }
  }
}

3.4、定义字段类型mappings

在es当中,每个字段都会有默认的类型,根据我们第一次插入数据进去,es会自动帮我们推断字段的类型,当然我们也可以通过设置mappings来提前自定义我们字段的类型。

3.4.1、使用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

ELK之ElasticSearch

把副本数改成2

PUT /document/_settings
{
  "number_of_replicas": 2   (副本)
}

ELK之ElasticSearch

副本可以改,分片不能改

PUT /document/_settings
{
  "number_of_shards": 3   (分片)
}

ELK之ElasticSearch

3.5、分页解决方案

3.5.1、size+from浅分页

按照一般的查询流程来说,如果我想查询前10条数据:

  • (1)客户端请求发给某个节点;
  • (2)节点转发给各个分片,查询每个分片上的前10条;
  • (3)结果返回给节点,整合数据,提取前10条;
  • (4)返回给请求客户端。

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出现内存不足而挂掉。

3.5.2、scroll深分页

scroll维护了当前索引段的一份快照信息--缓存(这个快照信息是执行这个scroll查询时的快照)。

scroll 分为初始化和遍历两步:

  • 1、初始化时将所有符合搜索条件的搜索结果缓存起来,可以想象成快照;
  • 2、遍历时,这个快照里取数据

初始化:初始化的时候就像是普通的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(不要把缓存的时时间设置太长,占用内存)。

3.5.3、浅分页与深分页的对比

浅分页,每次查询都会去索引库(本地文件夹)中查询pageNum*page条数据,然后截取掉前面的数据,留下最后的数据。 这样的操作在每个分片上都会执行,最后会将多个分片的数据合并到一起,再次排序,截取需要的。

深分页,可以一次性将所有满足查询条件的数据,都放到内存中。分页的时候,在内存中查询。相对浅分页,就可以避免多次读取磁盘。

3.6、ES的中文分词器IK

第一步:创建索引库并配置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来实现远程词库来解决这个问题。

ELK之ElasticSearch

(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中执行第一步的分词效果,注意比较两者的不同


推荐阅读
author-avatar
走下去就下去
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有