一ElasticSearch 基础概念

Posted coyote_xujie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一ElasticSearch 基础概念相关的知识,希望对你有一定的参考价值。

一、 Elastic Stack

Elasticsearch 最初是作为独立产品开发的。它的核心作用是提供可扩展的搜索引擎服务,它提供多种语言库API(包括JAVA、Python等),基于分布式模型创建,并对外提供 REST API 接口服务。随着Elastic生态圈的发展,衍生出了 Elasticsearch 的相关 工具集合。例如 Kibana (用于可视化和数据分析)、Logstash (用于日志收集)、Beats (数据传输,轻量级的Logstash)等。Elastic Stack 不单单是Elasticsearch,而是一体化大数据解决方案的工具集。

二、ES 建模方式

2.1 数据集分类

根据数据性质的不同,Elasticsearch 中存储的数据可以分成两类:静态数据时间序列 数据。它们会严重影响集群的配置和管理方式。

  • 静态数据: 增长或更新缓慢的数据集。类似于存储在常规数据库中的数据,就像博客文章、图书馆书籍等。在这些数据中通过 elasticsearch 快速检索相关数据,完成常规数据库难以实现的功能。
  • 时间序列数据: 通常是快速增长或在时间维度上相互关联数据,例如日志文件、度量数据、传感器数据等。在这些数据中通过 elasticsearch 编制索引,以进行数据分析、模式发现和系统监视。

2.2 数据集建模方式

根据不同的数据类型,应该以不同的方式为数据建模。

  • 静态数据: 应该选择固定数量的索引和分片。它们不会快速增长,并且总是希望能够检索数据集中的所有文档。
  • 时间序列数据: 应该选择基于时间的滚动索引。因为会相对频繁地查询最近的数据,并且最终甚至会删除或者归档过时的文档以便节约物理存储资源。

三、ES 搜索评分

对于每个搜索查询,Elasticsearch 都会计算相关性分数。该分数基于 TF-IDF 算法,该算法代表 词频-逆文档频率。在该算法中需要计算两个值,分别是TF和IDF。
基本上,在该算法中计算两个值。

  • TF: 表示在文档中使用给定词项的频率。
  • IDF: 表示给定词项在所有文档中的唯一性。

3.1 词项 TF 计算

例如,如果我们有两个文档:

文档1:To be or not to be, that is the question.
文档2:To be. I am. You are. He, she is.

question 词项的 TF 计算如下:

  • 对于文档1:1/10(10个词项中有1个出现)
  • 对于文档2:0/9(9个词项中出现0次)。

3.2 词项 IDF 计算

IDF 计算为整个数据集的单个值。它是所有文档与包含搜索词的文档的比率。

question 词项的 IDF 计算如下:

在我们的例子中它是:log(2/1)= 0.301 (简化)

其中:

  • 2 - 所有文档的数量,
  • 1 - 包含“question”词项的文档数量。

3.3 相关性得分结果

最后,两个文档的 tf-idf 分数计算为两个值的乘积:

  • 文档1:1/10 x 0.301 = 0.1 * 0.301 = 0.03
  • 文档2:0/9 x 0.301 = 0 * 0.301 = 0.00
    现在可以看到文档1的值为0.03,而文档2的值为0.00。因此,文档1将在结果列表中优先返回。

例如:

# 创建索引
PUT index_test

  "mappings": 
    "properties": 
      "title": 
        "type": "text"
      
    
  


# 创建文档1
POST index_test/_doc/1

  "title":"To be or not to be, that is the question."


# 创建文档2
POST index_test/_doc/2

  "title":"To be. I am. You are. He, she is."


# 创建文档2 
POST index_test/_search

  "explain": true, 
  "query": 
    "match": 
        "title":"question"
    
  

结果:


  "took" : 13,
  "timed_out" : false,
  "_shards" : 
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  ,
  "hits" : 
    "total" : 
      "value" : 1,
      "relation" : "eq"
    ,
    "max_score" : 0.6785375,
    "hits" : [
      
        "_shard" : "[index_test][0]",
        "_node" : "_s5Ha-5nRoKfE_Az6iiujg",
        "_index" : "index_test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.6785375,
        "_source" : 
          "title" : "To be or not to be, that is the question."
        ,
        "_explanation" : 
          "value" : 0.6785375,
          "description" : "weight(title:question in 0) [PerFieldSimilarity], result of:",
          "details" : [
            
              "value" : 0.6785375,
              "description" : "score(freq=1.0), computed as boost * idf * tf from:",
              "details" : [
                
                  "value" : 2.2,
                  "description" : "boost",
                  "details" : [ ]
                ,
                
                  "value" : 0.6931472,
                  "description" : "idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                  "details" : [
                    
                      "value" : 1,
                      "description" : "n, number of documents containing term",
                      "details" : [ ]
                    ,
                    
                      "value" : 2,
                      "description" : "N, total number of documents with field",
                      "details" : [ ]
                    
                  ]
                ,
                
                  "value" : 0.4449649,
                  "description" : "tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                  "details" : [
                    
                      "value" : 1.0,
                      "description" : "freq, occurrences of term within document",
                      "details" : [ ]
                    ,
                    
                      "value" : 1.2,
                      "description" : "k1, term saturation parameter",
                      "details" : [ ]
                    ,
                    
                      "value" : 0.75,
                      "description" : "b, length normalization parameter",
                      "details" : [ ]
                    ,
                    
                      "value" : 10.0,
                      "description" : "dl, length of field",
                      "details" : [ ]
                    ,
                    
                      "value" : 9.5,
                      "description" : "avgdl, average length of field",
                      "details" : [ ]
                    
                  ]
                
              ]
            
          ]
        
      
    ]
  

 

四、 数据模型

Elasticsearch 其性能优势主要集中两个方面:

  1. 它可以水平扩展
  2. 检索速度非常快

其中 Elasticsearch 的检索速度主要取决于索引对数据的存储方式。

4.1 索引阶段数据模型(写入)

Elasticsearch 索引文档有三个步骤来规范化文档:

  1. character filters(字符过滤器)
  2. tokenizer(标记生成器)
  3. token filters(标记过滤器)

例如:

To be or not to be, that is the question.

  1. character filters:将 , 替换为 ,将 . 替换为 并且将所有的大写字母替换为小写字母即 To 替换为 to,则原文档更新为

    to be or not to be that is the question

  2. tokenizer:根据 将文档分割为一个个 token

    to、be、or、not、to、be、that、is、the、question

  3. token filters:按照停用词过滤器,它将删除所有常用语言术语 to、be、or、not、that、is、the,仅剩下

    question

4.2 搜索阶段数据模型(查询)

在搜索文档时会应用相同的步骤。Elasticsearch 会搜索带有规范化词项的文档,因此在查询时也会通过相同的三个步骤来规范化文档,获得规范化的词项(takenterm 我理解这两个应该表达的是一个意思)后通过倒排索引结构,快速获取匹配文档。

  1. character filters(字符过滤器)
  2. tokenizer(标记生成器)
  3. token filters(标记过滤器)

Elasticsearch 可以为每个字段定义特定的过滤器。借助于analyzers实现定义。可以使用多个analyzers分词器分析字段以实现不同的目标。例如可以使用 standard 分词器逐字分词,使用 ik_max_word 细粒度分词,使用 ik_smart 粗粒度分词。然后在搜索阶段,通过定义要扫描的字段,获得检索结果。也正是因为 ES 对数据的存储方式,和规范化文档使得它可以更快的提供查询结果

五、分片规划

5.1 分片数和索引数

索引在时就需要确定分片数,并且索引建成后分片数量不能修改,因此确定索引的分片数就尤为重要。根据经验来说,数据集的规模决定了索引的分片数,单个分片最大应包含 20-40 GB的数据。

每一个 shard 都对应一个 Lucene,考虑到 Lucene 用于倒排索引和快速搜索的所有结构和开销,较小的 shard(例如 1 GB)时没有意义的。

所以答案真的取决于你拥有的数据集。根据经验,单分片最大应包含20-40 GB的数据。 Shards来自Apache Lucene。此外,由于分片不能进一步划分,并且始终驻留在单个节点上。20-40 GB 的分片也可以很容易地移动到其他节点,可以说 20-40 GB 的分片是在提供恢复、重建速度和内存消耗之间的折衷值。

当然,这只是一个建议,最合理的规划应当根据实际业务场景,并实现其性能目标。

5.2 注意事项

  1. 为了知道每个索引应该有多少分片,可以简单地估计一下。首先通过将一些文档索引到一个临时索引中,看看它们消耗了多少存储空间,之后预测在某一段时间内有多少文档。这里的时间只的是时间序列数据集中部分时间,或静态数据集中全部时间。
  2. 可以新建索引,并通过 reindex 将数据迁移到合理的索引中。
  3. 查询包含单分片的30个索引和包含30个分片的1个大索引的性能是一致的。

六、节点类型

Elasticsearch节点可以包括多个角色。角色包括:

  • Master:主节点,
  • Data:数据节点,
  • Ingest:摄取节点,
  • Coordinating-only:仅协调节点。

每个角色都有对应的用途。

6.1 主节点

  • 作用: 负责集群范围的设置和更改,例如创建或删除索引,添加或删除节点以及将分片分配给节点。针对大数据量级规模的集群,每个集群中应至少包含3个候选主节点。系统会从所有符合主节点的节点中,选择一个节点作为主节点,其作用是执行集群范围的操作。另外两个节点纯粹是为了获得高可用性。
    硬件要求: 主节点对CPU,RAM和磁盘存储的要求相对较低。

6.2 数据节点

作用: 用于存储和搜索数据。
**硬件要求:**数据节点对所有资源都有很高的要求:CPU,RAM和磁盘。您拥有的数据越多,硬件资源要求也就越高。

6.3 Ingest节点

作用: 在实际索引发生之前,Ingest节点用于文档预处理。Ingest节点拦截批量和索引查询,应用转换,然后将文档传递回索引或批量API。
硬件要求: 低磁盘、中等RAM和高CPU,

6.4 仅协调节点

作用: 客户端请求的负载平衡器。
它知道特定文档可以驻留的位置,并将搜索请求路由到对应节点。
【官方文档警告】:
将过多的仅协调节点添加到集群会增加整个集群的负担,因为所选主节点必须等待来自每个节点的集群状态更新的确认!不应过分夸大仅协调节点的好处 - 数据节点可以愉快地用于相同的目的。

硬件要求: 低磁盘,中高速RAM和中高CPU。

6.5 配置大型集群的建议

  1. 三个主节点 -> 维护集群状态和集群设置,
  2. 两个仅协调节点 -> 它们监听外部请求,并充当整个集群的智能负载平衡器,
  3. 许多数据节点 -> 取决于数据集需求,
  4. 几个 Ingest节点(可选) - 如果 logstash 管道并希望减轻\\预处理文档对其他节点的影响。

Elasticsearch基础概念

前戏

主要的基础概念有:Node, Index,Type,Document,Field,shard和replicas.

Node(节点):运行单个ES实例的服务器

Cluster(集群):一个或多个节点构成集群

Index(索引):索引是多个文档的集合

Type(类型):一个Index可以定义一种或多种类型,将Document逻辑分组

Document(文档):Index里每条记录称为Document,若干文档构建一个Index

Field(字段):ES存储的最小单元

Shards(分片):ES将Index分为若干份,每一份就是一个分片

Replicas(副本):Index的一份或多份副本

为了便于理解,我们和系型数据库做一个对比:​

关系型数据库(如mysql,oracle等)

elasticsearch

database或schema

index

table

type

row

document

column或field

field

ES是分布式搜索引擎,每个索引有一个或多个分片(shard),索引的数据被分配到各个分片上。你可以看作是一份数据分成了多份给不同的节点。

当ES集群增加或删除节点时,shard会在多个节点中均衡分配。默认是5个primary shard(主分片)和1个replica shard(副本,用于容错)。

ES基础API操作

什么是API?

API(Application Programming Interface)应用程序编程接口,就是无需访问程序源码或理解内部工作机制就能实现一些相关功能的接口。

RestFul API 格式

curl -X<verb> ‘<protocol>://<host>:<port>/<path>?<query_string>’-d ‘<body>’


参数

描述

verb

HTTP方法,比如GET、POST、PUT、HEAD、DELETE

host

ES集群中的任意节点主机名

port

ES HTTP服务端口,默认9200

path

索引路径

query_string

可选的查询请求参数。例如?pretty参数将返回JSON格式数据

-d

里面放一个GET的JSON格式请求主体

body

自己写的 JSON格式的请求主体

elasticseearch的API很多, 我们运维人员主要用到以下几个要介绍的较简单的API。

更多API参考: ​​https://www.elastic.co/guide/en/elasticsearch/reference/6.2/index.html​

查看节点信息

通过curl或浏览器访问​​http://192.168.100.40:9200/_cat/nodes?v(ip​​为ES节点IP,如果有ES集群,则为ES任意节点IP)

Elasticsearch基础概念_数据


查看索引信息

通过curl或浏览器访问​​http://192.168.100.40:9200/_cat/indices?v​

Elasticsearch基础概念_数据_02

新增索引

[root@test1 ~]# curl -X PUT  http://192.168.100.40:9200/test_index
"acknowledged":true,"shards_acknowledged":true,"index":"test_index"[root@test1 ~]#
[root@test1 ~]# curl http://192.168.100.40:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open test_index NZIMDUzzQ6-eRdATRVODbw 5 1 0 0 1.1kb 460b
[root@test1 ~]#

Elasticsearch基础概念_elasticsearch_03


green:所有的主分片和副本分片都已分配。你的集群是100%可用的。

yellow:所有的主分片已经分片了,但至少还有一个副本是缺失的。不会有数据丢失,所以搜索结果依然是完整的。不过,你的高可用性在某种程度上被弱化。如果 更多的 分片消失,你就会丢数据了。把 yellow 想象成一个需要及时调查的警告。

red:至少一个主分片(以及它的全部副本)都在缺失中。这意味着你在缺少数据:搜索只能返回部分数据,而分配到这个分片上的写入请求会返回一个异常。

删除索引

curl -X DELETE http://192.168.100.40:9200/test_index

ES查询语句

ES提供一种可用于执行查询JSON式的语言,被称为Query DSL。

针对elasticsearch的操作,可以分为增、删、改、查四个动作。

查询匹配条件:

  • match_all
  • from,size
  • match
  • bool
  • range

查询应用案例:

导入数据源

使用官方提供的示例数据:

1, 下载并导入进elasticsearch

[root@test2 ~]# wget https://raw.githubusercontent.com/elastic/elasticsearch/master/docs/src/test/resources/accounts.json
导入进elasticsearch
[root@test2 ~]# curl -H "Content-Type: application/json" -XPOST "192.168.100.40:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@accounts.json"
curl -H "Content-Type: application/json" -XPOST "10.1.1.12:9200/bank/_doc/_bulk?pretty&refresh" --data-binary "@accounts.json"
查询确认
[root@test2 ~]# curl http://192.168.100.41:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open bank DejnYeioQFe3KxhRBlq6og 5 1 1000 0 949.3kb 474.6kb

Elasticsearch基础概念_json_04

查询bank索引的数据(使用查询字符串进行查询)

curl -X GET "192.168.100.40:9200/bank/_search?q=*&sort=account_number:asc&pretty"

说明:

默认结果为10条

_search  属于一类API,用于执行查询操作

q=* ES批量索引中的所有文档

sort=account_number:asc 表示根据account_number按升序对结果排序

pretty调整显示格式

Elasticsearch基础概念_elasticsearch_05

查询bank索引的数据 (使用json格式进行查询)​

curl -X GET "192.168.100.40:9200/bank/_search" -H Content-Type: application/json -d
> "query": "match_all": ,
> "sort": [
> "account_number": "asc"
> ]
>
>
注意: 最后为单引号

持续更新!!!

以上是关于一ElasticSearch 基础概念的主要内容,如果未能解决你的问题,请参考以下文章

一ElasticSearch 基础概念

Elasticsearch基础概念

Elasticsearch基础教程(转载)

搭建elasticsearch可视化插件

ElasticSearch是什么?为什么快?倒排索引是什么?ElasticSearch的应用?

(转载)Elasticsearch基础教程