es写数据过程

  • 客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)
  • coordinating node对document进行路由,将请求转发给对应的node(有primary shard)
  • 实际上的node上的Primary Shard处理请求,然后将数据同步到replica node
  • coordinating node 如果发现 primary node和replica node都搞定了之后,就返回响应给客户端

    es读数据过程

    可以通过doc id来查询,会根据doc id进程hash,判断出来当时把doc id 分配到哪个shard 上去,从那个shard 进行查询。

  • 客户端发送请求到任意一个node,成为coordinate node

  • coordinate node对doc id进行过哈希路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard 和 其所有的replica shard随机选择一个,让读请求负载均衡。
  • 接收请求的node返回document给coordinate node
  • coordinate node返回document给客户端

    es搜索数据的过程

    es强大的是做全文检索。

  • 客户端发送请求到一个coordinate node

  • 协调节点将搜索请求转发到所有的shard对应的primary shard或者replica shard, 都可以
  • query phase: 每个shard 将自己的搜索结果(其实就是一些doc id)返回给协调节点,由协调 节点进行数据的合并、排序、分页等操作,产生最终的节点
  • fetch phase : 接着由协调节点根据doc id 去各个节点拉取实际的document数据,最终返回给客户端。

写请求就是写Primary Shrd, 然后同步给所有的replica shard,读请求可以从Primary Shard或者Replica Shard读取,采用的随机轮询算法。

写数据底层原理

先写内存buffer, 在buffer里的时候是搜索不到的,同时将数据写入translog日志文件。
如果buffer快满了,或者到一定时间,就会将内存buffer的数据refresh到一个新的segment file 中,但是此时数据不知直接进入segment file 磁盘文件,而是先进入os cache, 这个过程就是refresh.

为什么es是准实时的?

默认1秒refresh一次,所以是准实时的,因为数据写入1秒之后才能被看到。可以通过es 的restful api或者java api,手动执行一次refresh操作,手动将buffer刷入到os cache中,让数据立马就可以看到。只要数据被输入到os cache,buffer就被清空了,因为不需要保留buffer了,数据在translog里面已经持久化磁盘上一份了。

translog的作用?

buffer和os cache都是内存,机器死了,内存数据丢失,将操作写入一个专门的translog, 机器宕机,再次重启,可以恢复。

丢数据问题?

translog默认5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据仅仅停留在buffer或者translog的os cache中,如果机器挂了,会丢失5秒的数据。

总结:数据先写入内存buffer, 然后每隔1s,将数据refresh到os cache, 到了os cache就能被搜索到了。(所以我们说es从写入到被搜索到,中间有1秒的延迟),每隔5秒,将数据写入到translog,(这样如果机器宕机,内存数据全没,最多会有5秒的数据丢失),translog大到一定程度,或者默认每隔30分钟,会触发commit操作,将缓冲区的数据flush到segment file磁盘文件上。

删除/更新数据底层原理

如果是删除操作,commit的时候会生成一个.del的文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc是否被删除了。
如果是更新操作,将原来的doc标识为deleted状态,然后新写入一条数据。

buffer 每refresh一次,就会产生一个segment file , 所以默认情况下1秒钟产生一个segment file, 这样segment file 会越来越多,此时会定期执行merge,多个合并成一个,同时会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file, 然后打开segment file 供搜索使用,同时删除旧的segment file.

底层lucene

lucene就是一个jar包,里面包含了封装好的各种建立倒排索引的算法代码。

倒排索引

倒排索引就是关键词到文档id的映射,每个关键词都对应着一系列的文件,这些文件中都出现了关键词。
倒排索引的两个重要细节:

  • 倒排索引中的所有词项对应一个或者多个文档
  • 倒排索引中的词项根据字典顺序升序排列。