💖每天拿出20分钟,带你入门涨薪3k的ElasticSear

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

🌈往期回顾

    感谢阅读,希望能对你有所帮助,博文若有瑕疵请在评论区留言或在主页个人介绍中添加我私聊我,感谢每一位小伙伴不吝赐教。我是XiaoLin,既会写bug也会唱rap的男孩

    今天是特殊的一天,祝大家有情人的终成眷属,没情人的涨薪20k

一、ElasticSearch简介

1.1、什么是全文检索

    全文检索是计算机程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置。当用户查询时根据建立的索引查找,类似于通过字典的检索字表查字的过程。

    检索: 索(建立索引) 检:(检索索引)

    全文检索(Full-Text Retrieval(检索))以文本作为检索对象,找出含有指定词汇的文本。全面、准确和快速是衡量全文检索系统的关键指标。
    全文检索的特点:

  1. 只处理文本。
  2. 不处理语义。
  3. 搜索时英文不区分大小写。
  4. 结果列表有相关度排序。

1.2、什么是ElasticSearch

    ElasticSearch 简称ES ,是基于Apache Lucene构建的开源搜索引擎,是当前流行的企业级搜索引擎。Lucene本身就可以被认为迄今为止性能最好的一款开源搜索引擎工具包,但是lucene的API相对复杂,需要深厚的搜索理论。很难集成到实际的应用中去。但是ES是采用java语言编写,提供了简单易用的RestFul API,开发者可以使用其简单的RestFul API,开发相关的搜索功能,从而避免lucene的复杂性

1.3、ElasticSearch 的诞生

    多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。在他找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。

    直接基于Lucene工作会比较困难,所以Shay开始抽象Lucene代码以便Java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做“Compass”。

    后来Shay找到一份工作,这份工作处在高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是理所当然需要的。然后他决定重写Compass库使其成为一个独立的服务叫做Elasticsearch。

    第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过Elasticsearch将永远开源且对所有人可用。
    Shay的妻子依旧等待着她的食谱搜索……

1.4、ElasticSearch应用场景

    ES主要以轻量级JSON作为数据存储格式,这点与MongoDB有点类似。同时也支持地理位置查询 ,还方便地理位置和文本混合查询 。 以及在统计、日志类数据存储和分析、可视化这方面是引领者。国内外的使用场景为:

  1. 国外: Wikipedia(维基百科)使用ES提供全文搜索并高亮关键字、StackOverflow(IT问答网站)结合全文搜索与地理位置查询、Github使用Elasticsearch检索1300亿行的代码。
  2. 国内:百度(在云分析、网盟、预测、文库、钱包、风控等业务上都应用了ES,单集群每天导入30TB+数据, 总共每天60TB+)、新浪 、阿里巴巴、腾讯等公司均有对ES的使用。

二、ElasticSearch安装

2.1、环境准备

  1. centos7
  2. jdk(1.8以上)
  3. ElasticSearch6.8.0

2.2、下载ElasticSearch

    我们可以从官网下载ElasticSearch

wget http://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.0.tar.gz
复制代码

2.3、安装JDK

2.3.1、下载JDK

# 默认位置是 /usr/java/jdk1.8.0_171-amd64*/
rpm -ivh jdk-8u181-linux-x64.rpm
复制代码

2.3.2、配置环境变量

vim /etc/profile
复制代码

    在这个配置文件的末尾加入:

export JAVA_HOME=/usr/java/jdk1.8.0_171-amd64
export PATH=$PATH:$JAVA_HOME/bin
复制代码

2.3.3、重载系统配置

source /etc/profile
复制代码

2.4、ElasticSearch安装(Linux)

2.4.1、添加新的用户并且赋予权限

# 在linux系统中创建新的组
groupadd es

# 创建新的用户xialin并将es用户放入es组中
useradd xiaolin -g es 

# 修改es用户密码
passwd xiaolin

# 赋予权限(给xiaolin赋予/usr文件夹下所有权限)
chown -R xiaolin /usr
复制代码

2.4.2、解压

tar -zxvf elasticsearch-6.4.1.tar.gz
复制代码

2.4.3、了解目录结构

image-20210422101835207

  • bin 可执行的二进制文件的目录
  • config 配置文件的目录
  • lib 运行时依赖的库
  • logs 运行时日志文件
  • modules 运行时依赖的模块
  • plugins 可以安装官方以及第三方插件

2.4.4、启动服务

进入bin目录中启动ES服务

./elasticsearch
复制代码

image-20210422102014689

2.4.5、测试

默认web服务端口9200,真正的java端口(tcp端口)9300,任何身份都可以访问

# (curl相当于模拟浏览器,检测es是否安装成功且默认不允许远程链接)
curl http://localhost:9200
复制代码

image-20210422102134635

2.4.6、开启远程连接

注意:ES服务默认启动是受保护的,只允许本地客户端连接,如果想要通过远程客户端访问,必须开启远程连接

我们只需要

三、ElasticSearch基本概念

image-20200701163807755

3.1、接近实时(NRT Near Real Time )

    Elasticsearch是一个接近实时的搜索平台。这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒内)

3.2、索引

ElasticSearch操作流程

  1. 当ElasticSearch执行添加操作时,先将数据添加到索引中,然后根据指定好的分词器规则对text类型字段进行分词。
  2. 字段分词之后,会得到一系列词根,ElasticSearch将这些词根保存到一张倒排索引表中,这张表会建立词根与文档之间的关联关系。
  3. 当用户进行全文检索的时候,输入查询语句关键词语的时候,ElasticSearch会对这个关键词语进行分词,然后根据这些去匹配倒排索引表,如果这些分词与倒排索引表词根能够匹配,那么词根关联文档的id就是满足搜索条件的文档。
  4. ElasticSearch会将满足搜索的文档一个一个去查询,然后进行综合评分,排序后再返回。

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

3.3、类型

在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数 据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可 以为评论数据定义另一个类型。类型类似于关系型数据库中Table的概念。 不同的版本对索引的要求也不同。

版本 Type
5.x 支持多种 type
6.x 只能有一种 type
7.x 默认不再支持自定义索引类型(默认类型为:_doc)

3.4、映射

Mapping是ES中的一个很重要的内容,它类似于传统关系型数据中table的schema,用于定义一个索引(index)中的类型(type)的数据的结构。 在ES中,我们可以手动创建type(相当于table)和mapping(相关与schema),也可以采用默认创建方式。在默认配置下,ES可以根据插入的数据自动地创建type及其mapping。 mapping中主要包括字段名、字段数据类型和字段索引类型

3.5、文档

**一个文档是一个可被索引的基础信息单元,类似于表中的一条记录。**比如,你可以拥有某一个员工的文档,也可以拥有某个商品的一个文档。文档以采用了轻量级的数据交换格式JSON(Javascript Object Notation)来表示。

3.6、分片

一个索引可以存储超出单个节点硬件限制的大量数据。比如,一个具有 10 亿文档数据的索引占据 1TB 的磁盘空间,而任一节点都可能没有这样大的磁盘空间。或者单个节点处理搜索请求,响应太慢。为了解决这个问题,Elasticsearch 提供了将索引划分成多份的能力,每一份就称之为分片。当你创建一个索引的时候,你可以指定你想要的分片的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上。

分片很重要,主要有两方面的原因:

  1. 允许你水平分割 / 扩展你的内容容量。
  2. 允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。

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

3.6.1、分片原理

传统的数据库每个字段存储单个值,但这对全文检索并不够。文本字段中的每个单词需要被搜索,对数据库意味着需要单个字段有索引多值的能力。最好的支持是一个字段多个值需求的数据结构是倒排索引。

Elasticsearch 使用一种称为倒排索引的结构,它适用于快速的全文搜索。

见其名,知其意,有倒排索引,肯定会对应有正向索引。正向索引(forward index),反向索引(inverted index)更熟悉的名字是倒排索引。

3.6.2、正排索引

所谓的正向索引,就是搜索引擎会将待搜索的文件都对应一个文件 ID,搜索时将这个ID 和搜索关键字进行对应,形成 K-V 对,然后对关键字进行统计计数。

正排索引

但是互联网上收录在搜索引擎中的文档的数目是个天文数字,这样的索引结构根本无法满足实时返回排名结果的要求。于是倒排索引他来了!

3.6.3、倒排索引

倒排索引是把文件ID 对应到关键词的映射转换为关键词到文件ID 的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。

倒排索引

一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。例如,假设我们有两个文档,每个文档的 content 域包含如下内容:

  1. The quick brown fox jumped over the lazy dog
  2. Quick brown foxes leap over lazy dogs in summer

为了创建倒排索引,我们首先将每个文档的 content 域拆分成单独的 词(我们称它为 词条或 tokens ),创建一个包含所有不重复词条的排序列表,然后列出每个词条出现在哪个文档。

image-20210528193508693

现在,如果我们想搜索 quickbrown ,我们只需要查找包含每个词条的文档.

image-20210528193530543

两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单相似性算法,那么我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。

3.7、副本

在一个网络 / 云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch 允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。

复制分片之所以重要,有两个主要原因:

  1. 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。
  2. 扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。