赞
踩
ElasticSearch
简介ElasticSearch
就是独立的网络上的一个或一组进程节点http
或transport
协议),自从ElasticSearch 7.0
开始,主要支持http
协议ElaticSearch
对内其实就是一个数据库搜索是以词为单位做最基本单位的搜索单元,依赖分词器构建分词,用分词器倒排索引。
正向索引
对文档中的所有分词进行遍历,获取与 keyword 中分词相同的词,命中一次,这种索引方法需要对每一个文档都进行遍历,性能上不是很好。
倒排索引
对文档的分词结果进行遍历,如果 keyword 命中该分词,那么通过该分词便可以找到所有含有这个分词的文档,性能相对较高。
倒排索引包含两个部分:
- 单词词典(Term Dictionary),记录所有文档的单词,记录单词倒排列表的关联关系。单词词典一般比较大,可以通过B+树或者哈希拉链法实现,以满足高性能的插入与查询
- 倒排列表(Posting List),记录了单词对应的文档结合,由倒排索引组成。倒排索引项包含:文档ID,词频TF(该单词在文档中出现的次数,用于相关性评分),位置(Position,单词在文档中分词的位置。用于语句搜索(phrase query)),偏移(Offset,记录单词的开始结束位置,实现高亮显示)
Elasticsearch的倒排索引:Elasticsearch的JSON文档中的每个字段,都有自己的倒排索引。但是可以对某些字段不做索引,优点是可以节省存储空间,缺点是该字段将无法被搜索。
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>) |
5 | 5 | (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>) |
10 | 与 | 1 | (4;1;<6>) |
在ElasticSearch
中的索引=数据库,类型=表,文档=行数据
,在ElasticSearch 7.0
逐步的废弃了类型这样一个定义,也就是说索引和类型统称为索引,也就是说在ElasticSearch 7.0
中只有索引和文档的定义,其中索引相当于索引和类型。
与关系型数据库的名词之间的类比:
关系型数据库 | ElasticSearch |
---|---|
Database | Index |
Table | Type |
Row | Document |
Column | Field |
Schema | Mapping |
Index | Everything is indexed |
SQL | Query DSL |
SELECT * FROM table … | GET http://… |
UPDATE table SET … | PUT http://… |
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集群,并且支持将这些集群当成一个单独的集群处理
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的问题:影响搜索结果的相关性打分,影响统计结果的准确性;单个节点上过多的分片,会导致资源浪费,同时也会影响性能
# 单节点集群 单节点集群中,如果创建了一个索引,默认会拥有副本,此时由于副本和主分片在一个节点,则单节点集群的 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 集群就做到了负载均衡和读写分离。
开发环境中一个节点可以承担多种角色
生产环境中,应该设置单一的角色的节点(dedicated node)
节点类型 | 配置参数 | 默认值 |
---|---|---|
master eligible | node.master | true |
data | node.data | true |
ingest | node.ingest | true |
coordinating only | 无 | 每个节点默认都是coordinating节点。设置其他类型全部为false |
machine learning | node.ml | true(需要enable x-pack) |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。