write down,forget

索引optimize究竟是否减少索引内存占用的测试

<Category: Diving Into ElasticSearch> 查看评论

针对昨天wood兄的帖子,做的实验,http://elasticsearch.cn/article/32

Optimize做什么事情?ES底层的lucene是append模式,不支持修改,commit就会产生新的segment文件,删除只是标记,查询时候进行过滤,而optimize就是合并若干segment文件到一个segment文件(可设置最终多少个),合并过程中丢弃标记为删除的索引文档,其实没有太多的magic,合并过程中,就是倒排相关数据整合的过程,多个链表合并成一个,多个term词典合并成一个等等,并且需要注意的是,合并的过程中,不是在原有的文件上操作,其实是产生一个新的临时segment文件,合并完成再删除之前的,所有合并过程中索引磁盘是会额外增加的,必须确保足够的磁盘空间,究竟合并前后的内存占用是否有变化呢?合并前是很多段文件,也有很多倒排表,而合并后所有的segment文件数会减少,倒排表的个数会减少,这样从数据结构的角度来说可能会有一定压缩的空间,是否有内存的减少其实还需要看数据的情况,如果数据非常的集中,稀疏性没有那么高,内存理论上确实是会占用少一些的,但是如果只是为了减少segment的内存而作optimize就没必要了,optimize是开销很大的操作,不建议都optimize到一个segment,尤其是数据量非常大的时候,这样会产生一个超大文件,会有很多问题,比如在迁移的时候,单个文件没法并发拷贝,无法充分利用系统的资源,或者单块磁盘没有这么大等等,但是optimize也是有意义的,控制好最终的segment大小,通过optimize可以提高查询性能,尤其是分片很多的时候,optimize合并之后可以减少查询打开文件的IO操作,提高查询速度,但是记住一点,optimize的时候,索引写速度会受限制,另外系统开销非常大,这也是为什么后面es对optimize做了一些使用上的限制,避免滥用,另外测试时,在合并前和合并后都执行相同的查询,然后再比较一下内存真实使用量和查询的响应时间会更加有意义。

索引过程中的记录:

可以看到2.0对内存的开销实在是非常的低,在我的12寸的小本上跑一晚上生成这些数据,没有任何问题,ES没有改任何配置,包括HEAP_SIZE。

RUN大量的测试查询,对segment.size.memory没有影响

合并前的索引文件:

查看分片0的segment文件

curl -s “localhost:9200/_cat/segments/year_2014” |grep ‘0 p’

其它shard省略

shard0的size.memory求和:26766512

curl -XPOST “http://localhost:9200/year_2014/_optimize?max_num_segments=1”

重新RUN大量的测试查询,保证流程一致

合并之后的segment信息
http://localhost:9200/_cat/segments/year_2014?v

shard0的size.memory:28030260

size.memory比较:
合并前: 26766512
合并后: 28030260

tm(memory used per index)
合并前:129.1mb
合并后:133mb

测试结果:
数据随机生成,,数据量1亿条,Elasticsearch版本2.0.0,默认分词,针对同一份数据进行合并前后的比较,segment内存占用没有太大的变化。

数据样本:

查询测试脚本

本文来自: 索引optimize究竟是否减少索引内存占用的测试