ElasticSearch基本原理

ElasticSearch 基本原理
1. 搜索原理
1. ElasticSearch简介
  • ElasticSearch就是独立的网络上的一个或一组进程节点
  • 它能对外提供搜索服务(使用httptransport协议),自从ElasticSearch 7.0开始,主要支持http协议
  • ElaticSearch对内其实就是一个数据库
2. 分词

搜索是以词为单位做最基本单位的搜索单元,依赖分词器构建分词,用分词器倒排索引。

3. 倒排索引
  • 正向索引

    对文档中的所有分词进行遍历,获取与 keyword 中分词相同的词,命中一次,这种索引方法需要对每一个文档都进行遍历,性能上不是很好。
    

  • 倒排索引

    对文档的分词结果进行遍历,如果 keyword 命中该分词,那么通过该分词便可以找到所有含有这个分词的文档,性能相对较高。
    
    倒排索引包含两个部分:
    	- 单词词典(Term Dictionary),记录所有文档的单词,记录单词倒排列表的关联关系。单词词典一般比较大,可以通过B+树或者哈希拉链法实现,以满足高性能的插入与查询
    	- 倒排列表(Posting List),记录了单词对应的文档结合,由倒排索引组成。倒排索引项包含:文档ID,词频TF(该单词在文档中出现的次数,用于相关性评分),位置(Position,单词在文档中分词的位置。用于语句搜索(phrase query)),偏移(Offset,记录单词的开始结束位置,实现高亮显示)
    	
    Elasticsearch的倒排索引:Elasticsearch的JSON文档中的每个字段,都有自己的倒排索引。但是可以对某些字段不做索引,优点是可以节省存储空间,缺点是该字段将无法被搜索。
    

4. TF/IDF打分
TF:词频,这个 document 文档包含了多少个这个词,包含越多表名越相关
DF:文档频率,包含该词的文档总数目
IDF:DF 取反
单词 ID单词文档频率倒排列表(DocID;TF;<POS>)
1谷歌5(1;1;<1>),(2;1;<1>),(3;2;<1;6>),(4;1;<1>),(5;1;<1>)
2地图5(1;1;<2>),(2;1;<2>),(3;1;<2>),(4;1;<2>),(5;1;<2>)
3之父4(1;1;<3>),(2;1;<3>),(4;1;<3>),(5;1;<3>)
4跳槽2(1;1;<4>),(4;1;<4>)
5Facebook5(1;1;<5>),(2;1;<5>),(3;1;<8>),(4;1;<5>),(5;1;<8>)
6加盟3(2;1;<4>),(3;1;<7>),(5;1;<5>)
7创始人1(3;1;<3>)
8拉斯2(3;1;<4>),(5;1;<4>)
9离开1(3;1;<5>)
101(4;1;<6>)
2. 名词定义

ElasticSearch中的索引=数据库,类型=表,文档=行数据,在ElasticSearch 7.0逐步的废弃了类型这样一个定义,也就是说索引和类型统称为索引,也就是说在ElasticSearch 7.0中只有索引和文档的定义,其中索引相当于索引和类型。

与关系型数据库的名词之间的类比:

关系型数据库ElasticSearch
DatabaseIndex
TableType
RowDocument
ColumnField
SchemaMapping
IndexEverything is indexed
SQLQuery DSL
SELECT * FROM table …GET http://…
UPDATE table SET …PUT http://…
3. 分布式原理
Elasticsearch的分布式架构的好处:
	- 存储的水平扩容
	- 提高系统的可用性,部分节点停止服务,整个集群的服务不受影响
Elasticsearch的分布式架构:
	- 不同的集群通过不同的名字来区分,默认名字为“elasticsearch”
	- 通过配置文件修改,或者在命令行中-E cluster.name=Yankee进行设定
	- 一个集群可以有一个或者多个节点

节点:
	- 节点是一个Elasticsearch实例,本质上就是一个JAVA进程,一台机器上可以运行多个Elasticsearch进程,但是生产环境一般建议一台机器上只运行一个Elasticsearch实例
	- 每一个节点都有名字,通过配置文件配置,或者启动时候-E node.name=node1指定
	- 每一个节点在启动之后,会分配一个UID,保存在data目录下
	
Master-eligible Nodes和Master Node:
	- 每个节点启动后,默认就是一个Master eligible节点,可以设置node.master:false禁止
	- Master-eligible节点可以参加选主流程,称为Master节点
	- 当第一个节点启动时,它会将自己选举成Master节点
	- 每个节点上都保存了集群的状态,只有Master节点才能修改集群的状态信息
		- 集群状态(Cluster State),维护了一个集群中,必要的信息(所有的节点信息,所有的索引和其相关的Mapping和Settings信息,分片的路由信息)
		- 任意节点都能修改信息会导致数据的不一致性

Data Node和Coordinating Node:
	- Data Node:可以保存数据的节点,叫做Data Node。负责保存分片数据。在数据扩展上起到了至关重要的作用
	- Coordinating Node:负责接受Client的请求,将请求分发到合适的节点,最终把结果汇总在一起;每个节点默认都起到了Coordinating Node的职责
	
其他的节点类型:
	- Hot & Warm Node:不同硬件配置的Data Node,用来实现Hot & Warm架构,减低集群部署的成本。其中Hot存放新数据,硬件配置比较高;Warm存放旧数据,硬件配置比较低
	- Machine Learning Node:负责跑机器学习的Job,用来做异常检测
	- Tribe Node:(5.3开始使用Cross Cluster Search)Tribe Node连接到不同的Elasticsearch集群,并且支持将这些集群当成一个单独的集群处理
1. 分片
ElasticSearch 中默认的主分片(num_of_shards)数量为 5,默认的副本(num_of_replicas)个数为 1
主分片数量一旦设置就不会再改变,但是副本个数可以进行改变

在单集群节点中,如果主分片数量为 1,副本也为 1,那么此时单节点集群的 health 为 yellow,因为单节点必然会存在副本和主分片在同一个节点,会导致该索引的 health 为 yellow。此时可以修改集群的副本个数为 0,则索引和集群的状态会变回到 green 状态。

主分片(Primary Shard),用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上:
	- 一个分片是一个运行的Lucene的实例
	- 主分片数在索引创建时指定,后续不允许修改,除非Reindex
副本(Replica Shard),用以解决数据高可用的问题。分片是主分片的拷贝:
	- 副本分片数,可以动态调整
	- 增加副本数,还可以在一定程序上提高服务的可用性(读取的吞吐)
	
分片的设定:
	- 分片数设置过小:导致后续无法增加节点实现水平扩展;单个分片的数据量太大,导致数据重新分配耗时
	- 分片数设置过大,7.0开始,默认主分片设置成1,解决了over-sharding的问题:影响搜索结果的相关性打分,影响统计结果的准确性;单个节点上过多的分片,会导致资源浪费,同时也会影响性能
2. 主从
# 单节点集群
单节点集群中,如果创建了一个索引,默认会拥有副本,此时由于副本和主分片在一个节点,则单节点集群的 health 为 yellow。创建索引时,根据未来的扩展性,将主分片个数设置为合适的个数,但也不能太多,因为数量太多,如果数据量没有达到对应的瓶颈,在进行数据聚合时,就需要遍历所有的主分片,才能得到结果。

# 双节点集群
当新增一个集群节点的,此时节点集群会将副本全部存放到新增的节点上,此时如果索引的副本个数为 1 时,那么此时集群的状态会变成 green。

# 三节点集群
当继续新增一个集群节点时,此时节点集群会使用负载均衡,将某个索引的主分片会迁移到新增的节点上,会将部分的副本也迁移到新增的节点上

# 三台节点构成 es 集群
# 副本个数为 2 时
此时 es 集群会将副本个数分别存放于另外两个节点之上,这两个节点中并没有改索引的主分片,此时主从分离,读写也分离。es 集群其实是一个对称的结构,es 集群的 master 用来管理所有负载的一个核心节点,也就是说如果要进行写操作,如果要写的索引的主分片就在 master 上,那么就可以直接进行写请求;如果写的索引在另一个节点上,那么 master 会将这个写请求进行转发,转发到要写的主分片所在的节点,由该节点进行写请求。

# 当关掉此时的 master 节点时
此时 es 集群会进行选举,选举一个新的 master 节点,会比较剩余的节点中的 metadata 是最新的,就会通过 paxos 方式从具备竞争主节点能力的机器中竞选主节点。此时被关掉的 master 上存在的主分片会均匀的分布到剩余的集群节点上,此时由于副本个数为 2,所以集群的状态又会变成 yellow,但是集群对外响应服务的能力还是有的。

# 三台节点构成 es 集群,并且状态为 green
# PUT 请求
当有操作请求集群进行新建索引操作时,无论请求的是 es 集群的那个节点,都会将该请求转发到 master 节点,因为只有 master 节点知道所有的 metadata 存储的位置,此时 master 会对进行写请求的操作进行识别,如果写请求的 documenId 识别是在 master 节点上,那么由 master 节点进行写操作,如果在 node3 上,就会将该写请求进行转发,转发到 node3,由 node3 完成写请求。写操作完成之后,node3 会异步的将数据改动同步回其对应的副本。
# GET 请求
进行读请求时,master 会进行一次路由计算,计算出该读请求属于 R0 副本的操作,假设 master 节点上也存在 R0 副本,假设上一次的操作是在 master 节点上进行,那么 es 集群会根据负载均衡,将该读请求转发到另一个存在 R0 副本的节点上。如果读请求第一次命中在别的节点上,但是由于是读请求,可以由每个节点进行路由操作。
# 总结
也就是说,master 节点只路由读请求,所有的写请求可以由其命中的节点进行处理,此时整个 es 集群就做到了负载均衡和读写分离。
3. 配置节点类型
开发环境中一个节点可以承担多种角色
生产环境中,应该设置单一的角色的节点(dedicated node)
节点类型配置参数默认值
master eligiblenode.mastertrue
datanode.datatrue
ingestnode.ingesttrue
coordinating only每个节点默认都是coordinating节点。设置其他类型全部为false
machine learningnode.mltrue(需要enable x-pack)
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yanko24

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值