Elasticsearch 是一 个基于 Lucene 构建的开源、分布式、RESTful 接口的全文搜索引擎。
Lucense
Lucene 是 Apache 软件基金会中一个开放源代码的全文搜索引擎工具包,是一个全文搜索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文搜索引擎。
全文搜索(Full Text Search)
全文搜索是指计算机搜索程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,搜索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户。这个过程类似于通过字典中的搜索字表查字的过程。
倒排索引(Inverted Index)
倒排索引源于实际应用中需要根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而称为倒排索引(invertedindex)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(invertedfile)。
倒排索引包含两个部分:
- 单词字典(Term Dictionary):记录所有文档的单词,记录单词到倒排列表的关联关系。(单词字典一般比较大,可以通过 B+ 树或哈希链表法实现,以满足高性能的插入与查询)
- 倒排列表(Posting List):记录了单词对应的文档结合,由倒排索引项组成:
- 文档 ID
- 词频 TF:该词在文档中出现的次数,用于相关性评分。
- 位置(Position):单词在文档中分词的位置。用于语句搜索(phrase query)。
- 偏移(Offset):记录单词的开始结束位置,实现高亮显示。
文档(Document)
Elasticsearch 是面向文档的,文档是所有可搜索数据的最小单位;文档会被序列化成 JSON 格式,其中每个字段都有对应的字段类型(字符串/数值/布尔/日期/二进制/范围类型);每个文档都有一个 Unique ID,我们可以自己指定 ID,也可以通过 Elasticsearch 自动生成。
文档元数据:
- _index:文档所属的索引名
- _type:文档所属的类型名
- _id:文档唯一 ID
- _source:文档的原始 Json 数据
- _all:整合所有字段内容到该字段,已被废除
- _version:文档的版本信息
- _score:相关性打分
索引(Index)
索引是具有相同结构的文档集合。它体现了逻辑空间的概念:每个索引都有自己的 Mapping 定义,用于定义包含的文档的字段名和字段类型。我们可以在 Index 上定义 Mapping(文档字段的类型)和 Setting(不同的数据分布)。
类型(Type)
类型是索引的逻辑分区。在 7.0 之前,一个 Index 可以设置多个 Types。从 7.0 开始,每个索引做能创建一个类型:_doc。
映射(Mapping)
映射定义了索引中的每一个字段类型,以及一个索引范围内的设置。一个映射可以事先被定义,或者在第一次存储文档的时候自动识别。
集群(Cluster)
集群由一个或多个节点组成,对外提供服务。一个集群有一个唯一的名称默认为 Elasticsearch。此名称是很重要的,因为每个节点只能是集群的一部分,当该节点被设置为相同的集群名称时,就会自动加入集群。当需要有多个集群的时候,要确保每个集群的名称不能重复,否则,节点可能会加入错误的集群。请注意,一个节点只能加入一个集群。此外,我们还可以拥有多个独立的集群,每个集群都有其不同的集群名称。
节点(Node)
单个的 ElasticSearch 服务实例称为节点(node)。很多时候部署一个 ElasticSearch 节点就足以应付大多数简单的应用,但是考虑到容错性或在数据膨胀到单机无法应付这些状况时,我们会更倾向于使用多节点的 ElasticSearch 集群。
节点类型:
节点类型 | 说明 | 配置参数 | 默认值 |
---|---|---|---|
master eligible | 可以参加选主流程,成为 Master 节点 | node.master | true |
data | 保存分片数据 | node.data | true |
ingest | 执行预处理管道,不负责数据也不负责集群相关的事务 | node.ingest | true |
coordination only | 接受 Client 请求,将请求分发到合适的节点,最终把结果汇集到一起 | 无 | 每个节点默认都是 coordination 节点。设置其它类型全部为 false。 |
machine learning | 执行机器学习的 Job,用来做异常检测 | node.ml | true (需 enable x-pack) |
在开发环境中,一个节点可以承担多种角色;在生产环境中,应该设置单一的角色节点(dedicated node)。
主分片(Primary Shard)
用以解决数据水平扩展的问题。通过主分片,可以将数据分布到集群内的所有节点之上。主分片数在索引创建时指定,后续不允许修改,除非 Reindex。
对于生产环境中分片的设定,需要提前做好容量规划:
- 分片数设置过小:导致后续无法增加节点实现水平扩展;单个分片的数据量太大,导致重新分配耗时。
- 分片数设置过大:影响搜索结果的相关性打分,影响统计结果的准确性;单个节点上过多的分片,会导致资源浪费,同时也会影响性能。
副本分片(Replica Shard)
用以解决数据高可用的问题。副本分片是主分片的拷贝。副本分片数可以动态地调整。