1.1 基本概念
Elasticsearch是实时的分布式搜索分析引擎,底层使用Lucene提供索引和搜索功能。
实时:新增到ES的数据最快1s可被搜到
分布式:动态调整集群规模,弹性扩容
1.1.1 索引结构
ES是面向文档的,各种文本内容以文档的形式存储在ES索引中,默认使用JSON作为文档的序列化格式,文档可有很多字段,创建索引时需要声明每个字段的数据类型,某些类型需要指定分析器。
::在存储结构上,由_index、_id 共同标识一个文档。 _index即索引,_id即某个索引下文档的唯一ID::
1.1.2 分片(shard)
分布式系统中,单机无法存储规模巨大的数据,需依靠大规模集群处理和存储(水平扩展),对数据分片,通过路由规则定位某一数据位置
除了对数据分片提高水平扩展能力外,分布式存储中还会吧数据复制成多个副本,放置到不同机器上(要保证主分片和副本分片不在同一台机器,否则机器宕掉后数据无法恢复),对于并发更新问题,ES写过程中先写主分片,成功后再写副本分片,::恢复阶段::以主分片为准
数据分片和数据副本关系如下图。
- 一个ES索引包含很多分片,一个分片是一个完整的lucene索引,即一个数据分片是一个完整的搜索引擎,可以独立执行建立索引和搜索任务
- 一个分片又由很多分段(segment)组成,ES每次执行”refresh”操作都会生成一个新的分段,其中包括若干文档,分段内部文档的不同字段被单独建立索引
- 每个字段的值由若干Term组成,(Term是写入进索引的源数据经过分析器得到的最终结果,分词+过滤)
::在索引建立时需要确定好主分片数,ES5.x以后支持对索引的主分片拆分::
1.1.3 动态更新索引(我理解是mapping新增字段)
通过关键词搜索时会使用到倒排索引的数据结构,::倒排索引一旦被写入就不可被更改::。
索引如何更新?新增内容被写入一个新的倒排索引,查询倒排索引并对结果进行合并后返回。
1.1.4 近实时搜索
对于写操作来说,一批数据会在内存中缓存一段时间(ES默认1s),每1s执行一次refresh,在内存中行程一个segment,每5m或者通过某些写入策略执行一次flush,将内存中存在的分段合并并写入磁盘,当执行完refresh后,数据即可见,这两个过程中都会通过写事务日志来保证数据的安全,当ES启动的时候重放最后一次提交后发生的变更操作。
段合并
在ES中,每秒清空一次写缓冲 buffer,将这些数据写入文件,这个过程称为refresh,::每次refresh后会创建一个新的Lucene段::,但是分段太多会消耗文件句柄和内存,并且::每次搜索都会遍历每个段,查询完后对结果进行合并::,所以段越多,搜索效率越低下。常用的方案是选择::大小相似的分段::进行合并,在合并过程中,标记为删除的分段不会写入新分段,当合并结束后旧分段被删除,标记删除的数据才从磁盘或者内存中被删除。
集群原理
ES集群使用主从模式,部分操作只能由Master节点操作,并负责维护集群元数据信息,缺点是主节点存在单点故障。
集群元数据信息包括:内容路由信息、全局配置信息
集群状态由主节点维护,如果主节点从数据节点接收更新,会将更新广播到其他数据节点。
节点集群角色
- 主节点
负责集群层面的相关操作,管理集群变更。 ::脑裂如何解决?::
主节点全局唯一,并且可以作为数据节点。 - 数据节点
负责保存数据,执行数据相关操作:CRUD/搜索/聚合等,数据节点对CPU、内存、I/O要求较高。 - 预处理节点
5.0版本后引入的概念,写入文档前,通过事先定义好的一系列processors和pipline,对数据进行转化和富化,拦截bulk和index请求,进行相关操作后传回bulk或index API。::默认在所有节点启用ingest:: - 协调节点
处理客户端请求的节点被称为协调节点(每个节点都可以成为协调节点,这取决于请求打到哪台机器上),客户端请求可以发送到集群的任何节点,每个节点都知道任意文档所处的机器和分片,然后转发这些请求,收集数据并返回给客户端。 - 部落节点
5.0版本后被协调节点取代,部落节点可以在多个集群之间充当联合客户端。
集群健康状态
- Green 所有主分片和副本分片都正常运行
- Yellow 所有主分片正常运行,但部分副本分片状态异常(存在单点故障)
- Red 有主分片异常
ES源码内部模块
- Cluster
Cluster模块是主节点执行集群管理功能的封装实现,管理集群状态,维护集群配置等
主要功能:- 管理集群状态,将新生成的集群状态发布到集群所有节点。
- 调用allocation模块执行分片分配,决策哪些分片应该分配到哪个 节点。
- 在集群各节点中直接迁移分片,保持数据平衡。
- Allocation
Allocation模块封装了分片分配相关功能和策略,本模块由::主节点::调用,创建新索引、集群完全重启都需要分片重新分配。 - Discovery
Discovery模块负责发现集群中的节点,以及选举主节点。
当节点加入或 退出集群时,主节点会采取相应的行动。从某种角度来说,::发现模块起到类似ZooKeeper的作用::,选主并管理集群拓扑。 - Gateway
Gateway模块负责对收到Master广播下来的集群状态(cluster state)数据的持久化存储,并在集群完全重启时恢复它们。 - Indices
Indices模块管理全局级的索引设置,但不包括索引级的设置,封装了索引数据恢复功能。 - HTTP
http模块允许通过JSON over HTTP的方式访问ES的API。(完全异步) - Transport
传输模块用于集群内节点之间的内部通信。传输模块使用 TCP 通信,每个节点都与其他节点维持若干 TCP 长连接。(完全异步) - Engine
Engine模块封装了对Lucene的操作及translog的调用,它是对一个分片读写操作的最终提供者。