ElasticSearch 是目前最流行的搜索引擎,Java语言开发,基于 Luence 做底层的索引和检索,高可用,高扩展,天生分布式。学习ES首先就要了解他的基本概念。
集群(cluster)
具有相同 cluster.name
的节点组成一个集群,每个节点在集群中有唯一的UID。
//查看集群的状态 green=正常,yellow=有副本分片无法分配,red=有主分片无法分配
GET _cluster/health
//查看集群节点信息
GET _cat/nodes
//查询分片信息
GET _cat/shard
//查询集群节点的详细情况
GET _nodes[/nodeName,nodeName]
集群管理也可以使用 cerebro
节点(Node)
- 一个节点就是一个ES实例,本质上是一个Java进程。
- 一台机器上可以运行多个ES节点,生产环境建议一台机器运行一个。
- 每个节点都有自己的名称,可以通过配置文件配置或运行命令行
-E node.name={name}
指定 - 每一个节点在启动时会有一个 UID 保存在 data 目录下
- 节点有不同的类型,默认是
Master eligible
和Data
节点,Master eligible
节点可以参与选主过程,控制整个集群,通过设置node.master: false
禁止。 - 每个节点都保存了集群状态(Cluster State),但只有
master
节点可以修改集群状态。集群状态包括,节点地址、所有索引的定义信息、分片路由 - 当新节点加入到集群时,重新划分每个节点负责的分片,一个分片Primary 和 对应的 Replica 分片不能在同一个节点上。如果由于节点较少,导致 副本分片 无处分配,整个集群是一个黄色的状态,如果 主分片 无节点分配,整个集群是一个红色的状态。
节点类型 | 作用 | 启/禁用配置 |
---|---|---|
master eligible | 参与集群选主可以晋升为master节点 | node.master=true |
data node | 保存分片数据,数据扩展上起到重要的作用 | node.data=true |
ingest node | 预处理节点,会拦截 bulk、index 请求,会执行相关操作,然后把操作结果返回给 index、bulk请求。比如,你可以指定一个 pipeline 包含一个 processor 用于删除文档中一个字段 | node.ingest=true |
coordinating node | 负责接受用户请求,并分发到合适节点,聚合最终结果,每个节点默认就是 coordinating node | 上面全部为false 则 coordinateing only |
machine learning node | 负责跑机器学习job,用来做异常检测 | 需要enable x-pack node.ml=true |
hot & warm node | hot node 做热点数据存储,warm做冷数据存储,降低存储成本 | null |
Tribe node | 链接不同集群,把他们作为整体处理(5.3 之后使用 cross cluster search) | null |
开发环境一个节点可以承担多个角色,但生产环境为了保证高可用,应该每个节点承担一个角色。
分片(Primary Shard & Replica Shard)
分片主要用来解决数据水平扩展问题和数据高可用问题。
- 主分片(Primary Shard):用于解决数据水平扩展问题,一个索引(Index)会分散在多个主分片上,每一个分片都是一个 Lucene 实例,主分片数量在索引创建时制定,不可修改,想要修改必须通过
reindex
操作。 - 副本分片(Replica Shard):用来解决数据高可用问题,副本分片时主分片的备份。副本分片数可以动态调整,增加副本分片可以提高服务可用性即提高读吞吐量。
ES会讲主分片分散在多个节点上,并且主分片的副本分片,不能与主分片同属于一个节点。
//创建索引时,制定主分片和副本分片数量
PUT /blogs
{
settings:{
number_of_shards:3, //总共三个主分片
number_of_replicas:1 //每个主分片有一个副本分片
}
}
分片数不能多大或者过小,分片数太小,在数据增长太快时,无法支持水平扩展,单分片数据量太大。分片数大大,导致一个节点上分散太多分片,影响统计和打分,影响系统性能。7.0开始默认分片数=1
文档和索引
ES 中每一条存的数据就叫做文档(doc),文档已JSON格式存储在ES中,文档中每个字段都有自己的类型,每个文档都有一个ID,通过创建时指定或者由ES自动生成。每个文档也有自己的元数据,用来描述这个文档,如下图:
{
"_index" : ".kibana_1", //索引名
"_type" : "doc", //类型,类型概念逐渐被弱化了,现在固定为 doc
"_id" : "1", //文档的ID
"_score" : 1.0, //查询文档的得分
"_all" : "xx" //文档内容会同步到这个字段,后面被废除
"_source" : { //文档的数据信息
...
"updated_at" : "2021-06-26T09:12:04.166Z"
}
}
索引(Index)是文档的集合,索引定义包括两个部分 settings
和 mapping
,mapping 用来定义索引的结构,字段类型等,settings用来定义索引的分片和副本等。
类型(Type),6.0开始,一个索引下面可以有多个类型,7.0被废弃,一个索引只能创建一个Type=doc。Type存在时,操作ES的时候 Rest-API 路径可是这样子的 index/type/id
逐渐废弃后路径变成了 index/_doc/xx
或者是 index/op_type/xxx
.
倒排索引
倒排索引,是将文档相关内容分词索引存储,然后通过这些分词,反查文档整体记录。倒排索引包含两个部分,单词词典(Term Dictionary) 和 倒排列表(Posting List)。
单词词典(Term Dictionary):记录所有文档单词,记录单词到倒排列表的位置,一般通过B+树 或 Hash拉链法实现。
倒排列表(Posting List):记录单词对应的文档等相关信息,包括:
- 文档ID
- 词频(TF)-单词在文档中出现的频率,用于打分
- 位置(Position)-单词在文档中,分词的位置。用于(phase query)
- 偏移量(Offset)- 单词在文档中,出现的位置。用于(高亮显示)
ES 文档每个字段,都有自己的索引。但是你可以手动指定某些字段不被索引,这样可以减少存储空间。
文档相关性
在使用ES做 _search
时,返回结果内的文档内会有一个 _score
字段。这个字段来指明文档与搜索期望的相关性,这里涉及到三个概念:查准率(Precision)、查全率(Recall)相关度排序(sorting)。
- 查准率:尽可能返回准确结果,查准率 = 返回的符合期望的结果 / 全部返回结果
- 查全率:尽可能返回多的完整的结果,查全率 = 返回的符合期望的结果 / 所有符合期望的结果(这里包括了符合期望但是未返回的结果)