当前位置: 首页>后端>正文

Elasticsearch 入门到精通

1. 简介

Elasticsearch 是一个功能强大的分布式搜索和分析引擎,具备快速的数据处理能力、高可用性、灵活的扩展性和丰富的查询功能,广泛应用于日志分析、实时搜索、数据分析和监控等领域。通过其分布式架构和弹性扩展性,它可以应对大数据量和高查询速度的需求。

2. 安装和设置

2.1 Elasticsearch安装

2.2 Kinaba安装

3. 基本概念

3.1index索引

一个索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引,另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,可以定义任意多的索引。可类比mysql中表

3.2Filed字段

相当于是数据表的字段,对文档数据根据不同属性进行的分类标识 。

3.3映射mapping

mapping是处理数据的方式和规则方面做一些限制,如某个字段的数据类型、默认值、分析器、是否被索引等等,这些都是映射里面可以设置的,其它就是处理es里面数据的一些使用规则设置也叫做映射,按着最优规则处理数据对性能提高很大,因此才需要建立映射,并且需要思考如何建立映射才能对性能更好。相当于mysql中的创建表的过程,设置主键外键等等

3.4 document文档

一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档,某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以JSON(Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。在一个index/type里面,你可以存储任意多的文档。注意,尽管一个文档,物理上存在于一个索引之中,文档必须被索引/赋予一个索引的type。 插入索引库以文档为单位,类比与数据库中的一行数据

3.5 集群cluster

一个集群就是由一个或多个节点组织在一起,它们共同持有整个的数据,并一起提供索引和搜索功能。一个集群由 一个唯一的名字标识,这个名字默认就是“elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集 群的名字,来加入这个集群。

3.6 节点node

一个节点是集群中的一个服务器,作为集群的一部分,它存储数据,参与集群的索引和搜索功能。和集群类似,一 个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的 时候赋予节点。这个名字对于管理工作来说挺重要的,因为在这个管理过程中,你会去确定网络中的哪些服务器对 应于Elasticsearch集群中的哪些节点。
一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫 做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此, 它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。
在一个集群里,只要你想,可以拥有任意多个节点。而且,如果当前你的网络中没有运行任何Elasticsearch节点, 这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。

3.7分片和复制 shards&replicas

一个索引可以存储超出单个结点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。分片很重要,主要有两方面的原因: 1)允许你水平分割/扩展你的内容容量。 2)允许你在分片(潜在地,位于多个节点上)之上进行分布式的、并行的操作,进而提高性能/吞吐量。
至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。
在一个网络/云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片,或者直接叫复制。
复制之所以重要,有两个主要原因: 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。扩展你的搜索量/吞吐量,因为搜索可以在所有的复制上并行运行。总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和复制的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。
默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片(1个完全拷贝),这样的话每个索引总共就有10个分片。

4. 索引和查询数据

  • 展示如何创建索引和映射。
创建索引
#创建了名字为orders的index,类似于mysql的table
PUT /orders
{
  "mappings": {
    "properties": {
      "order_id": {
        "type": "keyword"
      },
      "customer_name": {
        "type": "text"
      },
      "order_date": {
        "type": "date"
      },
      "total_amount": {
        "type": "float"
      },
      "products": {
        "type": "nested",
        "properties": {
          "product_id": {
            "type": "keyword"
          },
          "product_name": {
            "type": "text"
          },
          "price": {
            "type": "float"
          }
        }
      }
    }
  }
}
创建文档
#创建了doc,类似于mysql的行数据
POST /orders/_doc
{
  "order_id": "123456789",
  "customer_name": "John Doe",
  "order_date": "2022-12-31T23:59:59",
  "total_amount": 199.99,
  "products": [
    {
      "product_id": "1",
      "product_name": "Product A",
      "price": 99.99
    },
    {
      "product_id": "2",
      "product_name": "Product B",
      "price": 100
    }
  ]
}
查询文档
GET /orders/_search
{
  "query": {
    "match_all": {}
  }
}

5. 高级搜索功能

5.1全文搜索、精确搜索、模糊搜索和通配符搜索

  1. 全文搜索:假设你希望在 "customer_name" 字段中执行全文搜索,找到包含关键词 "John Doe" 的订单。你可以使用 match 查询来完成:
{
  "query": {
    "match": {
      "customer_name": "John Doe"
    }
  }
}

这将返回所有 "customer_name" 字段中包含 "John" 或 "Doe" 单词的订单。

  1. 精确搜索:如果你希望根据订单的唯一标识符进行精确匹配搜索,可以使用 term 查询。以下是一个示例:
{
  "query": {
    "term": {
      "id": "123456789"
    }
  }
}

这将仅返回与订单标识符为 "123456789" 完全匹配的订单。

  1. 模糊搜索:假设你想要模糊搜索顾客姓名字段,以找到拼写类似于 "John Doe" 的订单。你可以使用 fuzzy 查询来实现:
{
  "query": {
    "fuzzy": {
      "customer_name": {
        "value": "John Doe",
        "fuzziness": "auto"
      }
    }
  }
}

这将返回与 "John Doe" 相近的顾客姓名,考虑到拼写的相似性。

  1. 通配符搜索:如果你想要搜索以 "J" 开头的顾客姓名的订单,可以使用通配符搜索。以下是一个示例:
{
  "query": {
    "wildcard": {
      "customer_name": "J*"
    }
  }
}

5.2 如何使用布尔查询、过滤器、聚合和排序来构建复杂的查询。

好的,让我们用 orders 这个示例来解释布尔查询、过滤器、聚合和排序的使用。

先增加properties和doc:

PUT /orders
{
  "mappings": {
    "properties": {
      "id": {"type": "keyword"},
      "customer_name": {"type": "text"},
      "status": {"type": "keyword"},
      "price": {"type": "float"},
      "order_date": {"type": "date"}
    }
  }
}
 
POST /orders/_bulk
{ "index": { "_id": "1" } }
{ "id": "123456789", "customer_name": "John Doe", "status": "pending", "price": 100.00, "order_date": "2022-02-15" }
{ "index": { "_id": "2" } }
{ "id": "987654321", "customer_name": "Jane Smith", "status": "shipped", "price": 50.00, "order_date": "2022-03-01" }
{ "index": { "_id": "3" } }
{ "id": "456789123", "customer_name": "Bob Johnson", "status": "cancelled", "price": 33.00, "order_date": "2022-02-01" }

首先,我们来创建一个 index 和一个包含一些订单的示例数据:

PUT /orders
{
  "mappings": {
    "properties": {
      "id": {"type": "keyword"},
      "customer_name": {"type": "text"},
      "status": {"type": "keyword"},
      "price": {"type": "float"},
      "order_date": {"type": "date"}
    }
  }
}
 
POST /orders/_bulk
{ "index": { "_id": "1" } }
{ "id": "123456789", "customer_name": "John Doe", "status": "pending", "price": 100.00, "order_date": "2022-02-15" }
{ "index": { "_id": "2" } }
{ "id": "987654321", "customer_name": "Jane Smith", "status": "shipped", "price": 50.00, "order_date": "2022-03-01" }
{ "index": { "_id": "3" } }
{ "id": "456789123", "customer_name": "Bob Johnson", "status": "cancelled", "price": 33.00, "order_date": "2022-02-01" }

现在,我们将使用以下示例查询、过滤器、聚合和排序对数据进行操作:

  1. 布尔查询:假设你想要查找价格在 Elasticsearch 入门到精通,20 到,第1张100 之间的处于 "pending" 状态的订单,也就是要执行一个 "must" 和 "must" 的布尔查询,用于组合多个条件以获取更精确的结果。以下是一个示例查询:
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "price": {
              "gte": 20,
              "lte": 100
            }
          }
        },
        {
          "match": {
            "status": "pending"
          }
        }
      ]
    }
  }
}

这将在满足价格在 Elasticsearch 入门到精通,20 到,第1张100,以及状态为 "pending" 的订单中搜索。

  1. 过滤器:假设你想要查找订单日期在 2022 年 2 月份的订单,也就是按照日期进行查询。这个时候我们可以用过滤器来实现:
{
  "query": {
    "bool": {
      "filter": {
        "range": {
          "order_date": {
            "gte": "2022-02-01",
            "lte": "2022-02-28"
          }
        }
      }
    }
  }
}

这将筛选出日期在 2022 年 2 月份的订单。

  1. 聚合:假设你想要按照顾客名字将订单分组,计算每个顾客的平均订单总价和最大订单总价。以下是一个示例聚合:
{
  "size": 0,
  "aggs": {
    "customer_orders": {
      "terms": {
        "field": "customer_name"
      },
      "aggs": {
        "avg_order_total": {
          "avg": {
            "field": "price"
          }
        },
        "max_order_total": {
          "max": {
            "field": "price"
          }
        }
      }
    }
  }
}

这将按顾客名称聚合订单,并计算每个顾客的平均和最大订单总价。

  1. 排序:假设你想要以价格降序对订单进行排序。你可以在查询中添加一个 "sort" 参数来实现:
{
  "query": {
    "match_all": {}
  },
  "sort": [
    { "price": { "order": "desc" } }
  ]
}

这将按价格降序排序所有订单。

可以看到,使用 Elasticsearch 的查询、过滤器、聚合和排序等功能可以构建复杂的查询,提高数据检索效率和准确性。这里仅提供了一些简单的示例,实际应用需要根据不同的场景和需求进行不

6. 搜索优化

6.1 - 介绍如何使用索引优化器和分析器来提升搜索的性能。

6.2 内存配置

当为 Elasticsearch 分配内存时,需要考虑多个因素,如数据量、索引结构、查询需求等。下面是根据不同场景建议的分配策略:

  1. 全文搜索场景:
  • 对于小规模或中等规模的索引(例如数百万条文档),建议将 Elasticsearch 堆内存分配为整个可用内存的 50% ~ 75%。这将允许 Elasticsearch 建立足够的缓存,以提供高效的索引和查询性能。在这种情况下,需要考虑避免存储过多的数据,以免触发 JVM 的 GC。

  • 对于大规模的索引(例如数千万条文档),由于内存资源有限,建议对 Elasticsearch 堆内存进行更小的配置(例如设置为整个可用内存的 25% ~ 50%)。此时,需要使用更多的硬盘 I/O 和操作系统缓存来补充内存不足的情况。对于此类场景,建议使用 SSD 以提高磁盘操作的性能。

  1. 聚合和排序场景:
  • 对于仅基于数字和日期字段的聚合和排序操作,可以将 Elasticsearch 堆内存设置为较小的值(例如 2GB ~ 4GB)。此时,需要留出一定的内存(例如 4GB ~ 8GB)用于操作系统缓存和 Lucene 的缓存。这将允许 Elasticsearch 建立足够的缓存,而无需使用过多的堆内存。

  • 对于同时处理数字、日期和文本字段的聚合和排序操作,建议将 Elasticsearch 堆内存扩大(例如 16GB ~ 32GB)。此时,需要留出一定的内存(例如 8GB ~ 16GB)用于操作系统缓存和 Lucene 的缓存。在这种情况下,需要注意堆内存的使用情况,并确保 Elasticsearch 不会触发 JVM 的 GC。

  1. 多租户场景:
  • 对于多租户场景,建议将 Elasticsearch 堆内存划分为多个分区,每个分区仅被单个租户使用。对于每个租户,可以根据其负载和实际需求进行不同的配置。例如,高负载的租户可以被分配更多的堆内存,而低负载的租户则可以被分配较少的堆内存。这种策略将允许 Elasticsearch 更好地隔离每个租户的资源,以保证系统的平稳运行。

7. 故障排除和监控

  • 提供一些故障排除的技巧和常见问题的解决方案。

  • 介绍如何使用监控工具来实时监测 Elasticsearch 集群的状态和性能。

8. 扩展 Elasticsearch

  • 解释如何使用集群、节点和索引级别的设置来扩展 Elasticsearch。

  • 介绍如何使用插件和自定义脚本来扩展 Elasticsearch 的功能。

9. 参考资料和进一步学习


https://www.xamrdz.com/backend/3et1944604.html

相关文章: