Elasticsearch的存储过程

原文地址

refresh和flush

1.      每当es接收一个文档时,在把文档放在buffer的同时,都会把文档记录在translog中。

2.      执行refresh操作时,会将缓存中的文档写入segment中,但是此时segment是放在缓存中的,并没有落入磁盘,此时新创建的segment是可以进行搜索的。

3.      按照如上的流程,新的segment继续被创建,同时这期间新增的文档会一直被写到translog中。

4.      当达到一定的时间间隔,或者translog足够大时,就会执行commit行为,将所有缓存中的segment写入磁盘。确保写入成功后,translog就会被清空。

执行commit并清空translog的行为,在es中可以通过_flush api进行手动触发。

如:

curl -XPOST127.0.0.1:9200/tcpflow-2015.06.17/_flush?v

通常这个flush行为不需要人工干预,交给es自动执行就好了。同时,在重启es或者关闭索引之间,建议先执行flush行为,确保所有数据都被写入磁盘,避免照成数据丢失。通过调用sh service.sh start/restart,会自动完成flush操作。

Segment的合并

前面讲到es会定期的将收到的文档写入新的segment中,这样经过一段时间之后,就会出现很多segment。但是每个segment都会占用独立的文件句柄/内存/消耗cpu资源,而且,在查询的时候,需要在每个segment上都执行一次查询,这样是很消耗性能的。

为了解决这个问题,es会自动定期的将多个小segment合并为一个大的segment。前面讲到删除文档的时候,并没有真正从segment中将文档删除,而是维护了一个.del文件,但是当segment合并的过程中,就会自动将.del中的文档丢掉,从而实现真正意义上的删除操作。

当新合并后的segment完全写入磁盘之后,es就会自动删除掉那些零碎的segment,之后的查询都在新合并的segment上执行。Segment的合并会消耗大量的IO和cpu资源,这会影响查询性能。

在es中,可以使用optimize接口,来控制segment的合并。

如:

POST/logstash-2014-10/_optimize?max_num_segments=1

这样,es就会将logstash-2014-10中的segment合并为1个。但是对于那些更新比较频繁的索引,不建议使用optimize去执行分片合并,交给后台的es自己处理就好了。

你可能感兴趣的:(Elasticsearch的存储过程)