后端 --- Elasticsearch学习笔记(入门篇)(一)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
日志服务 SLS,月写入数据量 50GB 1个月
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 后端 --- Elasticsearch学习笔记(入门篇)

什么是Elasticsearch

你知道的,为了搜索

首先,它是一个全文搜索和分析引擎,有以下三个特点。

  • 高度可扩展的
  • 开源的
  • 基于Lucene的

ELK的版本问题

现在所说的ELK其实就是Elastic Stack(官方称呼),包含ElasticSearch, logstash(服务器端的数据处理管道), kibana(ElasticSearch可视化)和beats(日志收集工具)。

这个网站可以查询所有有关ELK的历史版本https://www.elastic.co/cn/downloads/past-releases,当使用elk成员配合使用时,起码要保证大版本的统一,不能说使用的ElasticSearch是7.x版本的,而kibana却是6.x版本的,会产生版本不兼容问题。


环境搭建

安装 Elasticsearch

安装地址中选择你想要安装的版本,解压之后即可使用。

如果是集群形式的,可在 …\config\elasticsearch.yml中配置一些你的集群信息:

cluster.name: my-learn   # 集群名称
# path.data: /path/to/data       # ES数据存储路径
# path.logs: /path/to/logs       # ES日志存储路径
node.name: node-1              # 当前节点的名称
# network.host: 0.0.0.0          # 配置当前结点绑定的IP地址
http.port: 9200                # 设置对外服务的HTTP端口,默认为9200

运行Elasticsearch

Linux

./bin/elasticsearch

Windows

...\bin\elasticsearch.bat

当启动日志中出现starting …,标志后可以访问 http://localhost:9200/?pretty 。

{
  "name" : "LAPTOP-E0AJGK48",
  "cluster_name" : "my-application",
  "cluster_uuid" : "y5dYZ3tdQCqOuWeeSkkOhA",
  "version" : {
    "number" : "7.17.0",
    "build_flavor" : "default",
    "build_type" : "zip",
    "build_hash" : "bee86328705acaa9a6daede7140defd4d9ec56bd",
    "build_date" : "2022-01-28T08:36:04.875279988Z",
    "build_snapshot" : false,
    "lucene_version" : "8.11.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

当出现如上信息后则代表启动成功。

注意:在Elasticsearch v5.0版本之后需要JVAV8的环境。

安装Web界面(可视化处理)

为了方便我们使用,有两个可视化界面可供选择,elasticsearch-head和kibana。

安装elasticsearch-head插件

安装es-head插件需要有的依赖

  • node
  • 检查是否有node,在控制台输入node -v,如果有版本号弹出就是有了。
  • 没有的可以去下载,下载地址
  • 再次测试是否安装成功。
  • grunt
  • 在控制台中执行 npm install -g grunt -cli 等待安装成功即可。
  • 控制台输入:grunt -version 命令检查验证安装是否成功。

下载es-head

1.github下载:https://github.com/mobz/elasticsearch-head

2.百度云下载:https://pan.baidu.com/s/119GZF4E1NeEgctRxRp88Ng 提取码:oz9q


下载好后进行解压。

进入文件夹修改 Gruntfile.js

找到connect中添加hostname: ‘*’, 如下所示。

connect: {
    server: {
        options: {
            hostname: '*',
            port: 9100,
            base: '.',
            keepalive: true
        }
    }
}

接着在该文件下打开控制台,输入 npm install,等待安装完成。

接着输入 npm run start 启动es-head插件。

验证:http://localhost:9100/,如果发现无连接可能是

  • es 并未启动,启动即可。
  • es启动
  • 解决方法,在es文件中 …\config\elasticsearch.yml中添加以下配置:
http.cors.enabled: true        # 配置跨域资源共享
http.cors.allow-origin: "*"

安装kibana

下载地址中选择和你下载的es同一个版本的kibana。

解压后在…/config/kibana.yml文件中找到 elasticsearch.hosts: [“http://localhost:9200”],释放。

linux运行

./bin/kibana

windows

bin/kibana.bat
# 或是双击kibana.bat文件

验证,访问http://localhost:5601/app/dev_tools#/console出现如下界面,就代表成功了:

基本概念

了解基本概念有助于我们的进一步学习。

集群(Cluster)

集群(cluster)是一组具有相同cluster.name的节点集合,他们协同工作,共享数据并提供故障转移和扩展功能,当然一个节点也可以组成一个集群。

集群由唯一名称标识,默认情况下为“elasticsearch”。

但建议修改集群名称,使用默认名称可能会导致节点加入错误集群造成不必要的麻烦。

集群名称修改在 elasticsearch.yam 文件中,由 cluster.name 字段控制。

cluster.name: my-learn   # 集群名称

要确保不同的环境中使用不同的集群名称,否则最终会导致节点加入错误的集群。

集群的健康值

有三种状态,可以在es-head中查看。

也可以在kibana的控制台中使用 GET /_cluster/health 命令来查看状态。

{
  "cluster_name" : "my-learn",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 1,
  "number_of_data_nodes" : 1,
  "active_primary_shards" : 8,
  "active_shards" : 8,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}


绿色 - 一切都很好(集群功能齐全)。

黄色 - 所有数据均可用,但尚未分配一些副本(集群功能齐全)。

红色 - 某些数据由于某种原因不可用(集群部分功能)。

注意:当群集为红色时,它将继续提供来自可用分片的搜索请求,但您可能需要尽快修复它,因为存在未分配的分片。

节点(Node)

一个正在运行的ES实例就是一个节点,节点存储数据并参与集群的索引和搜索功能。

和集群一样,节点也是由名称进行标识的,默认的名称是随机分配的,这对管理项目以及查看日志非常的不利,所以尽量确定节点的名称。

建议给每个节点设置一个有意义的、清楚的、描述性的名字,同样也是在 elasticsearch.yml 中配置

node.name: elasticsearch_learn

可以将节点配置为按集群名称加入特定集群。默认情况下,每个节点都设置为加入一个名为 elasticsearch 的集群,这意味着如果您在网络上启动了许多节点并且假设它们可以相互发现 - 它们将自动形成并加入一个名为 elasticsearch 的集群。

索引(Index)

索引是具有某些类似特征的文档集合。例如,您可以拥有店铺数据的索引,商品的一个索引以及订单数据的一个索引。

类似于关系型数据库中的表。

索引由名称标识(必须全部小写),此名称用于在对其中的文档执行索引,搜索,更新和删除操作时引用索引。

类型(Type)

在v6.x及以上版本中已弃用。

是索引的逻辑类别/分区,允许您在同一索引中存储不同类型的文档,例如,一种类型用于用户,另一种类型用于博客帖子。

文档(Document)

文档是可以建立索引的基本信息单元。例如,您可以为单个客户提供文档,为单个产品提供一个文档,为单个订单提供一个文档。该文档以JSON(JavaScript Object Notation)格式表示。

类似于关系型数据库中的一行记录。

文档的元数据

es每一个文档,除了保存我们写入进行的文档原始数据外,也有文档自己的元数据,这些元数据,用于标识文档的相关信息。

下面是一个普通的es文档:

{
  "_index" : "test_logs2",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "uid" : 1,
    "username" : "test"
  }
}

从上面的文档中,我们可以看文档的元数据字段如下:

_index:文档所在索引名称

_source:原始json数据

_type:文档所属类型,es7.0以后只有为 _doc

_version:文档版本,如果对文档进行修改,则该字段会增加

_score:相关性打分

id:文档唯一id

分片(Shards)

索引存储量可能超过单个节点的硬件限制的数据量。例如,占用1TB磁盘空间的十亿个文档的单个索引可能不适合单个节点的磁盘,或者可能太慢而无法单独从单个节点提供搜索请求。

为了解决这个问题,Elasticsearch提供将索引细分为多个分布在不同的片区,这种功能被称之为分片,也是数据的最小单元块。

类似于关系型数据库的表分区概念。

设置分片的目的及原因主要是:

  • 它允许您水平拆分/缩放内容量
  • 它允许您跨分片(可能在多个节点上)分布和并行化操作,从而提高性能/吞吐量

分片的分布方式以及如何将其文档聚合回搜索请求的机制完全由 Elasticsearch 管理,对用户而言是透明的。也就是说用户在使用时是感觉不到分片的。

在可能随时发生故障的网络/云环境中,分片非常有用,建议使用故障转移机制,以防分片/节点以某种方式脱机或因任何原因消失。为此,Elasticsearch 允许您将索引的分片的一个或多个制作成所谓的副本分片或简称副本。


副本(Replicasedit)

副本,是对分片的复制。目的是为了当分片/节点发生故障时提供高可用性,它允许您扩展搜索量/吞吐量,因为可以在所有副本上并行执行搜索。

类似于关系型数据库中,担心一个表中数据量过大,新建了一个表。

总而言之,每个索引可以拆分为多个分片。索引也可以复制为零次(表示没有副本)或更多次。复制之后,每个索引将具有主分片(从原始分片复制而来的)和复制分片(主分片的副本)。

可以在创建索引时为每个索引定义分片和副本的数量。创建索引后,您也可以随时动态更改副本数。您可以使用_shrink 和 _splitAPI 更改现有索引的分片数,但这不是一项轻松的任务,所以预先计划正确数量的分片是最佳方法。

相同分片的副本不会放在同一节点。

副本是乘法,越多越浪费,但也越保险。分片是除法,分片越多,单分片数据就越少也越分散。

elasticsearch和关系型数据库的对比

关系型数据库 -> Tables(表) -> Rows(行) -> Columns(列)。

Elasticsearch -> Indeces(索引) -> Documents(文档) -> Fields(属性)。

由于elasticsearch中索引的特殊性,我们有必要将它做一个区分。

「索引」含义的区分

  • 索引(名词) 如上文所述,一个索引(index)就像是传统关系数据库中的数据库,它是相关文档存储的地方,index的复数是 indices 或 indexes。
  • 索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。
  • 倒排索引 传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。


交互

elasticsearch交互方式主要取决于你是否使用Java。

Java API

如果你正在使用 Java,在代码中你可以使用 Elasticsearch 内置的两个客户端:

  • 节点客户端(Node client)
    节点客户端作为一个非数据节点加入到本地集群中。换句话说,它本身不保存任何数据,但是它知道数据在集群中的哪个节点中,并且可以把请求转发到正确的节点。
  • 传输客户端(Transport client)
    轻量级的传输客户端可以将请求发送到远程集群。它本身不加入集群,但是它可以将请求转发到集群中的一个节点上。

两个 Java 客户端都是通过 9300 端口并使用 Elasticsearch 的原生 传输 协议和集群交互。集群中的节点通过端口 9300 彼此通信。如果这个端口没有打开,节点将无法形成一个集群。

更多的信息可以在Elasticserch客户端找到。

RESTful API with JSON over HTTP

除java外的语言可以使用RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。

curlcurl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'


curl的缩写格式

一个完整的curl请求为

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


curl的缩写格式就是省略请求中所有相同的部分,例如主机名、端口号以及 curl 命令本身。下面是他的缩写格式。

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


CRUD

可以在kibana控制台进行命令的执行操作。

插入文档信息

插入单条文档信息
PUT /learn/user/1
{
  "first_name" : "三",
  "last_name" :  "张",
  "age" :        25,
  "about" :      "法外狂徒",
  "interests": [ "偷盗", "抢劫","嘿嘿" ]
}


有关路径 /learn/user/1 包含了三部分信息:

  • learn 索引名称
  • user 类型名称
  • 1 ID

当出现如下信息时代表插入成功

{
  "_index" : "learn",
  "_type" : "user",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

在这里我们指定了文档的id,如果不指定id而是使用如下命令,那么es将会自动给其分配一个id。这个id是URL-safe、 基于 Base64 编码且长度为20个字符的 GUID 字符串,产生冲突的几率几乎为0。

POST /learn/user/
{
  "first_name" : "三",
  "last_name" :  "张",
  "age" :        25,
  "about" :      "法外狂徒",
  "interests": [ "偷盗", "抢劫","嘿嘿" ]
}

我又插入两条信息

PUT /learn/user/2
{
  "first_name" : "xk",
  "last_name" :  "蔡",
  "age" :        99,
  "about" :      "基尼太美",
  "interests": [ "唱", "跳","rap","篮球" ]
}
PUT /learn/user/3
{
  "first_name" : "倍",
  "last_name" :  "安",
  "age" :        10,
  "about" :      "散弹枪狂热者",
  "interests": [ "盗窃","篮球" ]
}

我们下面将讲到更改文档,如果使用PUT插入文档的话很容易造成文档的覆盖,这显然不是我们想要看到的。我们想要的是当文档不存在时再新增文档。有如下方法

# 新增文档但不更改,1
PUT /learn/user/5/_create
{
  "first_name" : "先森",
  "last_name" :  "双口",
  "age" :        10,
  "about" :      "散弹批发商",
  "interests": [ "嘿嘿","游戏" ]
}
# 新增文档但不更改,2
PUT /learn/user/6?op_type=create
{
  "first_name" : "先森",
  "last_name" :  "双口",
  "age" :        10,
  "about" :      "散弹批发商",
  "interests": [ "嘿嘿","游戏" ]
}

如果文档已近存在返回409状态码,如果成功添加返回201状态码。

更改文档信息

使用PUT请求

当一个文档已经存在是,再次使用PUT插入文档的方法就可以做到文档的更改。

PUT /learn/user/3
{
  "first_name" : "小日本鬼子",
  "last_name" :  "安",
  "age" :        10,
  "about" :      "散弹枪狂热者",
  "interests": [ "盗窃","篮球" ]
}

更改完成后version会改变。

在内部,Elasticsearch 已将旧文档标记为已删除,并增加一个全新的文档。 尽管你不能再对旧版本的文档进行访问,但它并不会立即消失。当继续索引更多的数据,Elasticsearch 会在后台清理这些已删除文档。

文档的部分更改

我们对文档进行更改时使用的是 update API。

文档是不可变的:他们不能被修改,只能被替换,所以我们对文档进行更改时其实时拿了个新的文档将老的文档给替换掉了

update 请求最简单的一种形式是接收文档的一部分作为 doc 的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段。

我们将user中的安倍的first_name改为鬼子就可以进行如下操作。

POST /learn/user/3/_update
{
   "doc" : {
      "first_name" : "鬼子"
   }
}

结果

{
  "_index" : "learn",
  "_type" : "user",
  "_id" : "3",
  "_version" : 4,
  "_seq_no" : 21,
  "_primary_term" : 2,
  "found" : true,
  "_source" : {
    "first_name" : "鬼子",
    "last_name" : "安",
    "age" : 10,
    "about" : "散弹枪狂热者",
    "interests" : [
      "盗窃",
      "篮球"
    ]
  }
}

我们也可以使用脚本对部分文档进行更新。

脚本可以在 update API中用来改变 _source 的字段内容, 它在更新脚本中称为 ctx._source

下面使用脚本对安鬼子的年龄进行修改。

POST /learn/user/3/_update
{
   "script" : "ctx._source.age=0"
}

结果

{
  "_index" : "learn",
  "_type" : "user",
  "_id" : "3",
  "_version" : 5,
  "_seq_no" : 22,
  "_primary_term" : 2,
  "found" : true,
  "_source" : {
    "first_name" : "鬼子",
    "last_name" : "安",
    "age" : 0,
    "about" : "散弹枪狂热者",
    "interests" : [
      "盗窃",
      "篮球"
    ]
  }
}




相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
存储 Java API
Elasticsearch 7.8.0从入门到精通
这篇文章详细介绍了Elasticsearch 7.8.0的安装、核心概念(如正排索引和倒排索引)、RESTful风格、各种索引和文档操作、条件查询、聚合查询以及在Spring Boot中整合Elasticsearch的步骤和示例。
153 1
Elasticsearch 7.8.0从入门到精通
|
3月前
|
数据可视化 Java Windows
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
本文介绍了如何在Windows环境下安装Elasticsearch(ES)、Elasticsearch Head可视化插件和Kibana,以及如何配置ES的跨域问题,确保Kibana能够连接到ES集群,并提供了安装过程中可能遇到的问题及其解决方案。
Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client
|
3月前
|
存储 关系型数据库 MySQL
浅谈Elasticsearch的入门与实践
本文主要围绕ES核心特性:分布式存储特性和分析检索能力,介绍了概念、原理与实践案例,希望让读者快速理解ES的核心特性与应用场景。
|
25天前
|
存储 JSON Java
ELK 圣经:Elasticsearch、Logstash、Kibana 从入门到精通
ELK是一套强大的日志管理和分析工具,广泛应用于日志监控、故障排查、业务分析等场景。本文档将详细介绍ELK的各个组件及其配置方法,帮助读者从零开始掌握ELK的使用。
|
2月前
|
缓存 架构师 数据库
后端开发的艺术:从入门到精通的旅程####
本文旨在探索后端开发的本质与魅力,通过一段段深入浅出的故事,串联起后端技术的精髓。不同于传统的技术总结,这里我们将以一位普通开发者的成长轨迹为线索,展现从初识编程到成为后端架构师的心路历程。每个阶段都伴随着挑战、学习与突破,最终揭示了技术背后的人文关怀与创新精神。 ####
|
1月前
|
监控 API 持续交付
后端开发中的微服务架构:从入门到精通
【10月更文挑战第26天】 在当今的软件开发领域,微服务架构已经成为了众多企业和开发者的首选。本文将深入探讨微服务架构的核心概念、优势以及实施过程中可能遇到的挑战。我们将从基础开始,逐步深入了解如何构建、部署和管理微服务。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和实用的建议。
42 0
|
2月前
|
JavaScript 前端开发
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
本文提供了一个Vue 3教程,讲解了如何使用axios库手动从后端获取数据,包括安装axios、配置后端访问地址、编写路由地址、发起HTTP请求以及在组件中读取和打印响应数据的步骤。
445 0
vue3教程,如何手动获取后端数据(入门到精通3,新人必学篇)
|
3月前
|
SQL JSON Java
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
本文为Spring Boot增删改查接口的小白入门教程,介绍了项目的构建、配置YML文件、代码编写(包括实体类、Mapper接口、Mapper.xml、Service和Controller)以及使用Postman进行接口测试的方法。同时提供了SQL代码和完整代码的下载链接。
springboot 如何编写增删改查后端接口,小白极速入门,附完整代码
|
2月前
|
Web App开发 JSON JavaScript
深入浅出:Node.js后端开发入门与实践
【10月更文挑战第4天】在这个数字信息爆炸的时代,了解如何构建一个高效、稳定的后端系统对于开发者来说至关重要。本文将引导你步入Node.js的世界,通过浅显易懂的语言和逐步深入的内容组织,让你不仅理解Node.js的基本概念,还能掌握如何使用它来构建一个简单的后端服务。从安装Node.js到实现一个“Hello World”程序,再到处理HTTP请求,文章将带你一步步走进Node.js的大门。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往后端开发新世界的大门。
|
3月前
|
前端开发 JavaScript Java
编程入门之前端和后端开发
前端开发就是开发网页上的内容展示与用户的交互,一部分后端开发工作就是开发数据访问服务,使前端可以通过后端服务对数据进行增删改查,也就是Crud,对前端用户的请求进行相应。
71 8