Elasticsearch线上搜索引擎读写内核原理深度认知-搜索系统线上实战

本套技术专栏是做者(秦凯新)平时工做的总结和升华,经过从真实商业环境抽取案例进行总结和分享,并给出商业应用的调优建议和集群环境容量规划等内容,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,若有任何学术交流,可随时联系。java

1 ES 分布式架构设计

elasticsearch设计的理念就是分布式搜索引擎,底层其实仍是基于lucene的。node

es中存储数据的基本单位是索引,好比说你如今要在es中存储一些订单数据,你就应该在es中建立一个索引,order_idx,全部的订单数据就都写到这个索引里面去,一个索引差很少就是至关因而mysql里的一张表。mysql

-> index(mysql里的一张表)
-> type(一个index里能够有多个type,每一个type的字段都是差很少的,可是有一些略微的差异。
         好比在订单index里,建两个type,一个是实物商品订单type,一个是虚拟商品订单type,
         这两个type大部分字段是同样的,少部分字段是不同的) 
-> mapping (mapping就是这个type的表结构定义)
-> document (一条document就表明了mysql中某个表里的一行,每一个document有多个field,每一个field就表明了这个document中的一个字段的值)
-> field(具体索引字段)
复制代码

  • 设计一个索引,这个索引能够拆分红多个shard,每一个shard存储部分数据。
  • 每个shard的数据实际是有多个备份,每一个shard都有一个primaryshard,负责写入数据,可是还有几个replica shard。primary shard写入数据以后,会将数据同步到其余几个replica shard上去。
  • es集群多个节点,会自动选举一个节点为master节点,这个master节点其实就是干一些管理的工做的,好比维护索引元数据拉,负责切换primary shard和replica shard身份等。
  • 若是master节点宕机了,那么会从新选举一个节点为master节点。
  • 若是是非master节点宕机了,那么会由master节点让那个宕机节点上的primary shard的身份转移到其余机器上的replica shard。

2 ES 写数据过程深刻剖析

2.1 ES 写数据整体流程

  • 客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)
  • coordinating node,对document进行路由,将请求转发给对应的node(拥有primary shard 的节点)
  • 拥有primary shard 的node处理写入请求,而后将数据同步到replica node
  • coordinating node,若是发现primary node和全部replica node都搞定以后,就返回响应结果给客户端。

2.2 ES 写数据内核原理剖析

  • 步骤一(buffer缓冲和写入translog日志阶段):ES 写数据先写入buffer,在buffer里的时候数据是搜索不到的,并同时将数据写入translog日志文件。sql

  • 步骤二(refresh刷写os cache阶段):当写入数据buffer快满了,或者到必定时间,就会将buffer数据refresh到一个新的segment file中,可是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的,这个过程就是refresh。segment file位于os cache中。api

    (1) 每隔1秒钟,es将buffer中的数据写入一个新的segment file,
          每秒钟会产生一个新的磁盘文件,segment file,这个segment file
          中就存储最近1秒内buffer中写入的数据。
      (2) 若是buffer里面此时没有数据,那固然不会执行refresh操做,每秒建立换一个空的
          segment file,若是buffer里面有数据,默认1秒钟执行一次refresh操做,刷入一个
          新的segment file中
      (3) 只要buffer中的数据被refresh操做,刷入os cache中,就表明这个数据就能够被搜索到了
      
      (4) 为何叫es是准实时的?NRT,near real-time,准实时。
          默认是每隔1秒refresh一次的,因此es是准实时的,由于写入的数据1秒以后才能被看到。
      (5) 能够经过es的restful api或者java api,
          手动执行一次refresh操做,就是手动将buffer中的数据刷入os cache中,让数据立马就能够被搜索到。
    复制代码
  • 步骤三(清空buffer阶段):只要数据被输入os cache中,buffer就会被清空了,由于不须要保留buffer了,数据在translog里面已经持久化到磁盘去一份了。restful

  • 步骤四(commit阶段flush操做):重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推动,translog会变得愈来愈大。当translog达到必定长度的时候,就会触发commit操做。架构

    (1)commit操做发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer
      
      (2)将一个commit point写入磁盘文件,里面标识着这个commit point对应的全部segment file
      
      (3)强行将os cache中目前全部的数据(全部的segment file文件)都fsync到磁盘文件中去。
      
      (4)将现有的translog清空,而后再次重启启用一个translog,此时commit操做完成。
         默认每隔30分钟会自动执行一次commit,可是若是translog过大,也会触发
         commit。整个commit的过程,叫作flush操做。咱们能够手动执行flush操做,
         就是将全部os cache数据刷到磁盘文件中去。
         
      (5)es中的flush操做,就对应着commit的全过程。咱们也能够经过es api,
         手动执行flush操做,手动将os cache中的数据fsync强刷到磁盘上去,
         记录一个commit point,清空translog日志文件。
         
      (6)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,因此默认状况下,
         可能有5秒的数据会仅仅停留在buffer或者translog文件的
         os cache中,若是此时机器挂了,会丢失5秒钟的数据。可是这样性能比较好,最多
         丢5秒的数据。也能够将translog设置成每次写操做必须是直接fsync到磁盘,可是性能会差不少。
      (7) es是准实时的,数据写入1秒后能够搜索到;可是却可能会丢失数据,由于
         有5秒的数据停留在buffer、translog os cache、segment file os cache中,
         有5秒的数据不在磁盘上,此时若是宕机,会致使5秒的数据丢失。
      
      (8) 若是你但愿必定不能丢失数据的话,你能够设置个参数,官方文档,百度一下。
          每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,可是
          这会致使写性能、写入吞吐量会降低一个数量级。原本一秒钟能够写2000条,
          如今你一秒钟只能写200条,都有可能。   
    复制代码
  • 步骤五(删除操做):commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了app

  • 步骤六(更新操做):就是将原来的doc标识为deleted状态,而后新写入一条数据elasticsearch

  • 步骤七 (merge阶段操做):buffer每次refresh一次,就会产生一个segment file,因此默认状况下是1秒钟一个segment file,segment file会愈来愈多,此时会按期执行merge。 每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,而后将新的segment file写入磁盘,这里会写一个commit point,标识全部新的segment file,而后打开segment file供搜索使用,同时删除旧的segment file。分布式

3 ES 读数据过程深刻剖析

  • 步骤一:客户端发送请求到一个coordinate node(随机选择)
  • 步骤二:协调节点将搜索请求转发到全部的shard对应的primary shard或replica shard(不一样的副本均可以用来搜索)。
  • 步骤三:query阶段,每一个shard将本身的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操做,产出最终结果
  • 步骤四:fetch阶段,接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端

4 总结

生产部署还有不少工做要作,本文从初级思路切入,进行了问题的整合。

本套技术专栏做者(秦凯新)专一于大数据及容器云核心技术解密,具有5年工业级IOT大数据云平台建设经验,可提供全栈的大数据+云原平生台咨询方案,请持续关注本套博客。QQ邮箱地址:1120746959@qq.com,若有任何学术交流,可随时联

秦凯新

相关文章
相关标签/搜索