从零开始的Elasticsearch学习-加深学习

从零开始的Elasticsearch学习-加深学习

一、前言

Elasticsearch是一个基于Apache Lucene构建的开源搜索引擎。它能够快速地存储、搜索和分析大量数据。与传统数据库查询相比,Elasticsearch提供了更为灵活的搜索功能,支持近实时的搜索,并且能够处理大规模数据集。Elasticsearch广泛应用于日志和事件数据分析、全文搜索、安全情报等领域。

官网:Elasticsearch官网

二、Elasticsearch核心概念

2.1 索引

在Elasticsearch中,索引是数据存储和检索的基础。类似于数据库中的表,索引包含了一系列的文档(documents)。

2.2 文档

文档是Elasticsearch中的基本数据单位,类似于关系型数据库中的行。每个文档都有一个唯一的ID,并且包含了一系列的字段(fields),字段中存储了实际的数据。

元数据(metadata)

  • _index:文档所属的索引名称。
  • _type:文档的类型,用于区分同一索引下的不同类别文档(在7.0版本后,_type已被弃用)。
  • _id:文档的唯一标识。

2.3 基本数据操作

创建删除索引
// 创建索引
PUT /my_index
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 2
  }
}

// 删除索引
DELETE /my_index
创建删除文档
// 创建文档
POST /my_index/_doc/1
{
  "name": "John Doe",
  "age": 30,
  "city": "New York"
}

// 删除文档
DELETE /my_index/_doc/1
查询
// 简单查询
GET /my_index/_search
{
  "query": {
    "match": {
      "name": "John Doe"
    }
  }
}
GET /my_index/_doc/1

2.4 批量操作

1. _msearch查询

_msearch API 允许你在一个请求中执行多个搜索请求。这对于需要在多个索引或查询类型中检索信息,或者需要执行多个不同查询的场景非常有用。每个搜索请求可以包含自己的查询条件、分页选项等。

// 批量查询
POST /_msearch   
{"index" : "my_index"}  //请求头
{"query" : {"match" : {"title" : "test1"}}}  
{"index" : "my_index"}  
{"query" : {"match" : {"title" : "test2"}}}
2. _bulk操作

_bulk API 允许你在一个请求中执行多个索引、更新或删除操作。这对于批量导入数据、更新多个文档或删除大量文档时非常有用,因为它减少了网络往返次数,提高了性能。

// _bulk操作
POST /_bulk
{ "index" : { "_index" : "my_index", "_id" : "1" } }
{ "name": "Jane Doe", "age": 25, "city": "Los Angeles" } 
{ "delete" : { "_index" : "my_index", "_id" : "1" } }

解释:指定了目标索引(_index)为 my_index 和要操作的文档 ID(_id)为 1。索引操作将创建一个新的文档或更新已存在的文档,第二行是文档内容,第三行删除操作。

使用 _bulk API 可以显著减少执行大量操作所需的网络请求数量,因此它是 Elasticsearch 中处理大量数据的高效方式之一。

3.mget批量id查询

mget API 允许你根据一组文档的 ID 来批量检索这些文档。这对于当你需要一次获取多个特定文档时非常有用,因为它可以减少网络往返次数并提高性能。

// mget批量id查询
POST /_mget
{
  "docs" : [
    {
      "_index" : "my_index",
      "_id" : "1"
    },
    {
      "_index" : "my_index",
      "_id" : "2"
    }
  ]
}

2.5 条件查询api

term查询

用于精确匹配某个字段的值。

// term查询
GET /my_index/_search
{
  "query": {
    "term": {
      "city": "New York"
    }
  }
}
terms查询

用于匹配字段的多个可能值。

// terms查询
GET /my_index/_search
{
  "query": {
    "terms": {
      "city": ["New York", "Los Angeles"]
    }
  }
}
range查询

用于匹配某个字段的值在某个范围内的文档。

// range查询
GET /my_index/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 20,
        "lte": 30
      }
    }
  }
}
match查询

用于全文搜索,会对查询的文本进行分词,并匹配包含这些词的文档。

// match查询
GET /my_index/_search
{
  "query": {
    "match": {
      "name": "Doe"
    }
  }
}
bool查询

用于组合多个查询条件,通过mustshouldmust_not来定义文档的匹配逻辑。

// bool查询
GET /my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "name": "John Doe" } }
      ],
      "filter": [
        { "range": { "age": { "gte": 20 } } }
      ]
    }
  }
}
exists过滤

用于过滤存在某个字段的文档。

// exists过滤
GET /my_index/_search
{
  "query": {
    "exists": {
      "field": "city"
    }
  }
}
missing过滤

用于过滤不存在某个字段的文档。

// missing过滤
GET /my_index/_search
{
  "query": {
    "missing": {
      "field": "city"
    }
  }
}

查询和过滤的对比,以及各自使用场景

  • 查询(Query):用于对文档进行全文搜索,返回匹配的文档。
  • 过滤(Filter):用于对搜索结果进行过滤,不计算评分,通常用于精确匹配、范围查询等。

2.6分词器

Elasticsearch分词器是Elasticsearch用于将文本拆分为单词(词项)的组件,以便于搜索和索引。分词器在ES中扮演着将文本转换为可索引和搜索的词元的角色,它根据预设的规则和算法,将输入的字符流分割成词元。每个词元通常代表一个独立的单词或词组,同时分词器还会记录词元的位置和原始单词的字符偏移量,为后续的搜索和索引操作提供必要的信息。

Elasticsearch包含多个分词器,如标准分词器、较好的中文分词器、IK分词器等。这些分词器适用于不同的场景和需求。例如,在中文环境中,由于中文没有空格来分隔单词,所以通常需要使用专门设计的中文分词器,如IK Analyzer。这样的分词器能够更好地理解中文文本的语义和结构,提高搜索的准确性。

分词过程通常包括将文本分成一个个词项,并去掉常见的停用词。分词后,Elasticsearch将每个词项与其所在文档的信息关联起来,建立倒排索引,以便于快速搜索文档。在搜索过程中,Elasticsearch会接收一个查询字符串,并将其转换为查询对象,然后与倒排索引中的文档信息匹配,最终返回匹配的文档。

IK分词器

使用Elasticsearch的_analyze API来测试分词器的分词效果。

GET /_analyze  
{  
  "analyzer": "ik_max_word",  
  "text": "我爱Elasticsearch"  
}

解释:指定了使用ik_max_word分词器(IK分词器的细粒度分词模式),并提供了要分词的文本"我爱Elasticsearch"

得到结果

{  
  "tokens": [  
    {  
      "token": "我",  
      "start_offset": 0,  
      "end_offset": 1,  
      "type": "CN_CHAR",  
      "position": 0  
    },  
    {  
      "token": "爱",  
      "start_offset": 1,  
      "end_offset": 2,  
      "type": "CN_CHAR",  
      "position": 1  
    },  
    {  
      "token": "elasticsearch",  
      "start_offset": 2,  
      "end_offset": 12,  
      "type": "ENGLISH",  
      "position": 2  
    }  
    // ... 可能还有其他分词结果  
  ]  
}

响应显示了分词器将输入文本分成了多个词项,并提供了每个词项的详细信息,如起始偏移量、结束偏移量、类型和位置等。

三、Elasticsearch原理

3.1 倒排索引

Elasticsearch使用倒排索引来存储和检索数据。倒排索引将文档中的每个词项映射到包含它的文档列表。这种结构使得Elasticsearch能够快速地对文本数据进行搜索和分析。在倒排索引中,所有的文档中的每个词都被作为关键字,并记录下这些关键字在哪些文档中出现过。这样,在用户查询时,系统可以迅速定位到包含特定关键词的文档,从而大大提高搜索效率。

正排索引

正排索引,也被称为前向索引,是以文档的ID作为索引,记录每个文档包含哪些词汇,以及这些词汇在文档中出现的位置或频率等信息。简单来说,正排索引是以文档为主体,记录文档中词汇的信息。这种索引结构更适用于全文阅读或展示文档内容等场景。

3.2 ElasticSearch的写入、删除和更新内部原理

Elasticsearch将文档写入到索引中时,会先对文档进行分词和分析,然后根据分析结果构建倒排索引。删除操作会标记文档为删除,而更新操作实际上是创建一个新的文档版本并删除旧版本。

写入原理

  1. 倒排索引:Elasticsearch使用倒排索引来加速数据的搜索和匹配。倒排索引是一种数据结构,它将文档中的每个词映射到包含该词的文档。这样,当用户进行搜索时,Elasticsearch可以快速定位到包含特定关键词的文档。
  2. 写入流程:数据首先被写入内存中的buffer,同时这一操作也会被记录到translog(事务日志)中。此时,数据还不能被检索到。每隔一段时间(这个时间可以调整),Elasticsearch会执行一次refresh操作,将buffer中的数据刷新到os cache中,构成一个segment分段。这时,数据就可以被检索到了。随着不断的写入操作,会产生更多的segment,translog也会不断增大。当达到一定的时间或translog的大小达到阈值时,Elasticsearch会执行一次fsync操作,将内存中的所有segment写入磁盘,并清空translog。

删除原理

  1. 标记删除:在Elasticsearch中,删除操作并不是直接从磁盘上删除文档,而是将文档标记为已删除状态。这是通过倒排索引来实现的。当执行删除操作时,Elasticsearch会将要删除的文档的标识信息(如文档的ID)添加到一个称为删除列表的数据结构中。
  2. 合并操作:在下一次执行合并操作时(如flush或segment merge),Elasticsearch会将删除列表中的标识信息应用到倒排索引中,从而将对应的文档标记为已删除状态。这样,在后续的搜索操作中,这些已删除的文档就不会被返回。

更新原理

  1. 基于倒排索引和乐观并发控制:在更新过程中,Elasticsearch会加载文档的源数据,并根据更新请求对字段进行修改。修改后的文档会保存到倒排索引中,并生成新的版本号。
  2. 乐观并发控制:Elasticsearch通过乐观并发控制机制来处理并发更新操作。这意味着在更新时,系统假设冲突不太可能发生,因此不会立即锁定资源。如果多个并发更新操作的版本号一致,则允许更新操作执行;如果版本号不一致,则会返回一个版本冲突的错误。这种机制可以提高系统的性能和吞吐量。
  3. 处理版本冲突:当出现版本冲突时,可以通过重试和乐观并发控制机制来处理。重试时,系统会检查最新的版本号,并基于该版本号进行更新。这样,可以确保在并发环境下数据的一致性和可靠性。

3.3 ElasticSearch查询原理

Elasticsearch的查询内部原理和流程主要依赖于其核心的倒排索引结构和一系列复杂的处理步骤。

查询原理

Elasticsearch的查询内部原理主要基于其倒排索引结构。倒排索引允许Elasticsearch根据关键词快速定位到包含这些关键词的文档。在构建倒排索引时,Elasticsearch会为文档中的每个单词创建一个条目,这些条目包含了单词在哪些文档中出现以及出现的位置等信息。这样,当用户输入查询关键词时,Elasticsearch可以快速扫描倒排索引,找到与关键词匹配的文档。

此外,Elasticsearch还支持各种复杂的查询类型和查询条件,如范围查询、模糊查询、通配符查询等。这些查询类型可以通过组合和嵌套来实现更复杂的查询需求。

查询流程

  1. 接收查询请求:当用户发起查询请求时,Elasticsearch会接收该请求,并解析其中的查询条件和参数。
  2. 构建查询计划:根据解析后的查询条件和参数,Elasticsearch会构建一个查询计划。这个计划描述了如何执行查询以及需要扫描哪些索引和文档。
  3. 扫描倒排索引:Elasticsearch会根据查询计划扫描倒排索引,找到与查询关键词匹配的文档。这一步是查询过程中最耗时的部分,因为需要遍历大量的索引条目。
  4. 过滤和排序:在找到匹配的文档后,Elasticsearch会根据查询条件中的过滤条件对文档进行过滤,只保留符合条件的文档。同时,还可以根据排序条件对文档进行排序。
  5. 聚合和分组:如果查询中包含聚合或分组操作,Elasticsearch会对过滤和排序后的文档进行聚合和分组计算,以生成聚合结果。
  6. 返回查询结果:最后,Elasticsearch会将查询结果返回给用户。这个结果包括符合条件的文档列表、聚合结果以及其他相关信息。

在整个查询过程中,Elasticsearch还会利用一些优化机制来提高查询性能,如缓存机制、分布式查询等。这些机制可以帮助减少查询的响应时间并提高系统的吞吐量。

总结来说,Elasticsearch的查询内部原理和流程是基于其倒排索引结构的一系列复杂处理步骤。通过构建查询计划、扫描倒排索引、过滤和排序文档以及聚合和分组等操作,Elasticsearch能够快速、准确地返回用户所需的查询结果。

3.4 Elasticsearch分布式架构

Elasticsearch的分布式架构是其强大性能和高度可扩展性的关键所在。这种架构允许Elasticsearch在多个节点上进行水平扩展,以处理大量数据。Elasticsearch分布式架构介绍:

  1. 节点与集群
    • 节点:Elasticsearch中的每个实例都称为一个节点。节点可以运行多个索引和搜索请求,并与其他节点通信以实现分布式搜索和分析。
    • 集群:节点组成的集群是Elasticsearch的基本组件。集群可以跨多个节点和机器分布数据和计算,从而确保数据在集群中的分布和冗余,以及监控集群的健康状况和进行故障恢复。
  2. 节点类型
    • 主节点:负责管理集群级别的操作,例如创建或删除索引、添加或删除节点等。
    • 数据节点:存储分片并处理搜索和分析请求。数据节点在集群中承担大部分计算和存储任务,其数量和配置可以根据需要进行调整,以满足性能和可靠性需求。
    • 协调节点:不存储数据,也不执行数据相关的操作,而是充当集群与外部客户端之间的通信中介,帮助分担数据节点的负载并提高集群的响应速度。
  3. 分片与副本
    • Elasticsearch将数据分为多个分片(shard),并将这些分片分布在不同的节点上。每个节点都可以存储和处理其中的一部分分片。
    • 为了提高可用性,Elasticsearch会在集群中复制多个分片副本。当进行搜索时,查询被路由到包含相关分片的节点上,并行地检索和聚合结果。
  4. 分布式搜索和聚合
    • Elasticsearch支持分布式搜索和聚合操作,能够将搜索和聚合任务分散到多个节点上,并将结果合并返回给客户端。这使得Elasticsearch能够处理大规模数据并实时返回结果。
  5. 优化技术
    • 为了进一步提高性能和效率,Elasticsearch使用了一系列优化技术,如倒排索引、内存缓存、多线程处理以及多种压缩算法等。
  6. 集群故障转移
    • 在节点、分片或副本发生故障时,数据和状态能够自动转移到其他可用的节点或分片,从而保持服务的可用性和数据的完整性。

四、Elasticsearch集群

4.1介绍

Elasticsearch集群是由多个Elasticsearch节点组成的分布式系统,主要用于存储和搜索大规模的数据。每个节点都是一个完整的搜索引擎,可以独立处理请求,并负责数据的存储和搜索。集群中的所有节点共同合作,共享索引和数据,提供分布式搜索和存储服务。通过将数据划分为分片并分布在多个节点上,Elasticsearch集群可以实现横向扩展和高可用性。

4.2基于集群的数据写入流程

  1. 客户端发送写入请求
    客户端向Elasticsearch集群发送写入请求,这个请求中包含要写入的索引、类型以及文档数据。文档数据通常是JSON格式,并可能包含文档ID,用于指明要写入的文档的唯一标识符。
  2. 路由到正确的分片
    Elasticsearch根据请求中的索引和类型信息,通过哈希算法确定该文档属于哪个分片。每个索引都会被划分为多个分片,每个分片负责一部分数据。这种分片机制使得Elasticsearch能够水平扩展,处理大规模数据。
  3. 主分片写入
    一旦确定了文档所属的分片,Elasticsearch会选择一个主分片进行写入操作。每个索引都有一个主分片,它负责处理所有的写入操作。文档首先被写入这个主分片。
  4. 主从复制
    写入主分片成功后,Elasticsearch会将该文档复制到对应的副本分片。副本分片位于不同的节点上,用于提供数据的冗余和高可用性。这样,即使某个节点或分片发生故障,数据仍然可以从其他副本分片中恢复。
  5. 确认写入成功
    一旦文档被主分片和副本分片写入成功,Elasticsearch会向客户端发送写入成功的响应。这个确认过程确保了数据的一致性和可靠性。

在写入流程中,Elasticsearch还提供了一些可选的请求参数,如consistency,用于影响写入过程的一致性级别。例如,可以设置consistencyone(只要主分片状态良好就允许执行写操作),all(必须主分片和所有副本分片状态良好才允许执行写操作),或quorum(大多数的分片副本状态良好就允许执行写操作)。默认值为quorum

4.3基于集群的search流程

  1. 发送搜索请求
    客户端向Elasticsearch集群发送搜索请求。这个请求可以包含各种搜索参数,如查询字符串、过滤条件、分页信息等。
  2. 请求路由
    Elasticsearch集群中的任何节点都可以接受搜索请求。一旦接收到请求,该节点会将其转发给协调节点(coordinating node)。协调节点负责整个搜索过程的协调和管理。
  3. 分片选择
    协调节点根据搜索请求中的索引和类型信息,确定需要搜索的分片。它可能会涉及多个主分片或副本分片,具体取决于搜索请求的配置和集群的状态。
  4. 执行搜索
    每个被选中的分片在本地执行搜索操作。它们会根据搜索请求中的查询条件,在本地索引中查找匹配的文档。这个过程可能涉及倒排索引的查找、评分计算等。
  5. 结果合并
    每个分片搜索完成后,会将结果返回给协调节点。协调节点会合并所有分片的结果,并根据搜索请求中的排序和分页要求进行排序和截取。
  6. 返回搜索结果
    协调节点将合并后的搜索结果返回给客户端。这个结果包含了符合条件的文档列表以及相关的元数据。

整个搜索流程是高度分布式的,利用了Elasticsearch集群的并行处理能力

4.4故障转移

Elasticsearch集群的故障转移是其分布式架构的重要特性之一,旨在确保在节点、分片或副本发生故障时,数据和状态能够自动转移到其他可用的节点或分片,从而保持服务的可用性和数据的完整性。

具体来说,当集群中的某个节点、分片或副本出现故障时,Elasticsearch会启动故障转移机制。这个过程主要通过使用Paxos算法和Raft算法来实现。Paxos算法用于确保在多个节点之间进行数据同步,保证分布式一致性;而Raft算法则用于在故障发生时进行故障转移,确保数据的可用性和容错性。

在Elasticsearch集群中,每个分片都可能有多个副本,这些副本分布在不同的节点上,用于提高数据的可用性和容错性。当主分片或主节点出现故障时,Elasticsearch会从副本中选择一个作为新的主分片或主节点,从而确保服务的连续性和数据的完整性。

4.5脑裂问题

Elasticsearch集群的脑裂问题是指在一个集群中,由于网络问题或其他原因导致不同节点对集群的状态有不同的理解,进而出现数据不一致和操作混乱的情况。具体来说,当集群中的节点失联时,可能会发生重新选主的情况,导致出现多个主节点和不同的数据状态,最终引发脑裂。

脑裂问题可能导致一系列不良后果。首先,集群的状态会变得不一致,使得查询和写入操作可能返回错误的结果或失败。其次,由于数据在不同节点之间可能不同步,可能导致数据丢失或损坏。最后,脑裂问题还可能影响集群的性能和稳定性,使得整个系统变得不可靠。

为了解决脑裂问题,Elasticsearch采取了一系列措施。其中,一个重要的策略是要求选票超过一定的阈值(通常是(eligible节点数量 + 1) / 2)才能当选为主节点。这样可以确保在出现网络分区时,只有拥有足够多支持的节点才能成为主节点,从而避免脑裂的发生。此外,Elasticsearch还提供了监控和告警功能,帮助管理员及时发现并处理潜在的脑裂问题。

4.6集群优化

  1. 集群配置优化
    • 节点类型:根据需求配置不同类型的节点,如主节点、数据节点、协调节点等。避免在主节点上执行数据操作,以保持其稳定性。
    • 分片:合理设置分片数。分片过多可能导致开销增加,而分片过少则可能导致单个节点过载。
    • 副本:根据数据的重要性和集群的可用性需求来设置合适的副本数。副本可以提高数据的可靠性和搜索性能,但也会增加存储和I/O开销。
  2. 索引优化
    • 映射:合理设计索引的映射,包括字段类型、属性和分析器等。这有助于提高索引效率和搜索准确性。
    • 合并策略:通过调整索引的合并策略来减少段的数量和大小,从而提高查询性能。
    • 刷新间隔:调整索引的刷新间隔以平衡实时性和性能。较短的刷新间隔可以提高实时性,但也会增加I/O开销。
  3. 查询优化
    • 复合查询:结合多个查询条件以减少搜索范围,从而提高搜索效率。
    • 分页:对于大量结果,使用分页来限制返回的文档数量,以减少网络传输和客户端处理的开销。
    • 缓存:利用Elasticsearch的查询结果缓存功能来提高重复查询的性能。
  4. 监控和日志
    • 使用Elasticsearch的监控工具(如Elasticsearch Monitoring、Kibana等)来实时监控集群的性能和健康状况。
    • 定期查看和分析日志以发现潜在的问题和瓶颈。
  5. 定期维护
    • 定期更新和重建索引以保持其性能。
    • 定期清理旧的、不再需要的数据以释放存储空间。
  6. 安全性
    • 确保Elasticsearch集群的安全性,包括使用HTTPS、身份验证和授权等机制来防止未经授权的访问和数据泄露。
  7. 备份与恢复
    • 定期备份Elasticsearch数据和配置,以防数据丢失或损坏。同时,确保在需要时能够快速恢复数据。

五、java客户端

由于现在java一般都是整合springboot开发,所以我们直接学习spring-data-elasticsearch的api操作。

整合springboot可以看 从零开始的Elasticsearch学习-springboot整合Elasticsearch(非响应式)

从零开始的Elasticsearch学习-springboot整合Elasticsearch(响应式)

  • 46
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值