ES学习笔记之-Translog实现机制的理解

ES做为一个NoSQL,典型的应用场景就是存储数据。即用户能够经过api添加数据到es中。因为Lucene内部的实现, 每次添加的数据并非实时落盘的。而是在内存中维护着索引信息,直到缓冲区满了或者显式的commit, 数据才会落盘,造成一个segement,保存在文件中。api

那么假如因为某种缘由,ES的进程忽然挂了,那些在内存中的数据就会丢失。而实际上,用户调用api, 返回结果确认用户数据已经添加到索引中。这种数据丢失是没法被接受的。怎么解决这个问题呢?async

ES实现了Translog, 即数据索引前,会先写入到日志文件中。假如节点挂了,重启节点时就会重放日志,这样至关于把用户的操做模拟了一遍。保证了数据的不丢失。ide

经过ES的源码,了解一下实现的细节。 首先关注Translog类。性能

Translog类是一个索引分片层级的组件,即每一个index shard一个Translog类。它的做用是: 将没有提交的索引操做以持久化的方式记录起来(其实就是写到文件中)。日志

InternalEnginecommit metadata中记录了当前最新的translog generation。 经过这个 generation,能够关联到全部没有commit的操做记录。code

每一个Translog实例在任什么时候候都只会有一个处于open状态的translog file. 这个translog file跟translog generation ID是一一映射的关系。索引

出于性能的考虑,灾后重建并非回放全部的translog, 而是最新没有提交索引的那一部分。因此必须有一个checkpoint, 即translog.ckp文件。进程

综上,从文件的视角看待translog机制实际上是两个文件:内存

$ tree translog
translog
├── translog-11.tlog
└── translog.ckp

translog记录日志的格式以下:|记录size|操做的惟一id|操做的内容|checksum| 每次add操做返回的location会记录到versionMap中,这样就能实现realtime get的功能了。get

了解了这一点,在配置es的时候,有两种途径能够提高ES索引的性能。

a. 将translog日子和索引配置到不一样的盘片。
b. 将translog的flush间隔设置长一些。好比以下的参数:
index.translog.sync_interval : 30s 
index.translog.durability : “async” 
index.translog.flush_threshold_size: 4g 
index.translog.flush_threshold_ops: 50000

了解了translog的机制,会发现,即便是translog机制,也并不能彻底能避免数据的丢失。在性能和数据丢失容忍度上,仍是须要作一些平衡。

相关文章
相关标签/搜索