1、elasticsearch基础概念
- 节点(Node): 物理概念,一个运行的elasticsearch实例,一般是一台机器上一个进程,用来存储数据并参与集群的索引和搜索。可以分为以下几种类型:
- 专有主节点(Master Node):为确保一个集群的稳定,分离主节点和数据节点,主要职责是和集群相关操作的内容,如创建和删除索引,跟踪哪些节点是集群的一部分,并决定哪些分片分配给相关节点。在大规模集群中,开启专有Master Node可增强集群的稳定性。
- 协调节点(Coordinator Node):该节点只处理路由请求,处理搜索,分发索引文件,相当于一个只能的负载均衡器,协调节点将请求分发给存储数据的Data Node。每个Data Node在本地执行请求,并将请求结果返回给Cooridinator Node 。协调节点收集完数据后,将每个节点的数据合并为单个全局结果。
- 数据节点(Data Node):存储索引数据的节点,主要对文档进行增删改查、聚合等操作。数据节点对cpu、内存、io要求比较高,在优化的时候需要监控数据节点的状态,当资源不够的时候,需要再集群中添加新的节点。
- 索引(Index):逻辑概念,索引是相同特性的文档集合(相当于关系型数据库的database),包括配置信息mapping和倒排正排数据文件,一个索引的数据文件可能会分布于一台机器,也有可能分布于多台机器。
- 类型(Type):一个类型通常是一个Index的一个逻辑分区,允许一个Index下存储不同类型的文档(相当于关系型数据库中table),在6.x版本,只允许一个Index包含一个Type,在7.x以后这个概念将会被删除。
- 文档(Document):一个文档是可以被索引的基础信息单元(相当于关系型数据库中一行数据)。文档可以用Json格式来表示。
- 映射(Mapping):模式映射(相当于关系型数据库的schema)用于定义索引结构。
- 字段(Field):字段是Elasticsearch里面的最小单元,相当于数据库中的某一列,类似于Json里面的一个key。
- 分片(Shard):为了支持更大量的数据,索引一般会按某个维度分成多个部分,每个部分就是一个分片,分片会被Node管理。一个Node一般会管理多个分片,但是为了可靠性和可用性,同一个索引的分片尽量会分布在不同的Node上。分片有两种,主分片(Primary Shard)和副本分片(Replica Shard)。分片的数量只能在索引创建的时候指定,创建后不能更改,每个分片的大小建议是小于50G,所以设计分片的提前预估数据量来设置合适的分片。
- 副本(Replica):同一个分片(Shard)的备份数据,一个分片可能有0个或者多个副本,这些副本中的数据保证强一致性或者最终一致性。
2、elasticsearch集群架构
2.1、分层部署
通过配置隔离Master Node和Data Node
代码语言:javascript复制#master node 配置
node.name: master
node.master: true
node.data: false
#data node 配置
node.name: node1
node.master: false
node.data: true
2.2、混合部署
Master Node也是Data Node,通过集群选举出Master Node,选举策略 discovery.zen.minimum_master_nodes = (master_eligible_nodes / 2) 1
3、Elasticsearch文档写入原理
3.1、文档写入流程
- 假设选中了Node2(DataNode) 发送写入Index1索引的请求,此时的Node2可以被称为协调节点(Coordinating Node);
- Coordinaing Node会根据算法(shard id的计算公式:shard_num = hash(_routing) % num_primary_shards,hash函数是murmur3Hash,_routing默认是文档ID(_id))进行路由,请求到对应的DataNode,假设对应的主分片为P1;
- 请求数据写入P1;
- 数据同步到R1;
- 返回数据写入结果。
3.2、文档存储
3.2.1、文档存储结构
每个Elasticsearch分片都是一个Lucene索引(Index),每个Lucene都包含了多个段(segment),每个segment有多个文档(Document)以及维护了一份词(terms)与文档Id关系的倒排索引(Inverted Index)数据。文档存储结构如下图所示:
3.2.2、倒排索引存储
- 从 in-memory buffer 到 disk page cache 的过程,对应 ElasticSearch 的
refresh()
API,默认 1s 触发一次; - 从 disk page cache 到 disk 的过程,则对应 ElasticSearch 的
flush()
API,默认 30min 触发一次; - translog 自己从 disk page cache 到 disk 的持久化,是 5s 一次
3.2.3、segment合并
- 自动refresh流程每秒会创建一个新的段,每一个段都会消耗文件句柄;
- 小的段被合并到大的段,然后这些大的段再被合并到更大的段(小于5G);
- 新的段被打开用来搜索,老的段被删除。
4、Elasticsearch检索原理
- 假如选择了Node3,此时Node3称为coordinating node(协调节点)
- 协调节点(Coordinating Node)将查询请求广播到每一个数据节点,这些数据节点的分片会处理该查询请求。
- 每个分片进行数据查询,将符合条件的数据放在一个优先队列中,并将这些数据的文档ID、节点信息、分片信息返回给协调节点。
- 协调节点将所有的结果进行汇总,并进行全局排序。
- 协调节点向包含这些文档ID的分片发送get请求,对应的分片将文档数据返回给协调节点,最后协调节点将数据返回给客户端。
5、参考资料:
ElasticSearch 索引的存储机制推演:https://www.yuque.com/terencexie/geekartt/es-index-store
ElasticSearch架构原理入门篇:https://juejin.cn/post/6994789245227368479
从Elasticsearch来看分布式系统架构设计:https://zhuanlan.zhihu.com/p/33375126
elastic:https://www.elastic.co/guide/en/elasticsearch/reference/6.8/elasticsearch-intro.html