搜索引擎Elasticsearch简介实践

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 之前在寻找日志收集搜索解决方案时,最常看到的便是 ELK

前言

之前在寻找日志收集搜索解决方案时,最常看到的便是 ELK:Elasticsearch + Logstash + Kibana 方案。尽管由于它对服务器资源要求很高转而使用 了 Loki,但也对它初步研究过。今天,就对其中的 Elasticsearch 深入了解一番。

Elasticsearch 介绍

Elasticsearch 是一个开源的搜索引擎,我们可以用它来处理文本、地理空间(如坐标)、结构化(如 DB 里的表)、非结构化(如报表、图片)等数据,然后通过简单的 REST API 对其搜索。它的最大特点就在于分布式以及实时速度,可部署到数百甚至上千台服务器上,以便我们存储处理海量的数据,而且其速度仍然能达到秒级。

它的底层使用的是 Apache Lucene。Apache Lucene 是一个高性能、功能强大的搜索引擎库,不过它只是一个库,需要使用 Java 才能集成到应用程序中。因此,Elasticsearch 对其进行了封装,屏蔽了底层的复杂性,对外只提供了简单的 RESTful API。

当 Elasticsearch 接收到像 Logstash 这种工具传输过来的数据后便会以文档的形式去分析提取索引,压缩数据,按配置的分片规则将数据均匀存储。在完成这些后,我们就可以进行可视化查询了,例如使用 Kibana 面板查看。

由于 Elasticsearch 具备了易用性、实时分析、全文搜索、分布部署、高可用等特性,所以除了用来做日志的处理分析外,还可以应用在安全分析、指标分析、性能监控等场景需求。

Elasticsearch 基本概念

文档(Document)

和传统的 DB 不一样,Elasticsearch 不是将数据存储为列式的二维表,而是
采用 Json 格式存储每一条数据,即文档是以键值对存在的字段集合。如下就可以是一条文档:

{
    "name":         "John Smith",
    "age":          42
}

我们也可以把文档理解为根对象,每条文档都会由唯一 \_id 标识它,如果我们在插入文档时没有指定 \_id,则 Elasticsearch 将会自动生成一个。

索引(Index)

Elasticsearch 之所以能进行实时搜索,最重要的就在于拿到文档数据后会对 json 里的所有字段建立索引,而且根据字段的不同类型建立不同的索引数据结构,例如 text 类型的字段会建立倒排索引,而数字和地理类型的字段会存储在 BKD 树里。这里重点介绍下倒排索引。

有倒排就有正排,我们先来看看正排索引,所谓的正排,我们可以简单的认为直接根据文档 \_id 获取到文档内容,只要你知道文档 \_id。

文档 \_id 文档内容
1 Elasticsearch 简介
2 Elasticsearch 实践

而倒排索引就不一样了,它会根据字段的内容进行分词提取出多个单词,然后根据单词建立起和文档 \_id 的关联关系。后续就可以通过单词 -> 文档 \_id -> 文档内容来搜索了。

单词 文档 \_id
Elasticsearch 1, 2
简介 1
实践 2

实际上像上述表格的第一列里的单词被称之为 term,而第二列被称之为 Posting List。在 Elasticsearch 里会对 term 进行优化以便快速寻找,同时还会其进行压缩,以减少存储空间。

映射类型(Mapping Types)

当文档被创建时,每个文档都会存储在一个单独的索引中,并且配以一个映射类型,以表示其文档类型,例如 twitter 索引可拥有 user 类型和 tweet 类型。

每个映射类型都可以有自己的字段,例如 user 类型可以有一个 full_name 、user_name、email 字段,而 tweet 类型可以有 content 、user_name、tweeted_at 字段。

实际上,user_name 字段在这两个映射类型里是共用存储的,这意味着,这个字段只能以一种数据类型而存在。如果我们想让 user 类型的 user_name 是 string 类型,想让
tweet 类型的 user_name 是 boolean 类型,是办不到的。

而且映射类型多了还会导致数据稀疏干扰 Lucene 的压缩文档能力。因此在 Elasticsearch 6.x 版本里只允许一个索引包含一个映射类型,在 7.x 版本里映射类型的概念则已被移除,变成 _doc 固定类型。

集群(Cluster)、节点(Node)

一个 ElasticSearch 实例称之为节点,当有多个实例节点一起协同工作时便称之为集群

分片(Shard)

ElasticSearch 处理的数据是非常大的,为了减少单个实例的压力,会将数据均衡的存储在各个节点上,而一个分片就是一个底层的工作单元,它保存了全部数据中的一部分。当我们集群扩容或缩小时,Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。

一个分片可以是主分片或者是副本分片,副本分片其实就是主分片的拷贝,即所谓的冗余备份,防止硬件故障数据丢失。

ElasticSearch 安装

使用 docker 安装将非常简单,我们只需要拉取镜像:

docker pull elasticsearch:7.2.0

然后启动:

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

验证是否安装成功:

curl http://localhost:9200

ElasticSearch 使用

ElasticSearch 提供了友好的 API 接口供外部使用。所以,当我们想往 ElasticSearch 输入数据、搜索数据便可以通过 HTTP + JSON 的方式进行。甚至我们可以直接使用 curl 命令来和 ElasticSearch 交互,例如统计文档数量:

curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'

在接收到请求,Elasticsearch 处理完成后将会返回一个 HTTP 状态码(例如:200 OK)和一个 JSON 格式的返回值,例如:

{
    "count" : 0,
    "_shards" : {
        "total" : 5,
        "successful" : 5,
        "failed" : 0
    }
}

为了书写方面,后面的请求将以简略形式呈现,不再描述所有相同的部分:主机名、端口号以及 curl 命令本身。例如以下简略格式:

GET /_count
{
    "query": {
        "match_all": {}
    }
}

事实上,如果我们使用 kibana 的控制面板,就会发现它就是这么要求命令输入的。另外,ElasticSearch 的版本有很多,有的版本差异将非常大,下面的使用都是是针对 7.20 版本的,请知悉。

创建

文档的创建需要指定三个元数据:\_index(文档的归集所在)、\_type(文档的归类)、\_id(文档的唯一标识)。其中,\_index 是一个逻辑上的命名空间,表示具有相同特性的文档集合,这个集合将会根据所有字段进行优化索引,在底层存储上则会被分发处理。

需要注意的是,由于 7.x 版本后的 _type 已经固定为 _doc 了,所以如果我们想要创建文档的话,可以这么发送命令:

POST my-index-000001/_doc/
{
  "@timestamp": "2099-11-15T13:12:00",
  "message": "GET /search HTTP/1.1 200 1070000",
  "user": {
    "id": "kimchy"
  }
}

此时,ElasticSearch 将会响应:

{
  "_shards": {
    "total": 2,
    "failed": 0,
    "successful": 2
  },
  "_index": "my-index-000001",
   "_type": "_doc",
  "_id": "W0tpsmIBdwcYyG50zbta",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "result": "created"
}

可以看到 ElasticSearch 将为我们自动生成了 _id 字段,如果我们的程序拥有自己的标识字段,那么可以自己定义 _id 的值:

PUT /my-index-000001/_doc/1
{
  "@timestamp": "2099-11-15T13:12:00",
  "message": "GET /search HTTP/1.1 200 1070000",
  "user": {
    "id": "kimchy"
  }
}

返回如下:

{
  "_shards": {
    "total": 2,
    "failed": 0,
    "successful": 2
  },
  "_index": "my-index-000001",
   "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "result": "created"
}

这样的话,如果我们知道文档 _id,那么就也这样获取数据了:

获取

GET /my-index-000001/_doc/1

将返回如下:

{
  "_index": "my-index-000001",
  "_type": "_doc",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "found": true,
  "_source": {
      "@timestamp": "2099-11-15T13:12:00",
      "message": "GET /search HTTP/1.1 200 1070000",
      "user": {
        "id": "kimchy"
      }
    }
}

搜索

当然,大多数时候我们是不知道文档 id 具体值的,所以我们得用下面 _search 来搜索:

GET /my-index-000001/_search?q=1.1

其中,q 表示查询任一字段包含 1.1 的记录。

如果我们想要更加功能丰富的查询,那么我们可以生成一个完整的 body 发送过去:

{
    "query": {
        "match" : {
            "message" : "1.1"
        }
    },
    "size": 2,
    "_source": [ "message", "user" ],
}

上面表示查询 2 条记录,并且只返回字段 messageuser

更新

如果我们想要更新文档的话,可以使用下面命令:

POST /<index>/_update/<_id>

删除

如果我们想要删除文档的话,可以使用下面命令:

DELETE /<index>/_doc/<_id>

关于更多 API 命令大伙可以查看下官方的 API :REST APIs

总结

优秀的开源框架总是能以友好的产品形态面向开发者,毫无疑问,Elasticsearch 就具备了这个特性。它屏蔽了底层复杂的逻辑概念,对外只暴露了简单易用的 API。让我们的程序能快速集成、快速应用,或许这就是一个开源框架被广泛使用的基操吧!

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
5月前
|
运维 监控 Java
探索Elasticsearch在Java环境下的全文检索应用实践
【6月更文挑战第30天】在大数据背景下,Elasticsearch作为分布式搜索分析引擎,因其扩展性和易用性备受青睐。本文指导在Java环境中集成Elasticsearch,涉及安装配置、使用RestHighLevelClient连接、索引与文档操作,如创建索引、插入文档及全文检索查询。此外,还讨论了高级查询、性能优化和故障排查,帮助开发者高效处理非结构化数据全文检索。
169 0
|
2月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
1月前
|
自然语言处理 搜索推荐 关系型数据库
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
这篇文章是关于Elasticsearch全文搜索引擎的学习指南,涵盖了基本概念、命令风格、索引操作、分词器使用,以及数据的增加、修改、删除和查询等操作。
20 0
elasticsearch学习六:学习 全文搜索引擎 elasticsearch的语法,使用kibana进行模拟测试(持续更新学习)
|
2月前
|
自然语言处理 搜索推荐 数据库
高性能分布式搜索引擎Elasticsearch详解
高性能分布式搜索引擎Elasticsearch详解
84 4
高性能分布式搜索引擎Elasticsearch详解
|
3月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
19145 21
|
1月前
|
开发框架 监控 搜索推荐
GoFly快速开发框架集成ZincSearch全文搜索引擎 - Elasticsearch轻量级替代为ZincSearch全文搜索引擎
本文介绍了在项目开发中使用ZincSearch作为全文搜索引擎的优势,包括其轻量级、易于安装和使用、资源占用低等特点,以及如何在GoFly快速开发框架中集成和使用ZincSearch,提供了详细的开发文档和实例代码,帮助开发者高效地实现搜索功能。
118 0
|
1月前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
49 0
|
1月前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
34 0
|
1月前
|
消息中间件 监控 关系型数据库
MySQL数据实时同步到Elasticsearch:技术深度解析与实践分享
在当今的数据驱动时代,实时数据同步成为许多应用系统的核心需求之一。MySQL作为关系型数据库的代表,以其强大的事务处理能力和数据完整性保障,广泛应用于各种业务场景中。然而,随着数据量的增长和查询复杂度的提升,单一依赖MySQL进行高效的数据检索和分析变得日益困难。这时,Elasticsearch(简称ES)以其卓越的搜索性能、灵活的数据模式以及强大的可扩展性,成为处理复杂查询需求的理想选择。本文将深入探讨MySQL数据实时同步到Elasticsearch的技术实现与最佳实践。
85 0
|
5月前
|
存储 监控 固态存储
elasticsearch索引生命周期管理(ILM):原理和实践
elasticsearch索引生命周期管理(ILM):原理和实践