

-
Master-Slave
-
P2P 环形结构
-
分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。 -
实时分析的分布式搜索引擎。 -
可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。

Lucene中包含了四种基本数据类型,分别是:
-
Index:索引,由很多的Document组成。
-
Document:由很多的Field组成,是Index和Search的最小单位。
-
Field:由很多的Term组成,包括Field Name和Field Value。
-
Term:由很多的字节组成。一般将Text类型的Field Value分词之后的每个最小单元叫做Term。

-
集群(Cluster)一组拥有共同的 cluster name 的节点。
-
节点(Node) 集群中的一个 Elasticearch 实例。
-
索引(Index) 相当于关系数据库中的database概念,一个集群中可以包含多个索引。这个是个逻辑概念。
-
主分片(Primary shard) 索引的子集,索引可以切分成多个分片,分布到不同的集群节点上。分片对应的是 Lucene 中的索引。
-
副本分片(Replica shard)每个主分片可以有一个或者多个副本。
-
类型(Type)相当于数据库中的table概念,mapping是针对 Type 的。同一个索引里可以包含多个 Type。
-
Mapping 相当于数据库中的schema,用来约束字段的类型,不过 Elasticsearch 的 mapping 可以自动根据数据创建。
-
文档(Document) 相当于数据库中的row。
-
字段(Field)相当于数据库中的column。
-
分配(Allocation) 将分片分配给某个节点的过程,包括分配主分片或者副本。如果是副本,还包含从主分片复制数据的过程。
-
gateway: 代表es索引快照的存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再重新启动时就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务。

-
Gateway是ES用来存储索引的文件系统,支持多种类型。 -
Gateway的上层是一个分布式的lucene框架。 -
Lucene之上是ES的模块,包括: 索引模块、搜索模块、映射解析模块等 -
ES模块之上是 Discovery、Scripting和第三方插件。 Discovery是ES的节点发现模块,不同机器上的ES节点要组成集群需要进行消息通信,集群内部需要选举master节点,这些工作都是由Discovery模块完成。 支持多种发现机制,如 Zen 、EC2、gce、Azure。 Scripting用来支持在查询语句中插入javascript、python等脚本语言,scripting模块负责解析这些脚本,使用脚本语句性能稍低。 -
ES也支持多种第三方插件。 -
再上层是ES的传输模块和JMX.传输模块支持多种传输协议,如 Thrift、memecached、http,默认使用http。 JMX是java的管理框架,用来管理ES应用。 -
最上层是ES提供给用户的接口,可以通过RESTful接口或java api和ES集群进行交互。
-
节点启动后先ping(这里的ping是 Elasticsearch 的一个RPC命令。如果 discovery.zen.ping.unicast.hosts 有设置,则ping设置中的host,否则尝试ping localhost 的几个端口, Elasticsearch 支持同一个主机启动多个节点)Ping的response会包含该节点的基本信息以及该节点认为的master节点。
-
选举开始,先从各节点认为的master中选,规则很简单,按照id的字典序排序,取第一个。
-
如果各节点都没有认为的master,则从所有节点中选择,规则同上。这里有个限制条件就是 discovery.zen.minimum_master_nodes,如果节点数达不到最小值的限制,则循环上述过程,直到节点数足够可以开始选举。
-
最后选举结果是肯定能选举出一个master,如果只有一个local节点那就选出的是自己。
-
如果当前节点是master,则开始等待节点数达到 minimum_master_nodes(最小候选节点数),然后提供服务。
-
如果当前节点不是master,则尝试加入master。
Elasticsearch 将以上服务发现以及选主的流程叫做 ZenDiscovery 。由于它支持任意数目的集群(1-N),所以不能像 Zookeeper/Etcd那样限制节点必须是奇数,也就无法用投票的机制来选主,而是通过一个规则,只要所有的节点都遵循同样的规则,得到的信息都是对等的,选出来的主节点肯定是一致的。但分布式系统的问题就出在信息不对等的情况,这时候很容易出现脑裂(Split-Brain)的问题,大多数解决方案就是设置一个quorum值,要求可用节点必须大于quorum(一般是超过半数节点),才能对外提供服务。而 Elasticsearch 中,这个quorum的配置就是 discovery.zen.minimum_master_nodes 。
ES是如何实现Master选举的
Elasticsearch的选举是ZenDiscovery模块负责的,通过多播或单播技术来发现同一个集群中的其他节点并与它们连接。
一个节点如何选取它自己认为的master节点?
它会对所有可以成为master的节点(node.master: true)根据nodeId字典排序,,然后选出第一个(第0位)节点,暂且认为它是master节点。
如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
基于以下假设:集群由cluster.name设置项相同的节点自动连接而成,同一个网段中存在多个独立的集群.Zen 发现机制是ElasticSearch中默认的用来发现新节点的功能模块,而且集群启动后默认生效。Zen发现机制默认配置是用多播来寻找其它的节点。如果各个模块工作正常,该节点就会自动添加到与节点中集群名字(cluster.name)一样的集群,同时其它的节点都能感知到新节点的加入。在比较大的集群中,多播发现机制可能会产生太多不必要的流量开销,Zen发现机制引入了第二种发现节点的方法:单播模式。关于名词多播和单播(链接:https://www.zhihu.com/question/29360024/answ):
-
多播:当节点并非集群的一部分时(比如节点只是刚刚启动或者重启 ),它会发送一个多播的ping请求到网段中,该请求只是用来通知所有能连接到节点和集群它已经准备好加入到集群中。
-
单播: 关闭多播,就可以安全地使用单播。当节点不是集群的一部分时(比如节点重启,启动或者由于某些错误从集群中断开),节点会发送一个ping请求到事先设置好的地址中,来通知集群它已经准备好加入到集群中了。
为了安全考虑,阿里一般用单播模式。
分布式系统的一个要求就是要保证高可用。如果是故障导致节点挂掉,Elasticsearch 就会主动allocation。但如果节点丢失后立刻allocation,稍后节点恢复又立刻加入,会造成浪费。Elasticsearch的恢复流程大致如下:
-
集群中的某个非master节点丢失网络连接 -
如果该节点上的分片有副本,那么master提升该节点上的所有主分片的在其他节点上的副本为主分片。 cluster集群状态变为 yellow ,因为副本数不够等待一个超时设置的时间,如果丢失节点回来就可以立即恢复(默认为1分钟,通过 index.unassigned.node_left.delayed_timeout 设置)。 如果该分片已经有写入,则通过translog进行增量同步数据。
-
但如果该节点上的分片没有副本,则无法恢复,集群状态会变为red,表示可能要丢失该分片的数据了。
每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
- routing
- 副本一致性(replica)

- 新索引生成
- 索引的删除
- 新增副本分片
- 节点增减引发的数据均衡

Segment 直接提供了搜索功能的,ES 的一个 Shard (Lucene Index)中是由大量的 Segment 文件组成的,且每一次 fresh 都会产生一个新的 Segment 文件,这样一来 Segment 文件有大有小,相当碎片化。ES 内部则会开启一个线程将小的 Segment 合并(Merge)成大的 Segment,减少碎片化,降低文件打开数,提升 I/O 性能。
Segment 文件是不可变更的。当一个 Document 更新的时候,实际上是将旧的文档标记为删除,然后索引一个新的文档。在 Merge 的过程中会将旧的 Document 删除掉。具体到文件系统来说,文档 A 是写入到 .cfs 文件里的,删除文档 A 实际上是在.del文件里标记某个 document 已被删除,那么下次查询的时候则会跳过这个文档,是为逻辑删除。当归并(Merge)的时候,老的 segment 文件将会被删除,合并成新的 segment 文件,这个时候也就是物理删除了。



- 存储原文_source的文件.fdt .fdm .fdx;
- 存储倒排索引的文件.tim .tip .doc;
- 用于聚合排序的列存文件.dvd .dvm;
- 全文检索文件.pos .pay .nvd .nvm等。
- 加载到内存中的文件有.fdx .tip .dvm,
- 其中.tip占用内存最大,而.fdt . tim .dvd文-件占用磁盘最大
- 另外segment较小时文件内容是保存在.cfs文件中,.cfe文件保存Lucene各文件在.cfs文件的位置信息,这是为了减少Lucene打开的文件句柄数。
存储文件类型比较可见:https://www.itcodemonkey.com/article/8954.html
作者:lhj_sjtu
原文:https://blog.csdn.net/weixin_36564655/java/article/details/82736327
·END·