Elasticsearch入门指南,介绍、安装、学习路线

前言:这篇文章可以对 Elasticsearch 有个快速、高效、和体验上的简单认识。但具体怎么应用到系统中,还需查阅更多资料去借鉴总结尝试。

SQL模糊查询

在了解Elasticsearch之前,如果让你做个文本搜索,你会怎么做?

  • 在常用的关系型数据库(SQL Server/MySql等),搜索通常使用SQL语言的 like 来进行模糊搜索,这种搜索是以文本(列)中是否“包含完整的目标关键词”的方式来匹配结果。

  • 另外在c#中,可以借助LINQ对内存中的数据集合进行查询,也是通过类似查找特定字段中的文本是否包含完整目标关键词的方式进行查询。

SQL模糊查询,可以应用在一些比较简单且数据量不大的场景中。这种搜索有两种限制,或缺点

  • 不能很好命中索引, where name like 'xxx%' 这种可以使用name字段上的索引,但是where name like '%xxx' 则不能用上索引。
  • 对于海量数据搜索,SQL语句查询响应时间远远超过用户能够接受的等待时间。

所以,在实际生成业务中,遇到高性能、高并发的查询场景(即需要在极短的时间内快速响应,以提高用户体验),就要用到搜索技术。而ES,就是答案。

衡量搜索引擎好坏的标准是搜索速度的快慢,以及搜索出来的内容的好坏。

什么是 Elasticsearch

Elasticsearch(以下简称ES)是一个开源的、支持分布式的搜索引擎(软件工具),用于解决海量数据高效搜索的问题。它使用JAVA开发,使用Lucene作为核心实现了索引和搜索功能,但是通过简单的Restful API隐藏了Lucene的复杂性,从而让全文搜索变得简单。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。

它自带一套完全Restful 风格的API系统,通过该API我们与ES进行交互。

核心特点和优势:

  1. 接近实时。
  2. 支持集群,去中心化。

虽然Elasticsearch主要用于搜索,但其本质还是还是一个存储系统,可以当成一个文档型数据库,一条数据在这里就是一个文档,用JSON作为文档结构,查询主要先通过内存查。

ES天生就是分布式的,它知道如何管理节点来提供高扩展和高可用。这意味着程序员并不需要关心这些内容。

这里有一份将Elasticsearch和关系型数据术语对照表:

ES 关系型数据库
Index
Document
Field
Mapping 表结构

ES 重要相关名词概念

Node(节点)、Cluster (集群)

ES是一个分布式搜索引擎,其本质是一个分布式数据库,支持多台计算机上的ES实例协同工作,这里面的某一台计算机上的某个ES实例,就可以称为一个Node(节点),所有的这些协同工作的实例,可以称为一个Cluster(集群)。

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

一个节点也是由一个名字来标识的,名字会在启动的时候赋予节点。一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做Elasticsearch的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做Elasticsearch的集群中。

在Elasticsearch中,可以通过以下方式(static)为实例指定集群的名称:

打开elasticsearch.yml文件,找到cluster.name参数并将其值改为所需的集群名称即可。例如:cluster.name: my_cluster

ES的配置文件介绍,参考:

https://www.elastic.co/guide/en/elasticsearch/reference/8.7/settings.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.7/important-settings.html#cluster-name

注意:最开始学习,哪能面面俱到,先整明白单节点集群的吧。别的再到时候看文档。

Index 索引

索引主要用来存储ES的数据。它包含一堆相似结构的文档数据,一个索引包含很多文档(相似或相同结构的文档)。

在一个文档中有多个Field,每个Field是一个数据字段。

ES中每个 Index 的名字必须是小写

文档类型(Type)旧版中,它相当于关系型数据库中的表的概念,一个索引(index)可以有多个文档类型(Type),例如商品index有多个Type:电子商品Type、生鲜商品Type,每个Type下的文档的 Field可能不一样。

Elastic 6.x 之前每个index可多个type,但6.x版只允许每个 Index 包含一个 Type,7.x 版开始已彻底移除 Type。

document 文档(_doc)

Index 里面单条的记录称为 Document(文档)。许多条 Document 构成了一个 Index。

Document 使用 JSON 结构表示,下面是一个例子。

{
"user": "张三",
"title": "工程师",
"desc": "数据库管理"
}

同一个 Index 里面的 Document,不要求有相同的结构(scheme),但是最好保持相同,这样有利于提高搜索效率。

在版本7.0中已经没有文档了,统一为“_doc”。

mapping 映射

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

shards(主分片)、replicas (副本或复制分片)

shard 分为 primary shard 和 replica shard。前者一般呗成为 Shard,后者一般被称为 Replica。

一个索引理论上可以存储超出单个节点硬件限制的大量数据。比如,一个具有10亿文档的索引占据1TB的磁盘空间,而任一节点都没有这样大的磁盘空间;或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片。

分片(shard )

单台机器无法存储大量数据,可以将一个索引中的数据切分为多个分片,这些分片分布在多台服务器上。有了分片就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,从而提升吞吐量和性能。每个分片都是一个 Lucene Lndex。

副本(replica )

任何一个服务器随时可能出现故障或宕机,此时分片可能会丢失,因此可以为每个分片创建多个副本。副本可以在分片出现故障时提供备用服务,保证数据不丢失。多个副本一起使用,可以提升搜索操作的吞吐量和性能。

ES中分片与索引的关系

  • 分片是最小级别的工作单元,它只保存了索引中所有数据的一部分。
  • 所有的文档均存在分片中,而直接与应用程序进行交互的时索引。

至于一个分片怎样分布,它的文档怎样聚合回搜索请求,是完全由Elasticsearch管理的,对于作为用户的你来说,这些都是透明的。

在索引创建之后,你可以在任何时候动态地改变复制分片(replica)的数量,但是你事后不能改变你分片(shard)的数量。

在7.0.0版本之前默认情况下,Elasticsearch中的每个索引被分片5个主分片和1个复制,这意味着,如果你的集群中至少有两个节点,你的索引将会有5个主分片和另外5个复制分片,这样的话每个索引总共就有10个分片。
注意:在7.0.0版本之后默认只有1个分片

ES为什么能搜索和存储海量数据呢?

是因为它的水平拓展,它内部分将整个数据进行分片,每个分片存储部分数据。

img

如图:将整个数据分为5片,每一片都有一个副本,5个主分片分别存储在不同节点。每个节点就是一个ElasticSearch实例。

倒排索引:ES高效搜索的关键

正排索引可以简单理解为一种映射关系,即文档ID与若干关键词的映射;每次搜索,找出这些关键词对应的ID,然后根据某种“打分算法”对文档打分,最后依据打分排名将结果展示给用户。

倒排索引是指依照关键词查找文档:用关键词作为索引的key,每个关键词的倒排索引的值是一个列表,这个列表的元素就是包含这个“关键词→文档ID列表”的关系。

注意:倒排索引的写入和更新性能都比较差,因此它只适合进行全文搜索,不适合用来更新频繁变化的数据。

性能利器:Filesystem Cache

向ES中写入的数据,最终都存储在磁盘文件中。

在查询数据时,ES主要依赖底层的 Filesystem Cache,即先通过任意一个分片 Shard 在FileSystem Cache中查找数据,如果查到则直接返回;否则查询磁盘文件并将数据缓存到 Filesystem Cache 中,然后将其返回。

所以性能的关键在于 Filesystem Cache能缓存多少数据,即性能由内存决定。想要搜索性能好,需要将服务器的内存配置的大一些,确保有足够多的数据能被缓存(至少能容纳数据的一半)。建议在ES中只存储用来搜索的索引数据。其它字段存储在MySQL或Hbase中。

ES的安装

总体流程为:

  1. 下载安装 ES ,并设为后台服务,且开机自启动。
  2. 下载安装 分词插件,比如中文分词器。
  3. 下载安装 Kibana,用于数据可视化或者一些命令执行。最好也配置为自启动的服务。

ES的配置文件介绍,参考:

https://www.elastic.co/guide/en/elasticsearch/reference/8.7/settings.html

下载安装

ES安装包下载地址:https://www.elastic.co/cn/downloads/elasticsearch

ES安装官方教程:https://www.elastic.co/guide/en/elasticsearch/reference/current/zip-windows.html

Kibana(数据的可视化管理与数据分析站点服务)安装包下载地址:https://www.elastic.co/cn/downloads/kibana?elektra=stack-and-cloud-8-6-blog

注意:

  • elasticsearch 和 Kibana ,都是后台任务运行的(Windows上已服务的形式)。
  • 8.x版本已不需要额外配置java运行环境。

下载解压后,在 config/elasticsearch.yml 文件中修改两项配置为false(默认是true):

# Enable security features
xpack.security.enabled: false
xpack.security.enrollment.enabled: false

在bin目录进入cmd界面,

输入elasticsearch-service.bat install 安装为服务,Install Elasticsearch as a service。

然后输入 elasticsearch-service.bat start 启动服务。进入服务列表,确定已设置服务启动类型为“自动”。

启动成功后,在浏览器窗口,打开: http://localhost:9200/ ,页面显示一个json对象内容,为正常。

关于cmd的一些命令:

image-20230410225508351

详见:https://www.elastic.co/guide/en/elasticsearch/reference/current/zip-windows.html

下面这个待测试:

Elasticsearch默认是不允许跨域访问的,因此还需要给Elasticsearch的添加可跨域访问的配置。

打开Elasticsearch的config目录下的elasticsearch.yml文件,在结尾处添加如下配置并保存文件:

http.cors.enabled: true
http.cors.allow-origin: "*"
ingest.geoip.downloader.enabled: false

ES的可视化 kibana

注意要和ES的版本一致。

参考文档:Kibana 用户手册 | Elastic

下载解压后打开config文件夹下的kibana.yml文件 增加以下配置

img

下载解压缩后,进入bin文件夹,打开cmd界面:

输入 :kibana 启动服务。

浏览器窗口打开: http://localhost:5601 //可能得等一会儿,因为那个服务启动要一些时间。

注意启动后该cmd界面若关闭,则页面不可访问,所以要把它设置成服务??。

数据的创建和查询

在安装好ES后,就可以创建或查询数据了,可以通过Kibana 的DevTools页面,也可以通过postman工具或别的语言,来通过http访问es的相关接口。

可参考: https://www.elastic.co/guide/en/welcome-to-elastic/current/getting-started-general-purpose.html

更多关于搜索的文档,在这里:https://www.elastic.co/guide/en/enterprise-search/8.7/index.html

分词器的下载安装

分词器下载地址:

中文分词器:medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary. (github.com)

拼音分词器:medcl/elasticsearch-analysis-pinyin: This Pinyin Analysis plugin is used to do conversion between Chinese characters and Pinyin. (github.com)

//这两个相关release下载,可以检验你的GitHub网络访问情况,龟速还是流畅。

根据文档描述,进行解压安装后,重启ES即可。

具体语法演示

以 8.7.0 版本举例。以下在 kibana 8.7 控制台中运行

新建index

# Click the Variables button, above, to create your own variables.
# 创建index,index名必须小写
PUT /test_saying
{
/*创建一个索引,名为:test_saying,设置3个主分片分开存储数据,每个主分片包含一个副本分片。即共计6个分片。*/
"settings":{
"number_of_shards":3,
"number_of_replicas":1
},
/*定义数据结构*/
"mappings":{
"properties":{
"Id":{
"type":"integer"
},
"UserId":{
"type":"integer"
},
"SortNumber":{
"type":"integer",
/*设置该field不被索引,因为field是默认被索引*/
"no_index": true
},
"IsPublic":{
"type":"boolean"
},
"MainContent":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
},
"Source":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
},
"Tag":{
"type":"text",
"analyzer":"ik_max_word",
"search_analyzer":"ik_max_word"
}
}
}
}

往index里插入一条或多条文档数据

#这个URL后面得带上ID才行,旧版本不需要带
POST /test_saying/_create/1
{
"Id":1,"UserID":2,"SortNumber":0,"IsPublic":true,"MainContent":"如果我是DJ,你会爱我吗?","Source":"","Tag":"句子迷"
}
#批量插入数据
POST /test_saying/_bulk
{ "create":{ } }
{"Id":2,"UserID":2,"SortNumber":0,"IsPublic":true,"MainContent":"hello Jack,你会爱我吗?","Source":"","Tag":"正能量"}
{ "create":{ } }
{"Id":3,"UserID":2,"SortNumber":9,"IsPublic":false,"MainContent":"你吃过了吗?","Source":"","Tag":"正能量"}
{ "create":{ } }
{"Id":4,"UserID":2,"SortNumber":1,"IsPublic":true,"MainContent":"DJ,放上一首歌。","Source":"","Tag":"句子迷"}

注意,多条数据插入,有个别的更好的方式参考下:

Want to index some of your own data? You can upload data from a CSV, TSV, JSON file or use Elastic integrations to collect data from popular services and platforms like Nginx, AWS, and MongoDB. To check what’s available, select Add integrations on the Kibana home page.

查找数据

#查找数据
GET /test_saying/_search?pretty
{
"query": {"match": {
"MainContent": "DJ"
}}
}

ES使用建议

对于使用Elasticsearch进行索引时需要注意:

  • 不需要索引的字段,一定要明确定义出来,因为默认是自动建索引的
  • 同样的道理,对于String类型的字段,不需要analysis的也需要明确定义出来,因为默认也是会analysis的

ES的后续学习精进

比的就是官方文档了解的多少。人家规矩和注意事项都写好了,就看你有没有空去看,去尝试了。

配置方面:https://www.elastic.co/guide/en/elasticsearch/reference/8.7/settings.html

Q & A

怎么把ES应用到项目中?

比如一个技术博客网站,博客数据主要放在MySQL中,那么怎么放到ES,放那些?

每次查询,只走ES不需要MySQL或其它缓存配合吗?查询结果分页和排序怎么做??

有了Redis还需要用ES吗?

??Redis不也支持海量数据存储吗,不也读写性能杠杠的吗?

有没有相关性搜索的解决方案?

比如用户在新闻列表页的搜索框输入“少女时代”,对新闻进行搜索,那么匹配到不仅完整包含“少女时代”这四个字的新闻,还包含同时出现“少女” 和“时代”但在文中分散出现这样的。

ES 配置相关?

本机同时仅添加配置(cluster.name、node.name)后ES服务启动不了,不知道为啥??

win11安装ES8.x后,有个 java.exe一直占用较多可用内存,咋整。

这导致机器CPU内存占用率一直在90%以上,这个java.exe占用了5G以上的内存,本机内存16G,看着很不舒服。

这个不用担心,这个东西是根据启动时机器内存情况动态变化的。控制的话,是可以通过在elasticsearch-8.7.0\config\jvm.options.d 文件夹里添加 jvm.options 文件来控制,里面加上两行配置信息即可:

-Xms512m
-Xmx512m

服务器启动es服务的时候,ES会自动根据当前服务器内存情况配置JVM内存大小。

参考:https://www.elastic.co/guide/en/elasticsearch/reference/8.7/advanced-configuration.html#set-jvm-options

还是说,ES往往就是单独占用若干台服务器,即这些服务器主要就是用来提供搜索服务的,这些服务器上不用瞎担心这个情况。??

ES存储的数据字段,支持哪些类型。

long、integer、text、boolean、date等等

参见:https://www.elastic.co/guide/en/elasticsearch/reference/8.7/mapping-types.html

中文分词器,怎么用?

ik 那个,文档还没怎么看。

ES中的数据,是只要存搜索相关的字段?

实际场景中是先到ES搜索出结果(ID和相应字段),然后到缓存或其它关系型数据库中,根据ID获取各个数据详细信息??

如果想要排序,是不是还得放排序相关字段??应该是的。


怎么在本机开启多个ES节点,以便在本机进行集群测试?

一台服务器即本机上,怎么运行多个节点,并配置到同一集群?还是说开发阶段这个需求并不常见或不合理?

对于海量数据搜索,SQL语句查询响应时间远远超过用户能够接受的等待时间。

这个实际检验下,写个方法,往一个测试表里添加8千万条数据,然后SQLlike查询,看下执行时间。


更新于:2023-5-16

posted @   AI大胜  阅读(307)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示