zoukankan      html  css  js  c++  java
  • ElasticSearch 主脉

    全文检索:
    		全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,
    	当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。
    		全文检索的方法主要分为按字检索和按词检索两种。按字检索是指对于文章中的每一个字都建立索引,检索时将词分解为字的组合。
    	对于各种不同的语言而言,字有不同的含义,比如英文中的字与词实际上是合一的,而中文中的字与词有很大分别。
    	按词检索指对文章中的词,即语义单位建立索引,检索时按词检索,并且可以处理同义项等。
    	英文等西方文字由于按照空白切分词,因此实现上与按字处理类似,添加同义处理也很容易。
    	中文等东方文字则需要切分字词,以达到按词索引的目的,
    
    倒排索引:
    	正排索引:根据索引(id),找到文档。
    	倒排索引:根据索引(拆分的文档内容),找到文档对应的id,再根据对应的id找到目标文档。
    
    架构:
    	1、需要检索的text -> 分词 -> 构建索引。
    	2、用户输入 -> 分词 -> 根据1步构建的索引,查询符合条件的内容 -> rank(打分,业务相关) -> 显示结果。
    系统划分:
    	1、分词
    	2、rank打分
    	
    技术选型:
    	1、根据业务进行选型。
    	2、java常用的全文索引框架有:Lucene(根本)、Solr、Elasticsearch
    		2.1、Solr 实时性不强,大数据处理弱。
    			参考博文: https://blog.csdn.net/u010510107/article/details/81051795
    		2.2、Elasticsearch 实时性强,分布式,大数据处理。
    			参考博文: https://blog.csdn.net/llwy1428/article/details/89714709
    					   https://blog.csdn.net/JENREY/article/details/81290535#commentBox
    		2.3、solrElasticsearch对比:https://www.jianshu.com/p/132b8f1b66a7	
    		2.4、lucene: https://blog.csdn.net/JENREY/article/details/81004130	
    
    Elasticsearch 
    
    核心概念:
    	1、Near Realtime 近实时
    	2、cluster 集群,分布式	
    
    是什么(what)
    	基本概念:
    		1、index (数据库,分片的对象)
    		2、type  (表)
    		3、Document (行,记录)
    		4、Field (列)
    	分片:一台服务器,无法存储大量的数据,ES把一个index里面的数据,分为多个shard,分布式的存储在各个服务器上面。
    	副本:主从
    	
    	Field 类型:text 分词,keyword 不分词。 
    	
    	
    	在 Elasticsearch 中,是master-slave架构。节点是对等的,节点间会通过自己的一些规则选取集群的 Master,
    	Master 会负责集群状态信息的改变,并同步给其他节点。这样写入性能会不会很低???注意,只有建立索引和类型需要经过 Master,
    	数据的写入有一个简单的 Routing 规则,可以 Route 到集群中的任意节点,所以数据写入压力是分散在整个集群的。
    	
    	评分机制:TF-IDF(词频-逆文档频率)
    		词频:在文档中出现的频率越高,得分越高。
    		逆文档频率:在所有的文档中,出现的频率越低,得分越高。(物以稀为贵)		
    		
    
    怎么用(how)
    	1、业务需要,过滤朋友圈:(自定义过滤规则:https://www.jianshu.com/p/a0a168585e3d)	
    	
    	2、_mapping
    	
    	3、_search  https://www.elastic.co/guide/en/elasticsearch/reference/7.4/search-uri-request.html
    		q	查询字符串(映射到query_string查询)  									_search?q=fieldname:value
    		df	在查询中不指定字段是默认查询的字段,如果不指定字段,ES会查询所有字段  	_search?q=value&df=fieldname
    		analyzer	分析查询字符串时要使用的分析器名称
    		sort	排序,可以升序排序和降序排序     									_search?sort=fieldname:ase/desc
    		timeout	指定超时时间,默认为无超时
    		from	返回的索引匹配结果的开始值,默认为0
    		size	要返回的搜索条数,默认为10
    		default_operator	要使用的默认运算符可以是AND或 OR,默认为OR
    
    	4、整合 springboot elasticsearch 
    		4.1、多条件搜索:https://blog.csdn.net/Topdandan/article/details/81436141
    		https://docs.spring.io/spring-data/elasticsearch/docs/3.1.3.RELEASE/reference/html/
    		打印es dsl 语句:logging.level.org.springframework.data.elasticsearch.core = debug
    
    
    为什么(why)
    	重难点:
    		集群内部原理、分布式文档存储、执行分布式检索、分片内部原理。
    		
    	1、集群的内部原理
    		1、集群概览
    			集群是由多个拥有相同 cluster.name 的节点组合而成的。
    			master节点:负责管理集群范围内的所有变更,如:增加、删除索引;增加、删除节点等。
    						主节点不涉及文档级别的变更何搜索等操作,所以主节点不会成为性能瓶颈。
    			存数据时:客户端发送消息到集群中的任何节点,每个节点都知道任意文档所处的位置,并且能够将外面的请求直接转发到存储我们所需文档的节点中。
    			取数据时:无论哪个节点,都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回给客户端。
    		
    		2、集群健康:GET /_cluster/health
    			green: 所有主副分片都正常运行。
    			yellow:所有主分片正常运行,有些副分片不能正常运行。
    			red:有些主分片不能正常运行。
    		
    		3、添加索引
    			索引:保存相关数据,指向一个或者多个物理“分片”的逻辑命名空间。
    			分片:保存全部数据中的一部分,一个分片就是一个Lucene实例,是一个完整的搜索引擎。我们的文档被存储和索引到分片内。程序直接对接索引。
    			
    			es将数据分配到分片中,分片是数据的容器,文档保存在分片内,分片又被分配到集群的各个节点中去。当集群扩大或缩小时,es自动在节点中迁移分片,使得数据仍然均匀分布在集群里。
    			
    			一个分片可以是 主分片 或者 副本分片 。副本分片:主分片的数据拷贝,冗余备份,并为搜索和返回文档等读操作提供服务。
    			索引建立时,确定了主分片(不可更改),副分片可以随时更改。
    		
    		4、水平扩容
    			主分片数决定了写入的性能。主分片数量=节点数,就是写入的最大性能点。
    			副本分片数决定了读的性能。越多的副本分片,读性能越好。(但是副本的同步需要消耗资源)
    			
    		5、故障处理
    			节点宕机后,如果宕机的节点内含主分片,失效的主分片将从别的节点中升级副本分片来替换。从而达到系统的高可用。
    			如果节点是master节点,那么将从剩余可用节点中,选举新的Master节点。
    	
    	2、数据的输入和输出
    		1、文档更新
    			put 整体更新。
    			es文档不能更新。更新的实现方式为:找到旧文档,替换对应的字段。再将新的结果插入,最后将旧的文档删除。
    		2、并发控制
    			_version 字段,乐观并发控制。
    		3、部分更新
    			POST 部分更新。
    	
    	3、分布式文档存储
    		底层:如何存,如何取。
    		1、路由一个文档到分片中
    			shard = hash(routing) % number_of_primary_shards;
    		2、主分片和副本分片的交互
    			每个节点都知道集群中任一文档的位置。每个节点都有能力处理任意请求。
    		3、新建、索引和删除文档
    			新建、索引和删除文档都是写操作,必须再主分片上完成之后,才能被复制到副本分片中。
    			
    			步骤:客户端发起请求 -> node(协调节点) (确定分片位置) -> node(包含了具体分片的节点) -> 处理完成 -> 同步到副本节点 -> 返回node(协调节点) -> 客户端
    		4、获取文档
    			轮询副本的方式,达到负载均衡。
    			根据id获取文档:根据id进行路由判断,直接定位到具体的分片,获取文档。
    			搜索获取文档:将搜索的内容,用轮询节点的方式,发送到所有的副本节点中(不重复的副本),获取到结果后,再汇总到协调节点,协调节点往外吐结果。
    			
    	4、搜索
    		1、概念
    			Mapping(映射) : 描述字段如何存储。
    			Analysis(分析): 全文是如何处理数据,使得数据可以被搜索到。
    		2、分页
    			需要进行集中排序,才能保证结果顺序是正确的。
    			分布式系统中深度分页的问题:(禁止排序,或者限制分页深度。scroll游标的使用)
    				1、前提条件:3个主分片。pageSize=10。page = 0。
    				2、第一页:每个节点返回10条数据,排序完成后,取前10条返回。
    				3、第二页:每个节点返回(page+1)*pageSize= 20。排完序后,取10~20的记录返回。
    				4、第99页:每个节点返回990条记录……
    			
    	5、映射和分析
    		1、指定分析器
    		2、内部对象的处理
    			1、数组:类型一致,无序。
    			2、内部对象的索引:
    				Lucene不理解内部对象,Lucene文档按照键值对处理的:user.age:valeu。
    		
    	6、执行分布式检索
    		1、查询阶段
    			各个分片返回对应的文档id和排序值给协调节点。
    		2、取回阶段
    			根据排序结果,获取对应的记录。通过文档id到对应的分片获取文档,组装返回。
    		3、搜索选项
    		4、游标查询Scroll
    			scroll游标,解决深分页问题。
    			游标查询会取某个时间点的快照数据,查询初始化之后索引上任何变化都会被他忽略。它通过保存旧的数据文件来实现这个特性,类似视图。
    			游标查询用字段_doc来排序,让es仅仅从还有结果的分片返回下一批结果。
    			scroll_id:游标的id(视图的id).
    	
    	7、索引管理(文档)
    		1、创建索引
    			默认情况下,系统会进行动态映射。
    			如果需要关闭动态映射:config/elasticsearch.yml   action.auto_ceate_index: false
    		2、删除索引
    			delete /my_index
    			delete /_all    所有索引。config/elaticsearch.yml action.destrutive_requires_name: true 禁止使用_all防止误删。
    			delete /index_* 通配符
    		3、索引设置
    			number_of_shards: 主分片数量,默认是5。索引创建完成后,不能修改。
    			number_of_replicas:副本分配数量,默认是1。可以随时更改。
    		4、分析器
    			分析器包含如下内容:
    				字符过滤器:过滤掉某些字符
    				分词器:将要索引的文本,拆分为索引的词元。
    				单词过滤器:lowercase/stop等过滤器。
    		5、类型和映射
    			1、Lucene 如何处理文档
    				1、没有类型(type)的概念,es通过type的过滤,来返回查询结果。
    				2、没有映射(mapping)的概念,es通过将复杂的json映射成Lucene需要的的扁平化数据方式。(转换为key,value的形式)			
    		6、根对象	
    			1、属性
    				type:字段的数据类型,String,date
    				index:字段是否索引
    					1、analyzed   拆分单词,索引
    					2、not_analyzed  不拆分单词,索引。
    					3、no  不索引。
    			2、元数据    
    				_source:存储文档的json字符串。
    				_all: 所有字段的集合,禁用:"_all":{"enable":false}
    				文档标识:
    				_id
    				_type
    				_index
    		7、动态映射
    			dynamic:
    				true(动态添加新字段)
    				false(忽略新字段)
    				strict(如果遇到新字段抛出异常)
    			date_datection: false (日期动态监测映射)
    		8、重新索引
    			1、用新的设置创建新的索引并把文档从旧的索引复制到新的索引。
    				用scroll从旧的索引中批量索引文档,再用bulk API把文档推送到新的索引中。(新版本:Reindex API)
    			2、索引别名和零停机
    				_alias
    				应用中,使用别名。迁移的时候将实际索引迁移完成,再将别名指向新的索引。
    			
    	8、分片内部原理
    		1、解答的问题:
    			1、为什么搜索是近实时的?
    			2、为什么文档的CRUD操作是实时的?
    			3、Elasticsearch是怎样保证更新被持久化在断电时也不丢失数据?
    			4、为什么删除文档不会立即释放空间?
    			5、refresh,flush,optimize API都做了什么,什么情况下应该使用它们?		
    		2、使文本可被搜索
    			1、倒排索引:包含每个词项出现过文档的列表;包含词项出现过的文档总数;在对应文档中出现的总次数;每个文档的长度……等更多的文档信息。
    			2、不变性
    				优点:
    					1、不需要锁。
    					2、可以常驻内存,加速搜索。					
    				缺点:
    					1、删除数据不及时,更新数据是删除和添加,浪费硬盘空间。
    					2、不变性导致段的数量太多,对服务器的句柄自由消耗非常大。
    					3、删除的不及时,查询出来的结果需要经过.del文件的过滤,消耗性能。		
    		3、动态更新索引
    			1、通过增加新的索引来实现动态更新索引。
    			2、es基于Lucene,Lucene按段搜索,每个段就是一个倒排索引。
    				1、Lucene段
    					1、重点:段不可变。
    					2、Lucene索引包含:提交点,段
    					3、新增
    						1、为了提升写性能:采用延迟写策略,积累到一定量的数据(缓存中),才写入到硬盘。
    						2、为新增的数据新建对应的段。(因为段是不可变的,所以只能新增)
    						3、写入硬盘,更新提交点。
    					4、查询的时候:
    						1、遍历对应的段。(缓存的数据不可用,这就是es是近实时搜索的原因。默认1秒自动写一次段)
    						2、过滤结果数据。						
    			3、删除和更新
    				1、段是不可变的,删除是把删除的文档记录到.del文件中;更新的是:删除+添加。
    				2、查询的时候,先查询结果,再从.del文件中过滤结果。			
    			4、refresh_interval 设置刷盘间隔时间。
    				优点:提升性能。
    				缺点:丢失数据。
    		4、持久化变更
    			1、es增加translog(事务日志),类似redis aof。
    			2、安全性
    				"index.translog.durability": "async", //异步刷新。(request实时刷新)
    				"index.translog.sync_interval": "5s"  //异步刷新间隔
    			3、每次新增的段写入到磁盘,translog会清空。
    		5、段合并
    			1、段合并过程
    				1、合并线程选择大小相似的段,在后台将它们合并到更大的段当中去。不会中断索引和搜索。
    				2、合并的过程,将删除那些失效的文档。
    

      

  • 相关阅读:
    test!
    Visual Studio 中的单元测试 UNIT TEST
    Jquery结合div+css实现文字间断停顿向上滚动效果
    asp.net中使用HttpWebRequest发送上传文件
    分享一个可以灵活控制的实现Javascript滚动效果的程序
    VeryCodes.Log让日志记录和读取变的更简单
    实现MyXLS设置行高的功能
    设计模式学习笔记建造者模式
    设计模式学习笔记原型模式
    设计模式学习笔记模板方法
  • 原文地址:https://www.cnblogs.com/chen--biao/p/9660571.html
Copyright © 2011-2022 走看看