总结《Elasticsearch源码解析和优化实战》第一讲
一、基本概念及原理
elastic是实时分布式搜索分析引擎,内部使用luence作为索引和搜索。
什么是实时?
新增到 ES 中的数据在1秒后就可以被检索到,这种新增数据对搜索的可见性称为“准实时搜索”。
什么是全文?
对全部的文本内容进行分析,建立索引,使之可以被搜索,因此称为全文。
1.1 基本概念
-
集群
集群cluster是一个或多个节点(node)的集合,这些节点将共同拥有完整的数据,由唯一的名称标识(elasticsearch.yml的cluster.name)。 -
节点
节点(node)是一个ElasticSearch的运行实例,也具有唯一标识。
服务器与节点可以是一对多的关系
-
索引
索引(index)是具有某种相似特征的文档集合,索引由一个名称(必须全部是小写)标识,可以对其中的文档进行执行索引、搜索、更新、删除等操作。 -
类型
类型(type)很多初学者喜欢套用RDBMS中的概念,将_index理解为数据库,将_type理解为表,这是很牵强的理解,实际上这是完全不同的概念,没什么相似性,
不同_type下的字段不能冲突,删除整个_type也不会释放空间。在实际应用中,数据模型不同,有不同_type需求的时候,我们应该建立单独的索引,而不是在一个索引下使用不同的_type。正由于_type在实际应用中容易引起概念混淆,以及允许索引存在多_type并没有什么实际意义,
删除过期老化的数据时,最好以索引为单位,而不是_type和_id。
在ES 6.x版本中,一个索引只允许存在一个_type,未来的7.x版本将完全删除_type的概念。
-
文档
文档(document)是可以被索引的基本单位,文档是以json作为序列化格式的。 -
分片
分片(shard)将索引水平切分成多段,最基本的读写单元。分片是数据的容器,文档保存在分片内,不会跨分片存储。
- 分片可以水平切分数据
- 可以跨分片进行并发和并行操作。
- 副本
为了防止数据丢失,es将shard复制一个或多个拷贝,称为副本(replica),读操作可以在副本上并行执行,可以提高搜索能力和水平扩展吞吐量。
shard和其副本永远不可能出现在同一个节点
这样会带来什么问题?
多副本会带来了一致性的问题:部分副本写成功,部分副本写失败。
在实际中,不推荐以_id 为单位来删除文档,因为不会立即释放空间,删除的 doc 只在 Lucene分段合并时才会真正从磁盘中删除。即使手工触发分段合并,仍然会引起较高的 I/O 压力。
所以建议周期性地创建新索引。例如,每天创建一个。假如有一个索引website,可以将它命名为website_20180319。当需要删除时,删除整个索引。
- 索引别名
索引别名就像一个快捷方式或软链接,不同的是它可以指向一个或多个索引。可以用于实现索引分组,或者索引间的无缝切换。
1.2 动态更新索引
为文档建立索引,使没个字段都可以被搜索到,会使用倒排索引的数据结构。倒排索引一旦写入文件中,就不可变。这样的好处就是对文件的访问不需要加锁,而且可以被文件系统缓存。
新文档写入后,会创建一个新的倒排索引,查询时会对多个倒排索引轮流查询,然后对结果进行合并。
然后会生成文件,所以如果删除一个文档,只会先设置一个删除标记,因此不会删除掉空间。
1.3 写数据底层原理
总结一下,数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。
每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。
每秒清空一次写缓冲,将这些数据写入文件,这个过程称为refresh,每次refresh会创建一个新的Lucene 段。但是分段数量太多会带来较大的麻烦,每个段都会消耗文件句柄、内存。每个搜索请求都需要轮流检查每个段,查询完再对结果进行合并;所以段越多,搜索也就越慢。因此需要通过一定的策略将这些较小的段合并为大的段。
常用的方案是选择大小相似的分段进行合并。在合并过程中,标记为删除的数据不会写入新分段,当合并过程结束,旧的分段数据被删除,标记删除的数据才从磁盘删除。
数据写入 segment file 之后,同时就建立好了倒排索引。
二、集群内部原理
分布式系统的集群方式大致可以分为
- 主从(Master-Slave)模式 ES、HDFS、HBase使用主从模式
- 无主模式。Cassandra使用无主模式。
主从模式 Master作为权威节点,部分操作仅由Master执行,并负责维护集群元信息。缺点是Master节点存在单点故障,并且集群规模会受限于Master节点的管理能力。
2.1 集群中的角色
2.1.1 主节点
主节点负责集群层面的相关操作,管理集群变更。
通过配置 node.master: true(默认)使节点具有被选举为 Master 的资格。主节点是全局唯一的,将从有资格成为Master的节点中进行选举。
生产环境尽量分离主节点和数据节点
配置如下:
node.master: true
node.data: false
2.1.2 数据节点
负责保存数据,执行相关操作,CRUD,搜索,聚合等。