一、document增删改内核级原理

1、document 新增文档时es内部执行步骤

(1)数据写入服务器的内存缓冲器(buffer)和translog日志文件;

(2)每隔一秒钟,buffer中的数据被写入新的segment file,并进入os cache,此时segment被打开并供search使;

(3)index segment 直接把数据写入到cache缓存;

(4)os cache 存储数据后会返回结果给index segment,index segment 的查询开关会被打开;

(5)内存缓存器(buffer)会被清空;

2、写入流程实现NRT近实时(filesystem cache,refresh)

数据写入os cache,并被打开供搜索的过程,叫做refresh。默认是每隔1秒refresh一次。也就是说,每隔一秒就会将buffer中的数据写入一个新的index segment file,先写入os cache中。所以,es是近实时的,数据写入到可以被搜索,默认是1秒。

POST /my_index/_refresh命令可以手动refresh,一般不需要手动执行,没必要,让es自己搞就可以了

如果说我们对时效性要求比较低,只要求一条数据写入es一分钟以后能够让我们搜索到就可以了,那么就可以调整refresh interval

PUT /my_index
{
  "settings": {
    "refresh_interval": "30s" 
  }
}

3、写入流程实现durability可靠存储(translog,flush)

elasticsearch 内部是通过translog文件来实现持久化可靠存储的。其内部具体的执行流程如下:

  1. 当translog长度达到一定程度的时候,commit操作发生
  2. buffer中的所有数据写入一个新的segment,并写入os cache,同时打开index segment 开发供查询(search)使用
  3. buffer被清空
  4. 一个commit ponit被写入磁盘,标明了所有的index segment
  5. filesystem cache中的所有index segment file缓存数据,被fsync强行刷到磁盘上
  6. 现有的translog被清空,创建一个新的translog

elasticsearch 内部整个document 新增文档时es内部执行步骤(包含近实时、持久化可靠存储(translog,flush))图解说明如下:

es 部分更新 es更新原理_数据库

2、document 修改和删除操作

每次commit point时,会有一个.del文件,标记了哪些segment中的哪些document被标记为deleted了

es 部分更新 es更新原理_redis_02

ps:上述的流程还只是一个相对来说考虑的比较少的流程,真正的es内部增删改还有很多其他的步骤来确保数据的及时性,比如es近实时的概念。

3、document 查询操作

搜索的时候会依次查询所有的segment,比如查询被修改过的document,在旧的segment中,会标记为deleted,在新的segment中会有其新的数据。

其查询逻辑遵循以下几点

(1)如果document没有被修改和删除过,搜索的时候会依次查询所有的segment找到这条数据后直接返回;

(2)如果document被删除了,当搜索时依次查询segment时,发现需要查询的数据已经被标记为deleted时,则不会返回该数据回去;

(3)如果document被更新了,这时搜索的时候会找到一个document的多个版本,但是只有最新的版本是正常的(其他的版本会被标记为deleted),则返回最新的版本数据;

二、基于translog和commit point,如何进行数据恢复

os cache存放一批数据,但是此时宕机了,导致os cache中的数据全部丢失了,那这个时候需要怎么才能够进行数据的修复呢?

解决办法:比较三种中的数据

  • 磁盘中的数据:当服务器宕机时,磁盘(disk)中的数据并不会丢失,磁盘中存放了上一次commit point操作为止的所有数据(index segment通过fsync命令刷进去的数据)。
  • os cache 中的数据:宕机后cache中的数据全部丢失了
  • translog 文件:存放了上一次执行flush到最近的所有的数据

综合以上三个数据存放的地方比较,elasticsearch内部是直接把tarnslog文件中的记录进行回放,重新在(内存缓冲器)buffer中执行之前的各种操作,然后重新刷一个个的index segment到cache中,等待下一次的commit point操作执行。

三、写入流程实现海量磁盘文件合并(segment merge,optimize)

在上面讲的内容中,elasticsearch内部每秒一个index segment file,就会导致文件过多,而且每次search都要搜索所有的segment很耗时,所以elasticsearch内部默认会在后台执行segment merge操作,把多个大小相似的index segment文件合并成一个文件,并且在merge的时候被标记为deleted的document也会被彻底物理删除。

每次merge操作的执行流程如下:

(1)选择一些有相似大小的segment,merge成一个大的segment

(2)将新的segment flush到磁盘上去

(3)写一个新的commit point,包括了新的segment,并且排除旧的那些segment

(4)将新的segment打开供搜索

(5)将旧的segment删除

手动执行merge操作语句如下,但是尽量不要手动执行,让它自动默认执行就可以了

POST /my_index/_optimize?max_num_segments=1