分布式特性

es 支持集权模式,是一个分布式系统,好处有二:

  1. 增大系统容量,磁盘 内存 使得 es集群可以支持pb级别的业务
  2. 提高系统可用性 即使部分节点停止服务 整个集群可以正常使用

es集群由多个es实例组成

  1. 不同的集群通过集群名称组成,通过 cluster.name 定义
  2. 每个es实例本质上是一个jvm进程,且有自己的名字 通过 node.name定义

构建集群

启动一个节点
bin/elasticsearch -E cluster.name=my_cluster -E node.name=node1

cluster state
es集群的相关数据称为 cluster state 主要记录如下信息:

  1. 节点信息 节点名称 连接地址等
  2. 索引信息 索引名称 配置等

master node
可以修改 cluster state 的节点称为 master 节点 一个集群只能有一个
cluster state 存储在每个节点上,master 维护最新版本并同步给其他节点
master节点通过集群中所有节点选举产生,可以被选举的节点称为master eligible节点
node.master=true

分片

  1. 如何将数据分簿于所有节点上
    引入分片解决问题
  2. 分片是es支持pb事务的基石

    1. 分片存储了部分数据,可以分布于任意节点上
    2. 分片数在索引创建时指定,且后续不允许更改,默认为五个
    3. 分片有主分片和副本分片的区别,实现数据高可用
    4. 副本分片数据由主分片同步,可以有多个,从而提高吞吐量
  3. 继续增加节点是否提高索引的数据容量?
    不能,只有三个分片,新增节点上的资源无法被利用
  4. 继续增加副本数能否提高索引的数据吞吐量?
    不能,新增副本还是分布在已有节点上,资源并没有增多

健康状态

通过api GET _cluster/health 可以查看集群的健康状况,包括三种:

  1. green 健康 指所有的主副分片都正常
  2. yellow 指所有的主分片都正常 但是有副本分片未正常分配
  3. red 所有分片都未分配

故障转移

  1. node1 所在的集器宕机,集群会如何处理?

    1. node2 发现主分片p0未分配,将R0提升为主分片,此时由于所有的主分片都正常,集群状态为yellow
    2. node2 为p0和p1生成新的副本,集群状态为绿色

分布式存储

  1. 使用映射算法将文档均匀的分布在所有的分片上,以充分利用资源
  2. es 使用 shard = hash(routing)%number_of_primary_shards
  3. hash算法可以保证将数据均匀的分布在分片中
  4. routing 默认为文档id

文档创建流程

  1. client向node3发起文档创建请求
  2. node3通过routing计算出该文档应该存储在shard1上,查询cluster state后确认主分片在p1
    在node2中,转发创建请求到node2上
  3. p1接收并创建文档,将同样的请求发送到副本分片r1
  4. r1接收并执行创建文档请求后通知p1创建成功
  5. p1接收副本分片结果后,通知node3创建成功
  6. node3将结果返回给client

文档读取流程

  1. client向node3发起读取文档1的请求
  2. node3通过routing计算该文档在shard1上,查询cluster state后获取shard1的主副分片列表,然后轮询获取shard,例如R1,转发请求到node1
  3. R1接收并执行读取文档,将结果返回node3
  4. node3返回结果给client

脑裂问题

  1. 当集群中出现网络网体,node2 与 node3 重新组成集群选举一个master,并更新cluster state
  2. node1 自己组成集群后,也会更新cluster state
  3. 同一个大集群有两个master 并且有两个 cluster state 网络恢复后无法决定哪个是正确的master 和 cluster state
  4. 解决 增加选举条件 可被选举为master-eligible节点数大于等于quorum 时才可以进行master选举

    1. quorum=master-eligible 节点数/2+1 例如三个master-eligible节点时,quorum为2
    2. 设定 discovery.zen.minimum_master_nodes为quorum可避免脑裂

shard

倒排索引不可变更

  1. 倒排索引一旦生成,不能更改
  2. 不用考虑并发写文件的问题,避免锁机制带来的性能问题
  3. 可以充分利用缓存,载入一次,多次读取
  4. 利于对文件进行压缩存储,节省磁盘和内存存储空空间
  5. 写入新文档时,必须重新构建倒排索引文件,然后替换老文件,新文档才会被检索,实时性差

文档搜索实时性

  1. lucene构建单个倒排索引称为segment 合在一起称为index,与 es 中的index不同,es中一个shard对应一个lucene index。
  2. lucene 会有一个专门的文件来记录所有的segment信息,称为commit point。

文档搜索实时性 - refresh

  1. segment 写入缓存,并开放查询,该过程称为refresh
  2. 在refresh前文档会先存储在一个buffer中,refresh时将buffer中的所有文档清空并生成segment
  3. es默认每一秒执行一次refresh,因此文档的实时性被提高到1秒,这也是es被称为近实时的原因

translog

如果缓存中segment还没写入磁盘时发生宕机怎么办?

  1. es 引入 translog机制,写入到buffer时,同时将操作写入translog。
  2. translog文件会即时写入磁盘fsync,6.X默认每个请求都会落盘,可以修改每五秒一次,这个风险为丢失五秒内数据,祥光配置为index.translog.*
  3. es 启动时会检查translog文件,并且从中恢复数据

flush

flush 负责将内存中的segment 写入磁盘

  1. 将translog 写入磁盘
  2. 将index buffer 清空,其中的文档生成新的segment 相当于refresh操作
  3. 更新 commit point并写入磁盘
  4. 执行fsync操作 将内存中的segment写入磁盘
  5. 删除旧的translog

删除与更新文档

  1. lucene专门维护一个 .del文件,记录所有的已经删除的文档,.del上记录的文芳时lucene内部的文档id
  2. 在分会查询结果前会过滤掉.del中的文档
  3. 更新文档等于先删除,在创建新文档

segment merging

  1. 随和segment增多 一次查询的segment过多 查询速度变慢
  2. es 定时在后台进行 segment merge 减少segment数量
  3. 通过force_mergeapi 可以手动 merge操作

Fox_Valentin
1 声望1 粉丝