【ReactJs+springBoot项目——租房】第10章:Elasticsearch集群搭建+集群的故障转移+Java客户端的使用+Spring Data Elasticsearch

网友投稿 285 2022-09-12

【ReactJs+springBoot项目——租房】第10章:Elasticsearch集群搭建+集群的故障转移+Java客户端的使用+Spring Data Elasticsearch

了解倒排索引全文搜索API的使用Elasticsearch集群搭建集群中分片和副本集群的故障转移分布式文档Java客户端的使用Spring Data Elasticsearch

1、全文搜索

1.1、倒排索引

倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值 的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(inverted index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(inverted file)。

正排索引:

转化成倒排索引:

说明: “单词ID”一栏记录了每个单词的单词编号; 第二栏是对应的单词; 第三栏即每个单词对应的倒排列表; 比如单词“谷歌”,其单词编号为1,倒排列表为{1,2,3,4,5},说明文档集合中每个文档都包含了这个单词。 而事实上,索引系统还可以记录除此之外的更多信息,在单词对应的倒排列表中不仅记录了文档编号,还记载了单 词频率信息(TF),即这个单词在某个文档中的出现次数,之所以要记录这个信息,是因为词频信息在搜索结果排 序时,计算查询和文档相似度是很重要的一个计算因子,所以将其记录在倒排列表中,以方便后续排序时进行分值 计算。

倒排索引还可以记载更多的信息,除了记录文档编号和单词频率信息外,额外记载了两类信息,即每个单词对应 的“文档频率信息”,以及在倒排列表中记录单词在某个文档出现的位置信息。

1.2、全文搜索

全文搜索两个最重要的方面是:

相关性(Relevance) 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是 TF/IDF 方法、地理位置邻近、模糊相似,或其他的某些算法。

分析(Analysis) 它是将文本块转换为有区别的、规范化的 token 的一个过程,目的是为了创建倒排索引以及查询倒排索引。

1.2.1、构造数据

批量插入数据:

结果:

1.2.2、单词搜索

1.检查字段类型

爱好 hobby 字段是一个 text 类型( 指定了IK分词器),这意味着查询字符串本身也应该被分词。

2.分析查询字符串 。

将查询的字符串 “音乐” 传入IK分词器中,输出的结果是单个项 音乐。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。

3.查找匹配文档 。

用 term 查询在倒排索引中查找 “音乐” 然后获取一组包含该项的文档,本例的结果是文档:3 、5 。

4.为每个文档评分 。

用 term 查询计算每个文档相关度评分 _score ,这是种将 词频(term frequency,即词 “音乐” 在相关文档的hobby 字段中出现的频率)和 反向文档频率(inverse document frequency,即词 “音乐” 在所有文档的hobby 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。

1.2.3、多词搜索

结果:

可以看到,包含了“音乐”、“篮球”的数据都已经被搜索到了。

可是,搜索的结果并不符合我们的预期,因为我们想搜索的是既包含“音乐”又包含“篮球”的用户,显然结果返回的“或”的关系。

在Elasticsearch中,可以指定词之间的逻辑关系,如下:

结果:

可以看到结果符合预期。 前面我们测试了“OR” 和 “AND”搜索,这是两个极端,其实在实际场景中,并不会选取这2个极端,更有可能是选取这种,或者说,只需要符合一定的相似度就可以查询到数据,在Elasticsearch中也支持这样的查询,通过minimum_should_match来指定匹配度,如:70%; 示例:

相似度应该多少合适,需要在实际的需求中进行反复测试,才可得到合理的值。

1.2.4、组合搜索

在搜索时,也可以使用过滤器中讲过的bool组合查询,示例:

上面搜索的意思是:

搜索结果中必须包含篮球,不能包含音乐,如果包含了游泳,那么它的相似度更高。

结果:

评分的计算规则

bool 查询会为每个文档计算相关度评分 _score , 再将所有匹配的 must 和 should 语句的分数 _score 求和,最后除以 must 和 should 语句的总数。

must_not 语句不会影响评分; 它的作用只是将不相关的文档排除。默认情况下,should中的内容不是必须匹配的,如果查询语句中没有must,那么就会至少匹配其中一个。当然了,也可以通过minimum_should_match参数进行控制,该值可以是数字也可以的百分比。

示例:

minimum_should_match为2,意思是should中的三个词,至少要满足2个。结果:

1.2.5、权重

有些时候,我们可能需要对某些词增加权重来影响该条数据的得分。如下:

搜索关键字为“游泳篮球”,如果结果中包含了“音乐”权重为10,包含了“跑步”权重为2。

结果:

如果不设置权重的查询结果是这样:

1.3、短语匹配 在Elasticsearch中,短语匹配意味着不仅仅是词要匹配,并且词的顺序也要一致,如下:

结果:

结果符合预期。

如果觉得这样太过于苛刻,可以增加slop参数,允许跳过N个词进行匹配。示例:

结果:没有匹配到数据

设置跳过次数:

结果:

从结果中,可以看出已经跳过了“乒乓球”这个词。 2、Elasticsearch集群

2.1、集群节点 ELasticsearch的集群是由多个节点组成的,通过cluster.name设置集群名称,并且用于区分其它的集群,每个节 点通过node.name指定节点的名称。 在Elasticsearch中,节点的类型主要有4种: master节点 配置文件中node.master属性为true(默认为true),就有资格被选为master节点。 master节点用于控制整个集群的操作。比如创建或删除索引,管理其它非master节点等。data节点 配置文件中node.data属性为true(默认为true),就有资格被设置成data节点。 data节点主要用于执行数据相关的操作。比如文档的CRUD。 客户端节点

配置文件中node.master属性和node.data属性均为false。该节点不能作为master节点,也不能作为data节点。 可以作为客户端节点,用于响应用户的请求,把请求转发到其他节点部落节点 当一个节点配置tribe.*的时候,它是一个特殊的客户端,它可以连接多个集群,在所有连接的集群上执行搜索和其他操作。 2.2、使用docker搭建集群

查看集群:

创建索引:

查询集群状态:namespace)”.

一个分片(shard)是一个最小级别“工作单元(worker unit)”,它只是保存了索引中所有数据的一部分。

我们需要知道是分片就是一个Lucene实例,并且它本身就是一个完整的搜索引擎。应用程序不会和它直接通信。

分片可以是主分片(primary shard)或者是复制分片(replica shard)。

索引中的每个文档属于一个单独的主分片,所以主分片的数量决定了索引最多能存储多少数据。

复制分片只是主分片的一个副本,它可以防止硬件故障导致的数据丢失,同时可以提供读请求,比如搜索或 者从别的shard取回文档。

当索引创建完成的时候,主分片的数量就固定了,但是复制分片的数量可以随时调整。

2.4、故障转移

为了测试故障转移,需要再向集群中添加一个节点,并且将所有节点的node.master设置为true。

查看集群状态:(需要将之前创建haoke索引删除)

此时,node02为主节点。

创建haoke索引:

2.4.1、将node01停止

说明:

需要连接到node2的端口9201进行查看状态

当前集群状态为黄色,表示主节点可用,副本节点不完全可用

过一段时间观察,发现节点列表中看不到node01,副本节点分配到了node02和node03,集群状态恢复到绿色。

将node02恢复:

可以看到,node01恢复后,重新加入了集群,并且重新分配了节点信息。

2.4.2、将node02停止

接下来,测试将node02停止,也就是将主节点停止。

从结果中可以看出,集群对master进行了重新选举,选择node01为master。并且集群状态变成黄色。

集群状态从黄色变为了绿色。

恢复node02节点:

重启之后,发现node02加不到集群中了。这其实是集群中脑裂问题。

2.4.3、脑裂问题

解决方案: 思路:不能让节点很容易的变成master,必须有多个节点认可后才可以。设置minimum_master_nodes的大小为2 官方推荐:(N/2)+1,N为集群中节点数测试:(node02为主,一宕机)

node02恢复后,正常加入到了集群:

2.5、分布式文档

2.5.1、路由

首先,来看个问题:

如图所示:当我们想一个集群保存文档时,文档该存储到哪个节点呢? 是随机吗? 是轮询吗? 实际上,在ELasticsearch中,会采用计算的方式来确定存储到哪个节点,计算公式如下:

routing值是一个任意字符串,它默认是_id但也可以自定义。

这个routing字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余 数的范围永远是0到number_of_primary_shards - 1,这个数字就是特定文档所在的分片。

这就是为什么创建了主分片后,不能修改的原因。

2.5.2、文档的写操作

新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。

下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤:

2.5.3、搜索文档(单个文档)

文档能够从主分片或任意一个复制分片被检索。

下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤:

2.5.4、全文搜索

对于全文搜索而言,文档可能分散在各个节点上,那么在分布式的情况下,如何搜索文档呢? 搜索,分为2个阶段,搜索(query)+取回(fetch)。

搜索(query)

查询阶段包含以下三步:

取回(fetch)

分发阶段由以下步骤构成:

1.协调节点辨别出哪个document需要取回,并且向相关分片发出 GET 请求。

2.每个分片加载document并且根据需要丰富(enrich)它们,然后再将document返回协调节点。

3.一旦所有的document都被取回,协调节点会将结果返回给客户端。

3、Java客户端

在Elasticsearch中,为java提供了2种客户端,一种是REST风格的客户端,另一种是Java API的客户端。

​​Low Level REST Client:官方提供的低级客户端。该客户端通过返回的JSON数据手动封装成对象。虽然麻烦,不过该客户端兼容所有的Elasticsearch版本。

Java High Level REST Client:官方提供的高级客户端。该客户端基于低级客户端实现,它提供了很多便捷的API来解决低级客户端需要手动转换数据格式的问题。

3.2、构造数据

3.3、REST低级客户端

3.3.1、创建工程

创建工程itcast-elasticsearch:

3.3.2、编写测试用例

从使用中,可以看出,基本和我们使用RESTful api使用几乎是一致的。

3.4、REST高级客户端

3.4.1、引入依赖

3.4.2、编写测试用例

4、Spring Data ElasticsearchSpring Data项目对Elasticsearch做了支持,其目的就是简化对Elasticsearch的操作。地址:4.4.1、编写User对象

4.4.2、新增数据

运行效果:

4.4.3、批量插入数据

4.4.4、更新数据

4.4.5、删除数据

4.4.6、搜索

效果:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Taurus.MVC 2.2.3.4 :WebAPI 实现权限控制认证(及功能增强说明)
下一篇:【serverless与微服务】华为云函数工作流FunctionGraph
相关文章

 发表评论

暂时没有评论,来抢沙发吧~