java系统找不到指定文件怎么解决
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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~