Elasticsearch的相关原理与问题

1、首先来谈谈es的分布式架构原理

首先es是一个分布式 的搜索引擎,底层是依赖于Lucene(使用倒排索引)的,核心是在多个机器上,启动多个es进程的实例来组成一个es的集群,保证其的高可用性,每个进程也被成为一个node,多个es的进程会选举出来master的节点,它将负责管理集群变更,例如创建或删除索引,添加节点到集群或从集群删除节点。,master 节点无需参与文档层面的变更和搜索。

es的基本存储单位是索引,es会将索引分为存储到多个shard(分片是一个独立的Lucene实例,并且它自身也是一个完整的搜索引擎)上,每个shard存储部分数据,可以很好 的横向扩张和提高查询的性能,各个shard分别查找,提高查询速度,每个shard分为primary shard 和 replica shard(备份数据),默认的情况下,每个索引会被分成5个primar shard和一个replica shard,每个shard的primar shard和replica不能再同一个node上,为了一台node宕机,不会丢数据,写数据都是要写入到 primary shard 中去,但是读数据,两者都可以。

如果master节点宕机了,那么剩下的node会选举出一个master节点,并且重新协调各个shard,如果哪个primary shard 没了,但是 replica shard 还在,master会将备份节点转为 primary shard,如果修复了宕机的那台机器,重启之后,master节点就会控制将缺失的replica shard 分配过去,同步后续的修改工作,让集群恢复正常。

2、es的写数据过程

首先客户端发送一个请求写入数据,随机选择一个节点,选择的这个节点叫做协调节点,协调节点对写入的数据的document进行hash,然后找到对应的(可能就在协调节点或者在其他节点上)primary shard ,写入数据,这个写入的数据也是复杂的一个步骤:

(1)、根据路由找到对应的primary shard节点上,首先是将数据写入到es的进程内存 buffer 中去的,同时将数据写入到tranglog日志文件中,这其实先将日志数据写入到OS cache中,然后每个5秒回涮新到tranglog中的,刚写入到内存的时候,这个时候,其他查询这个数据的请求是无法查询到的。

(2)、不断的数据写入到buffer中,写入满的时候,或者默认每隔1秒钟回刷新(refresh)buffer,将数据刷新到OS cache中,OS cache回将数据写入到segment file(磁盘),只要刷新到OS cache中 就可以读取数据了(也可以手动的刷新refresh)

(3)、随着磁盘的 tranglog中的数据越来越来多,就会触发commit命令,这个会将buffer中的数据refresh到OS cache中,清空 buffer ,将一个commit point 写入磁盘中,里面标识这这个commit point 对应的所有segment file,也会将OS cache中的数据刷新到磁盘上面去,清空tranglog文件中日志,这个命令是,每个30分钟或者满了会执行flush。

3、删除数据的过程

不是直接将数据删除,而是有一个 .del 的文件,将数据标志为delete,但是这个时候,这个数据是查询不到的,只有当segment file文件很大时候,才会将del文件删除

4、读数据过程

  • 搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch;
  • 在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。PS:在搜索的时候是会查询Filesystem Cache的,但是有部分数据还在Memory Buffer,所以搜索是近实时的。
  • 每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
  • 接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并 丰富 文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。

5、es集群的脑裂

es集群有可能会出现脑裂问题,原因主要有两个:
1)如果集群中节点不在同一个网段有可能是网络延迟造成的
2)如果集群中的节点在同一个网段,有可能是主节点负载太大造成的
解决方案主要有两种:
1)把主从节点的职责分离,设置三个储备主节点,node.master=true,node.data=false从节点只存储数据,node.master=false,node.data=true
2)增加延迟时间 将储备主节点数最小设为n/2+1个

6、es提高查询效率

给 OS cache 较大的内存、将不必要的数据不存入es中,将热点数据提前存入到OS cache中

7、Elasticsearch的Master选举

  • Elasticsearch的选主是ZenDiscovery模块负责的,主要包含Ping(节点之间通过这个RPC来发现彼此)和Unicast(单播模块包含一个主机列表以控制哪些节点需要ping通)这两部分;
  • 对所有可以成为master的节点(node.master: true)根据nodeId字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是master节点。
  • 如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新选举一直到满足上述条件。
  • 补充:master节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data节点可以关闭http功能。

8、客户端在和集群连接时,如何选择特定的节点执行请求的

TransportClient利用 transport 模块远程连接一个 elasticsearch 集群。它并不加入到集群中,只是简单的获得一个或者多个初始化的 transport 地址,并以 轮询 的方式与这些地址进行通信。