ELK(搜索与分析技术栈)
创始人
2024-03-25 03:33:25
0

一、介绍

ELK其实并不是一款软件,而是一整套解决方案,是三个软件产品的首字母缩写,Elasticsearch,Logstash 和 Kibana。这三款软件都是开源软件,通常是配合使用,而且又先后归于 Elastic.co 公司名下,故被简称为ELK技术栈。

  • Elasticsearch:Elasticsearch是一个实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。它是一个建立在全文搜索引擎Apache Lucene基础上的搜索引擎,使用Java语言编写。

  • Kibana:Kibana是一个免费且开放的用户界面,能够让您对Elasticsearch数据进行可视化。Kibana是一款基于Apache开源协议的可视化Web管理平台。它可以在Elasticsearch的索引中查找,交互数据,并生成各种维度的表图。

  • Logstash:Logstash 是免费且开放的服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的“存储库”中。使用JRuby语言编写。其作者是世界著名的运维工程师乔丹西塞 (JordanSissel)

 二、Elasticsearch

(1)介绍

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式的全文搜索引擎,其对外服务是基于RESTful web接口发布的。Elasticsearch是用Java开发的应用,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到近实时搜索,稳定,可靠,快速,安装使用方便。

(2)主要功能

Elasticsearch具备两个主要功能:

  • 搜索:代替目前(海量数据)的MySQL模糊查询。

  • 分析:结合LogStash使用。类似数据库中的聚合统计查询。

(3)核心概念

1.Cluster

集群:Elasticsearch集群由一或多个节点组成,其中有一个主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。Elasticsearch的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部看Elasticsearch集群,在逻辑上是个整体,你与集群中的任何一个节点通信和与整个Elasticsearch集群通信是等价的。也就是说,主节点的存在不会产生单点安全隐患、并发访问瓶颈等问题。

2.Index(表)

索引:相当于关系型数据库中的表。其中存储若干相似结构的Document数据。如:客户索引,订单索引,商品索引等。Elasticsearch中的索引不像数据库表格一样有强制的数据结构约束,在理论上,可以存储任意结构的数据。但了为更好的为业务提供搜索

3.Shards(主分片)

Primary Shard:代表索引的主分片,Elasticsearch可以把一个完整的索引分成多个primary shard,这样的好处是可以把一个大的索引拆分成多个分片,分布存储在不同的Elasticsearch节点上,从而形成分布式存储,并为搜索访问提供分布式服务,提高并发处理能。primary shard的数量只能在索引创建时指定,并且索引创建后不能再更改primary shard数量。

 4.Replicas(副本)

Replica Shard:代表索引主分片的副本,Elasticsearch可以设置多个replica shard。replica shard的作用:一是提高系统的容错性,当某个节点某个primary shard损坏或丢失时可以从副本中恢复。二是提高Elasticsearch的查询效率,Elasticsearch会自动对搜索请求进行负载均衡,将并发的搜索请求发送给合适的节点,增强并发处理能力。

5.Type(逻辑分类)

类型:每个索引中都必须有唯一的一个Type,Type是Index中的一个逻辑分类。Elasticsearch中的数据Document是存储在索引下的Type中的。

6.Document(一条数据)

文档:Elasticsearch中的最小数据单元。一个Document就是一条数据,一般使用JSON数据结构表示。每个Index下的Type中都可以存储多个Document。一个Document中可定义多个field,field就是数据字段。如:学生数据({"name":"张三", "age":20, "gender":"男"})。

 7.MetaData(有特殊含义的属性,可以理解为关键字)

元数据:在Elasticsearch中所有以“_”开头的属性都成为元数据,都有着自己特定的含义。

8.Inverted Index(优化检索的关键)

倒排索引:对数据进行分析,抽取出数据中的词条,以词条作为key,对应数据的存储位置作为value,实现索引的存储。这种索引称为倒排索引。倒排索引是Document写入Elasticsearch时分析维护的。

 三、安装Elasticsearch和Kibana

(1)拉取Elasticsearch镜像

docker pull elasticsearch:7.6.2

(2)创建并启动Elasticsearch容器

9200是基于http协议的服务端口,9300是基于TCP协议的服务端口

docker run --name elasticsearch -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.6.2

(3)拉取Kibana镜像

docker pull kibana:7.6.2

(4)创建并启动Kibana容器

端口5601

docker run -d --name kibana --link elasticsearch:elasticsearch -p 5601:5601 kibana:7.6.2

四、常见Elasticsearch管理操作

 (1)查看健康状态

GET /_cat/health?v

含义表头数据
编号epoch1640140938
时间戳timestamp02:42:18
集群名称clusterdocker-cluster
健康状态statusgreen
节点总数node.total1
数据节点数node.data1
总分片数shards5
主分片数量pri5
备份分片数量relo0
正在初始化的分片init0
未分配的分片unassign0
正在等待执行的任务pending_tasks0
挂起任务的等待时间max_task_wait_time-
活动的分片的占有百分比active_shards_percent100.0%

健康状态含义说明

 status值包括:green、yellow、red

- green:每个索引的primary shard和replica shard都是active的。
- yellow:每个索引的primary shard都是active的,但部分的replica shard不是active的。
- red:不是所有的索引的primary shard都是active状态的。

 (2)查看节点信息

GET /_cat/nodes?v

含义表头数据
ES主机地址ip172.17.0.5
堆占用率heap.percent13
内存占用率ram.percent96
CPU占用率cpu2
每分钟平均运行命令load_1m0.46
每5分钟平均运行命令load_5m0.21
每15分钟平均运行命令load_15m0.20
ES节点权限node.roledilm
是否是主节点master*
ES节点名称namedd99a098c1f0

(3)查看Elasticsearch中的全部索引 

GET /_cat/indices?v

含义表头数据
健康状态healthgreen
索引是否可用statusopen
索引名称index.kibana_1
索引唯一键uuid3opvkLJPQdaDCYuEBGZFRA
主分片数量pri1
副本分片数量rep0
索引中文档总数docs.count16
索引中已删除文档数docs.deleted0
索引总计占用空间store.size23kb
索引主分片占用空间pri.store.size23kb

(4)查看分片信息

 GET /_cat/shards?v

含义表头数据
索引名称index.kibana_1
分片编号(从0开始自然数递增)shard0
主分片(p)或副本分片(r)prirepp
分片状态stateSTARTED
分片中文档数docs16
分片占用存储空间store26kb
分片所在ES服务器IPip172.17.0.5
分片所在ES服务器名称nodedd99a098c1f0

(5)创建索引

命令语法:PUT 索引名{索引配置参数} ​ index名称必须是小写的,且不能以下划线'_','-','+'开头。 ​ ElasticSearch7.x版本中,默认创建索引时,分配一个Primary Shard,每个Primary Shard分配一个Replica Shard。在Elasticsearch6.x及更早版本中,默认的创建索引的时候,会分配五个Primary Shard,并为每个Primary Shard分配一个Replica Shard。在Elasticsearch中,默认的限制是:如果磁盘空间不足15%的时候,不分配Replica Shard。如果磁盘空间不足5%的时候,不再分配任何的Primary Shard。Elasticsearch中对shard的分布是有要求的。Elasticsearch尽可能保证Primary Shard平均分布在多个节点上。Replica Shard会保证不和他备份的那个Primary Shard分配在同一个节点上,且每个节点中不会存在相同的备份Replica Shard。

PUT /index_test_1 

(6)创建索引并指定配置

PUT /index_test_1
{
  "settings":{
    "number_of_shards" : 2, #主分片数量
    "number_of_replicas" : 0 #每个主分片的副本分片数量
  }
}

(7)修改索引

PUT /index_test_2/_settings
{
  "number_of_replicas" : 2
}

(8)查看索引详情 

GET /index_test_1

(9)删除索引

DELETE /index_test_1,index_test_2 

(10)PUT新增文档(_doc)

PUT语法新增文档时,默认逻辑是:如果主键_id不存在,则新增数据;存在则覆盖旧数据。

PUT /index_test_1/_doc/1
{
  "name":"张三",
  "address":"北京亦庄"
}

(11)PUT强制新增(_create)

PUT语法新增文档时,可以通过参数实现强制新增。其逻辑是:如果主键_id不存在,则新增数据;存在则抛出异常。

PUT /index_test_1/_create/2
{
  "name":"李四",
  "address":"北京亦庄"
}

(12)POST文档新增

POST语法新增文档特性和PUT语法新增文档一致,只是POST允许主键自动生成。

POST /index_test_1/_doc
{
  "name":"王五",
  "address":"北京亦庄"
}

(13)GET根据主键查询文档(_doc)

GET /index_test_1/_doc/1

(14)GET根据主键批量查询文档(_mget)

GET /index_test_1/_mget
{
  "docs":[
    {
      "_id":1
    },
    {
      "_id":2
    }
  ]
}

(15)GET查询全部(_search)

GET /index_test_1/_search

(16)全文替换

和新增的PUT|POST语法是一致。

PUT /index_test_1/_doc/1
{
  "name":"张三",
  "address":"北京亦庄"
}

(17)POST部分文档更新(_update

POST /index_test_1/_update/1
{
  "doc":{
    "address":"赛帝工业园",
    "age":22
  }
}

(18)DELETE删除文档(_doc)

DELETE /index_test_1/_doc/1

(19)bulk批量增删改

使用bulk语法执行批量增删改。注意:_bulk的所有{}有强制要求,每个{}必须是一行,多个{}之间必须另起一行。语法格式如下: ​ POST [/索引名称/_doc]/_bulk ​ { "action_type" : { "metadata_name" : "metadata_value" } } ​ { document datas } ​ 语法中的action_type可选值为:

  • create:强制新增,相当于PUT /索引名/_create/主键。

  • index: 普通的保存文档操作,相当于新增文档或全量替换。

  • update: 更新操作(partial update),相当于 POST /索引名/_update/唯一ID{doc:{字段名:字段值}}。

  • delete: 删除操作。

 POST /_bulk
{ "create" : { "_index" : "index_test_1" , "_id" : "1" } }
{ "name" : "测试create" }
{ "index" : { "_index" : "index_test_1" , "_id" : "1" } }
{ "name" : "批量新增name1" , "address" : "批量新增address1" }
{ "index" : { "_index" : "index_test_1" , "_id" : "2" } }
{ "name" : "批量新增name2" , "address":"批量新增address2" }
{ "delete" : { "_index" : "index_test_1" , "_id" : "1" } }
{ "update" : { "_index" : "index_test_1" , "_id" : "2" } }
{ "doc" : { "address" : "批量更新address3" } }

五、分词器和标准化处理

 当一个文档被索引时,每个Field都可能会创建一个倒排索引(Mapping可以设置不索引该Field)。创建倒排索引的过程就是将文档通过Analyzer分成一个一个的Term,每一个Term都指向包含这个Term的文档集合。当搜索(search)时,Elasticsearch会根据搜索类型决定是否对搜索条件进行Analysis,然后和倒排索引中的term进行相关性查询,匹配相应的文档。

(1) Elasticsearch常见的内置的分词器

1. standard

切分过程中不会忽略停止词(如:the、a、an等)。会进行单词的大小写转换、过滤连接符(-)或括号等常见符号。

GET /_analyze
{
  "text": "Set the shape to semi-transparent by calling set_trans(5)",
  "analyzer": "standard"
}

2.simple

就是将数据切分成一个个的单词。使用较少,经常会破坏英语语法。

GET /_analyze
{
  "text": "Set the shape to semi-transparent by calling set_trans(5)",
  "analyzer": "simple"
}

3.whitespace

就是根据空白符号切分数据。如:空格、制表符等。使用较少,经常会破坏英语语法。

GET /_analyze
{
  "text": "Set the shape to semi-transparent by calling set_trans(5)",
  "analyzer": "whitespace"
}

4.language

据英语语法分词,会忽略停止词、转换大小写、单复数转换、时态转换等。

GET /_analyze
{
  "text": "Set the shape to semi-transparent by calling set_trans(5)",
  "analyzer": "english"
}

(2)中文分词器 - IK

IK分词器提供了两种analyzer,分别是ik_max_word和ik_smart。 ​

ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,国,国歌”,会穷尽各种可能的组合; ​

ik_smart: 会做粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。

GET _analyze
{
  "text" : "中华人民共和国国歌",
  "analyzer": "ik_max_word"
}

GET _analyze
{
  "text" : "中华人民共和国国歌",
  "analyzer": "ik_smart"
}

六、Elasticsearch中的Mapping问题

(1)介绍

Mapping在Elasticsearch中是非常重要的一个概念。决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段等。

(2)数据类型

只有text类型能被分词

类型类型名称
文本(字符串)text
整数byte、short、integer、long
浮点型float、double
布尔类型boolean
日期类型date
数组类型array {a:[]}
对象类型object {a:{}}
不分词的字符串(关键字)keyword

 (3)查看索引中的Mapping

GET /index_test_1/_mapping

 (4)自定义映射

语法:

PUT /索引名称
{
  "mappings":{
    "properties":{
      "字段名":{
        "type":类型,
        ["analyzer":字段的分词器(默认standard),]
        ["index":是否创建索引树(默认true,创建索引),]
        ["fields":{
          "子字段名称":{
            "type":类型,
            "ignore_above":长度限制
          }
        }]
      }
    }
  }
}

案例:

put /index_mapping_1
{
  "mappings":{
    "properties":{
      "id":{
        "type":"long",
        "index":false
      },
      "name":{
        "type":"text",
        "index":true,
        "analyzer":"ik_max_word"
      },
      "remark":{
        "type":"text",
        "analyzer":"ik_smart",
        "fields" : {
          "keyword" : {
            "type" : "keyword",
            "ignore_above" : 16
          }
        }
      },
      "gender":{
        "type":"keyword"
      }
    }
  }
}

(5)为已有的索引增加新的字段Mapping

语法:

PUT /索引名/_mapping
{
  "properties":{
    "新字段名":{
      "type":类型,
      ["analyer":字段的分词器,]
      ["index":是否创建索引树(默认true,创建索引),]
      ["fields":{
        "子字段名":{
          "type":类型,
          "ignore_above":长度
        }
      }]
    }
  }
}

案例:

PUT /index_mapping_1/_mapping
{
    "properties":{
      "address":{
        "type":"text",
        "analyzer":"ik_max_word"
      }
  }
}

七、Search搜索详解

(1)搜索全部

GET /_search

timeout参数:是超时时长定义。代表每个节点上的每个shard执行搜索时最多耗时多久。不会影响响应的正常返回。只会影响返回响应中的数据数量。

GET /_search?timeout=10ms

(2)指定索引搜索

GET /index_test_1,test_search/_search

(3)索引的模糊搜索

GET /index_*/_search

GET /test_*/_search

(4) 在所有字段中搜索

GET /test_search/_search?q=sales

(5)在指定字段中搜索

GET /test_search/_search?q=+dname:sales

(6)在指定字段中搜索不存在

GET /test_search/_search?q=-dname:sales

(7)分页搜索

from代表从第几个文档开始(从0开始,自然数递增,默认0),size代表搜索多少个文档(默认10)。

GET /test_search/_search?from=0&size=2

(8)搜索结果排序

排序规则: asc(升序,默认) | desc(降序)

GET /test_search/_search?sort=eage:asc

GET /test_search/_search?sort=eage:desc

八、DSL Search搜索详解

(1)搜索全部

GET /test_search/_search
{
   "query" : { "match_all" : {} }
}

(2)匹配搜索(match)

GET /test_search/_search
{
  "query": {
    "match": {
      "dname": "sales department"
    }
  }
}

(3)短语搜索(match_phrase)

GET /test_search/_search
{
  "query": {
    "match_phrase": {
      "dname": "sales department"
    }
  }
}

(4)范围搜索(range)

GET /test_search/_search
{
  "query" : {
    "range" : {
      "eage" : {
        "gte" : 20,
        "lte" : 30
      }
    }
  }
}

(5)多条件复合搜索

GET /索引名/_search
{
  "query": {
    "bool": {
      "must": [ #数组中的多个条件必须同时满足
        {
          "range": {
            "字段名": {
              "lt": 条件
            }
          }
        }
      ],
      "must_not":[ #数组中的多个条件必须都不满足
        {
          "match": {
            "字段名": "条件"
          }
        },
        {
          "range": {
            "字段名": {
              "gte": "搜索条件"
            }
          }
        }
      ],
      "should": [# 数组中的多个条件有任意一个满足即可。 当和must一起使用的时候,丧失意义。minimum_should_match=1设置至少满足一个条件。
        {
          "match": {
            "字段名": "条件"
          }
        },
        {
          "range": {
            "字段名": {
              "gte": "搜索条件"
            }
          }
        }
      ]
    }
  }

GET /test_search/_search
{
  "query": {
    "bool": {
      "must": [ 
        {
          "range": {
            "eage": {
              "lte": 26,
              "gte": 20
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "dname": "Sales Department"
          }
        },
        {
          "match": {
            "ename": "张三"
          }
        }
      ]
    }
  }
}

(6)排序

GET 索引名/类型名/_search
{
  "query" : { "match_all" : {} },
  "sort": [
    {
      "gender": {
        "order": "asc"
      }
    },
    {
      "eage": {
        "order": "desc"
      }
    }
  ]
}

(7)分页

GET 索引名称/_search
{
  "query":{
    "match_all":{}
  },
  "from": 0,
  "size": 2
}

(8)高亮

参数名参数含义
fragment_size代表字段数据如果过长,则分段,每个片段数据长度为多少。长度不是字符数量,是Elasticsearch内部的数据长度计算方式。默认不对字段做分段。
number_of_fragments代表搜索返回的高亮片段数量,默认情况下会将拆分后的所有片段都返回。
pre_tags高亮前缀。
post_tags高亮后缀。

GET /索引名/_search
{
  "query": {
    "match": {
      "字段名": "条件"
    }
  },
  "highlight": {
    "fields": {
      "要高亮显示的字段名": {
        "fragment_size": 5, #每个分段长度,默认20
        "number_of_fragments": 1 #返回多少个分段,默认3
      }
    },
    "pre_tags": ["前缀"], 
    "post_tags": ["后缀"] 
  }
}

GET /test_search/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "dname": "Development department"
          }
        },
        {
          "match": {
            "gender": "男性"
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "dname": {
        "fragment_size": 20,
        "number_of_fragments": 1
      },
      "gender": {
        "fragment_size": 20,
        "number_of_fragments": 1
      }
    },
    "pre_tags":[""],
    "post_tags":["
"]
  }, 
  "from": 2,
  "size": 2
}

相关内容

热门资讯

用心做好每一块电池的欣旺达,因... 这两天国内动力电池生产厂商欣旺达遇到麻烦事了,因其所生产的电芯存在质量问题被威睿电动汽车技术(宁波)...
以案为鉴筑防线 以审促廉扬清风... 为充分发挥以案释法、以案说纪的警示教育作用,进一步加强党风廉政建设,提高党员干部的法纪意识和廉洁意识...
新加坡国立大学东亚研究所高级研... 由三亚市人民政府主办,《财经》杂志、财经网、《财经智库》、三亚中央商务区管理局、三亚经济研究院承办的...
原创 全... 在国家有关调查力量进驻南京之后,一个并不显眼、却耐人寻味的现象悄然出现了。 短时间内,全国多地博物馆...
跨境金融研究院院长王志毅:离岸... 由三亚市人民政府主办,《财经》杂志、财经网、《财经智库》、三亚中央商务区管理局、三亚经济研究院承办的...
原告向法官出示证据,右下角赫然... 近日,湖北孝感大悟法院民二庭在审理一起房屋租赁合同纠纷案时,精准识破原告方利用AI技术伪造证据的行为...
美国纽约州出台法律约束“成瘾性... 美国纽约州州长凯茜·霍楚尔26日宣布,根据该州新出台的一项法律,具备无限刷新、自动播放和算法推送功能...
富安娜理财纠纷一审落槌,中信证... 乐居财经 李兰经历近三年后,富安娜(002327.SZ)理财纠纷有了新进展。 12月25日,富安娜发...
从合作伙伴到对簿公堂:威睿起诉... 12月26日,欣旺达发布公告,其全资子公司欣旺达动力科技股份有限公司(下称“欣旺达动力”)因买卖合同...
突发!俄称已控制库皮扬斯克;泽... 俄乌,突传大消息! 俄国防部称已控制库皮扬斯克 俄罗斯国防部12月27日在每日例行通报中说,库皮扬斯...