ES分片上的数据写入过程
ES分片是对一个lucene实例的抽象,最终调用的都是lucene的缓冲和提交能力。
1)将BulkItemRequests的每条数据在ES中被封装成index对象;
2)ES调用lucene的addOrUpdateDocument()将数据缓冲到page cache;写入成功后,更新记录事务日志location;批量数据写入成功后,执行sync()将translog落盘;
3)lucene执行fsync把数据落盘,并执行提交操作,将数据可见;
过程如图所示
可以看到,ES通过记录事务日志将所有写入操作在返回给协调节点前都记录了下来。
Translog保证数据不丢失
translog保证数据不丢失
数据在page cache落到磁盘之前,如果发生意外的故障,导致内存中数据丢失。这个时候可以通过读取translog事务日志,找回内存中丢失的数据。
在数据正确写入到磁盘以前,包含内存数据操作的translog将一致保存,直到数据fsync和commit之后,才会将这部分translog删除。
Translog生命周期
ES的trasnlog由几部分组成。
translog记录所有未提交的索引操作。每个InternalEngine有一个Translog实例,使用 translog_generation 包含所有没有提交给lucene索引的操作记录。使用 translog_uuid 关联lucene索引和事务日志文件。
每个Translog只打开一个translog文件。translog.ckp文件写入每个事务日志的fsync操作,并记录写入的操作数、fsync偏移量(以字节为单位)和其他一些信息。
当前的translog文件达到特定大小(index.translog.generation_threshold_size,默认为64MB)时,或者新旧操作之间有明显的区分(upon change in primary term)时,当前文件以只读方式重新打开,并创建新的写文件。只读的translog文件始终具有关联的translog-${gen}.ckp,他是最后一个translog.ckp的fsync副本,用来在灾难恢复中最后fsynce的偏移量和其他操作记录仍然保留。
lucene从page cache落盘后,将对应的translog文件从磁盘清除。根据提交seqNo范围,查找tranlog-${gen}.ckp文件,找到tranlosg-${gen}.tlog文件后,进行删除。
translog生命周期如图所示:
Translog配置策略
ES提供的对translog的几个动态配置
index.translog.durability: 默认Request;
index.translog.sync_interval:按时间间隔,默认5秒;
index.translog.flush_threshold_size: 当translog的大小达到此值时会进行一次flush操作。默认是512mb;
index.translog.retention.age: 默认12h;
index.translog.retention.size:默认512M;