ES面试题

ES写入数据流程

  1. 首先客户端根据配置的连接节点,通过轮询方式连接到一个coordinate节点。
  2. coodinate节点通过hash算法计算出数据在shard1上shard = hash(document_id) % (num_of_primary_shards),然后根据节点上维护的shard信息,将请求发送到node1上。
  3. node1 对索引数据进行校验,然后写入到shard中。
  4. 主节点数据写入成功后,将数据并行发送到副本集节点Node2,Node3。
  5. Node2,Node3写入数据成功后,发送ack信号给shard1主节点Node1。
  6. Node1发送ack给coordinate node
  7. coordinate node发送ack给客户端。

为什么ES的搜索是近实时,而不是准实时?

es在插入文档的时候,并不是直接把数据写到磁盘,而是先写到他在内存里创建的一个索引缓冲区index buffer里。我们知道搜索是需要在segment里的倒排索引里搜的,而现在数据都还在index buffer里,所以刚刚插入的文档是搜不到的。这时es需要通过一个refresh操作,在内存里创建一个segment,并把index buffer里的数据插到segment里,然后把index buffer清空。由于此时segment是在内存里直接创建的,所以刚才插入的文档现在可以被搜索到了。然而内存里的segment数据需要刷到磁盘里存储才算插入成功,所以refresh会继续调用系统的fsync方法,把内存里的segment刷到磁盘,这样才完成一个完整的refresh操作。因为调用了fsync这种写磁盘方法,会消耗很大的资源,所以为了提升性能,需要尽量减少对fsync的调用, 因此es采用一秒钟执行一次refresh操作。这就导致了从插入文档到可被搜索,中间有1s的延迟,从而使得es的搜索功能不是准实时的,而是近实时的。

为什么文档的CRUD操作是实时的?

translog还有另外一个用处,就是在每次用_id对文档做crud操作的时候,都先在translog里查,如果translog里没有,再执行refresh操作,从segment里查,这样就可以实现对文档的crud(增删改查)操作达到准实时:

为什么Elasticsearch能做到保证数据不丢失?

和其他系统的解决方法一样,es也是通过加了一个写translog(事务日志)机制,插入的文档在写入内存的index buffer之后,需要同步把操作数据追加到translog(事务日志)文件里,在index buffer和translog都写入成功后,才给客户端返回写入成功.这样系统在断电重启后,就可以根据translog里的记录进行还原

Refresh、flush的作用是什么? 什么时候使用?

  • refresh操作使得写入文档搜索可见
  • flush操作使得filesystem cache写入磁盘,以达到持久化的目的

发表评论