基本概念
一、文档(Document)
-
elasticsearch是面向文档的文档型数据库,其中最基本的数据存储信息是文档(document),可以理解为关系型数据库中一条(row)数据记录;
-
elasticsearch中的文档是以json的形式存储在数据库中,json对象由字段组成,每个字段都有对应的字段类型(字符串、数值、布尔、日期、二进制、范围类型等),字段类型可以通过指定其类型,或者在未指定其类型时,es会自动推算该字段数据的类型,并且字段支持数组和嵌套;
-
每个文档都有一个独一无二的ID字段这个ID可以我们自己指定,也可以通过es自动生成;
-
文档的元数据(用于标注文档的相关基本信息)
| 元数据名称 | 描述 |
|---|---|
| _index | 文档所在的索引名称 |
| _type(* doc) | 文档的类型名称 |
| _source | 文档的数据,即该文档的数据信息 |
| _all | 整合所有字段到all中,但现在已经被废除了 |
| _id | 文档的唯一ID |
| _version | 文档的版本信息,用于在并发的情况下对数据版本的校验,解决文档冲突的问题 |
| _score | 文档的相关性打分 |
二、索引(Index)
-
索引是文档的容器,是一类文档的集合;
-
每个索引都有自己的mapping映射定义,该mapping映射定义了字段以及字段类型;
-
以及setting,用于定义使用多少分片(shard),即指定该索引的数据是如何在物理空间意义的分片上如何分布的;
-
在7.0版本之前,一个索引下可以建立多个types;但是在7.0之后,一个索引下只被允许创建一个type(_doc);
三、关系型数据库概念与ES概念对比
| RDBMS | ElasticSearch |
|---|---|
| table | index |
| row | document |
| column | field |
| schema | mapping |
| Sql | DSL |
四、节点
-
es每个节点的本质就是一个java实例进程,在一台机器上可以运行多个实例,但是在生产环境中,建议一台服务器只部署一个实例;
-
每一个节点在启动后,都会分配一个UID,保存到data目录下;
4.1 Master-eligible Nodes 和 Master Nodes
-
每一个节点默认都是Master-eligible节点,如果想要禁止该节点参与主节点的选举,则在配置文件中配置node.master=false;
-
每一个Master-eligible节点都有权利参与主节点的选举过程,成为master节点;
-
当第一个Master-eligible节点启动的时候,他会将自己选为master节点;
-
每个节点都会保存集群的状态信息,但只有通过master节点,才能修改集群的状态信息;
-
Master Node负责创建,删除索引等请求,决定分片被分配到哪个节点等;
-
Master Node最佳实践,一般生产上会为一个集群设置多个master节点;
-
集群状态(cluster state),维护了集群的所有节点信息、所有索引的mapping和setting信息、分片的路由信息等,每个节点都存有集群状态信息,但是只有master节点才能修改集群状态信息,并负责同步给其他节点;
4.2 Data Node & Coordinating Node
-
data node:即保存数据节点,负责保存分片数据,在数据扩展的方面非常重要;
-
coordinating node:即协调节点,负责将客户端发起的请求分发到合适的节点上,并将结果汇集在一起,返回给客户端,每个节点都默认都拥有这个功能;
4.3 Hot Node & Warm Node
- 冷热节点,对于不同的硬件配置上的节点,可以通过hot&warm冷热节点的指定,实现对于活跃度较高的数据部分分配到性能高的热节点上,对于活跃度低的数据部分分配到配置不那么高的冷节点上,节省服务器开支;
4.4 节点类型的配置建议
-
开发环境上,我们可以给一个节点赋予多个节点角色;
-
生产环境上,建议每一个节点设置为一个节点角色,好处在于可以明确每个节点的职责,提高整个集群的性能;
五、分片(Primary Shard & Replica Shard),ES最小工作单元
5.1 主分片(Primary Shard)
-
用于解决数据水平扩展的问题,通过主分片,可以将索引数据分布到集群中所有节点上;
-
每一个主分片都是一个lucene实例;
-
分片数量在创建索引时就需指定好,后续不可更改,除非对索引进行reindex,进行重新指定;
5.2 副本分片(Replica Shard)
-
副本的分片数可以动态调整;
-
增加副本数,在一定程度上还可以增加服务的可用性(读取的吞吐),但是需要占用和主分片一样的资源;
-
副本分片会降低数据索引速度,因为涉及到数据的副本写入;
-
number_of_shards:3,代表着该索引的主分片分为3个,es会尽可能的将主分片平均的分配到各个es节点之上;
-
number_of_replicas:1,代表该索引的每个主分片上的数据,都有一份副本拷贝的数据;
-
如图所示,副本的存储节点顺序会打乱后,平均分配到每个es的节点上(防止节点宕机后,部分数据缺失,提高可用性);
5.3 生产环境上分片设定注意事项
-
分片数量过少,会导致后期es集群无法通过增加节点来水平扩展;
-
分片数量过少,单个分片的数据量过大,导致数据重新分配非常耗时;
-
分片数量过大,影响搜索结果的相关性打分,影响统计结果的准确性;
-
分片数量过大,单个节点如果分片过多,导致资源浪费,并且会影响性能,并且master节点维护的信息会过多,增加管理负担,经验值,控制分片总数在10万以内;
5.4 如何设计分片数
-
当分片数>节点数,一旦集群有新数据节点加入,分片会自动进行分配;
-
多分片好处:一个索引如果分布在不同节点,多个节点可以并行执行查询,并将数据写入分散到多个机器上;
-
对于日志类应用,单个分片数据量不超过50GB;对于搜索类应用,单个分片数据量不超过20GB;
六、倒排索引
-
正排索引:文档ID与文档内容的直接关系,更适合通过ID去寻找文档信息;
-
倒排索引:文档内容与文档ID与位置的直接关系,更适合通过内容关键词去寻找对应的文档ID下的文档信息;
6.1 倒排索引的核心组成
-
单词词典(Term Dictionary),记录分词后的所有文档的单词与倒排列表之间的关系,由于单词词典一般比较大,所以会通过B+树或者哈希拉链法实现,用于高性能的读写;
-
倒排列表(Posting List),由倒排索引项组成的记录单词相关文档信息的记录,包含以下倒排索引项:
| 字段 | 描述 |
|---|---|
| 文档ID | 单词所在的文档ID |
| 词频(TF) | 单词在该文档中出现的次数,用于相关性评分 |
| 位置(Position) | 单词在该文档中分词的位置,用于语句搜索 |
| 偏移量(Offset) | 单词在该文档中出现的开始与结束的位置,用于高亮显示 |
- 在ES中,每个索引下的字段,都会有各自对应的倒排索引,其中可以指定某些字段不创建倒排索引,那么将节省存储空间,但是缺点就是该字段不可被搜索;
6.2 倒排索引不可变性
-
倒排索引采用Immutable Design,一旦生成,不可更改;
-
不可变性优点:
-
无需考虑并发写文件问题,避免锁机制带来的性能问题;
-
一旦读入内核的文件系统缓存,便停留在那里。只要文件系统有足够空间,大部分请求就会直接请求内存,不会命中磁盘,提升了很大的性能;
-
缓存容易生成和维护,数据可以被压缩;
- 不可变性缺点:
- 如果需要一个新文档被搜索,则需要重建整个索引;