ES索引优化

ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡。所以从上我可以通过索引的settings进行第一优化: 
“index.translog.flush_threshold_ops”: “100000″ 
“index.refresh_interval”: “-1″, 
这两个参数第一是到tranlog数据达到多少条进行平衡,默认为5000,而这个过程相对而言是比较浪费时间和资源的。所以我们可以将这个值调大一些还是设为-1关闭,进而手动进行tranlog平衡。第二参数是刷新频率,默认为120s是指索引在生命周期内定时刷新,一但有数据进来能refresh像lucene里面commit,我们知道当数据addDoucment会,还不能检索到要commit之后才能行数据的检索所以可以将其关闭,在最初索引完后手动refresh一之,然后将索引setting里面的index.refresh_interval参数按需求进行修改,从而可以提高索引过程效率。 
另外的知道ES索引过程中如果有副本存在,数据也会马上同步到副本中去。我个人建议在索引过程中将副本数设为0,待索引完成后将副本数按需量改回来,这样也可以提高索引效率。 
“number_of_replicas”: 0 
上面聊了一次索引过程的优化之后,我们再来聊一下检索速度比较慢的问题,其实检索速度快度与索引质量有很大的关系。而索引质量的好坏与很多因素有关。 

一、数据结构优化 

1、尽量减少不需要的字段 
ElasticSearch中存储的数据是用于搜索服务,因此其他一些不需要用于搜索的字段最好不存到ES中,这样即节省空间,同时在相同的数据量下,也能提高搜索性能。 
2、routing值的设置 
通常情况下,往ElasticSearch服务器添加索引数据时,是无需指定routing值。ElasticSearch会根据索引Id,将该条数据存储到ElasticSearch集群中的一个shard中。而当指定了routing值为accountId(用户Id),则ElasticSearch会将相同accountId的多个数据都存放到同一个shard中,后续查询的时候,在指定routing值后,ElasticSearch只需要查询一个shard就能得到所有需要的数据,而不用再去查询所有的shard,从而大大提供了搜索性能。

二、分片数和副本数

分片数,与检索速度非常相关的的指标,如果分片数过少或过多都会导致检索比较慢。分片数过多会导致检索时打开比较多的文件别外也会导致多台服务器之间通讯。而分片数过少为导至单个分片索引过大,所以检索速度慢。 
在确定分片数之前需要进行单服务单索引单分片的测试。比如我之前在IBM-3650的机器上,创建一个索引,该索引只有一个分片,分别在不同数据量的情况下进行检索速度测试。最后测出单个分片的内容为20G。 
所以索引分片数=数据总量/单分片数 
目前,我们数据量为4亿多条,索引大小为近1.5T左右。因为是文档数据所以单数据都中8K以前。现在检索速度保证在100ms 以下。特别情况在500ms以下,做200,400,800,1000,1000+用户长时间并发测试时最坏在750ms以下. 


副本数与索引的稳定性有比较大的关系,怎么说,如果ES在非正常挂了,经常会导致分片丢失,为了保证这些数据的完整性,可以通过副本来解决这个问题。建议在建完索引后在执行Optimize后,马上将副本数调整过来。 
大家经常有一个误去副本越多,检索越快,这是不对的,副本对于检索速度其它是减无增的我曾做过实现,随副本数的增加检索速度会有微量的下降,所以大家在设置副本数时,需要找一个平衡值。另外设置副本后,大家有可能会出现两次相同检索,出现出现不同值的情况,这里可能是由于tranlog没有平衡、或是分片路由的问题,可以通过?preference=_primary 让检索在主片分上进行。 

三、分词 

其实分词对于索引的影响可大可小,看自己把握。大家越许认为词库的越多,分词效果越好,索引质量越好,其实不然。分词有很多算法,大部分基于词表进行分词。也就是说词表的大小决定索引大小。所以分词与索引膨涨率有直接链接。词表不应很多,而对文档相关特征性较强的即可。比如论文的数据进行建索引,分词的词表与论文的特征越相似,词表数量越小,在保证查全查准的情况下,索引的大小可以减少很多。索引大小减少了,那么检索速度也就提高了。 

四、索引段 

索引段即lucene中的segments概念,我们知道ES索引过程中会refresh和tranlog也就是说我们在索引过程中segments number不至一个。而segments number与检索是有直接联系的,segments number越多检索越慢,而将segments numbers 有可能的情况下保证为1这将可以提到将近一半的检索速度。 
$ curl -XPOST ‘  http://localhost:9200/twitter/_optimize? max_num_segments =1′ 

五、删除文档 

删除文档在Lucene中删除文档,数据不会马上进行硬盘上除去,而进在lucene索引中产生一个.del的文件,而在检索过程中这部分数据也会参与检索,lucene在检索过程会判断是否删除了,如果删除了在过滤掉。这样也会降低检索效率。所以可以执行清除删除文档。 
$ curl -XPOST ‘  http://localhost:9200/twitter/_optimize? only_expunge_deletes =true 

 

$ curl -XPOST 'http://localhost:9200/twitter/_optimize'
 

六、管理索引优化

 
optimize API允许通过API优化一个或多个索引。优化过程的操作基本上优化的索引搜索速度更快(和涉及到Lucene索引内保存每个碎片的段数)。优化操作允许减少的段数,把它们合并。

 

$ curl -XPOST 'http://localhost:9200/creative_query/_optimize' 

 

名称 描述
max_num_segments

段数优化。要全面优化索引,将其设置为 1。默认设置只需检查是否需要执行一个合并,如果是这样,执行它

。【经过测试越小速度越快】

only_expunge_deletes优化过程中应该只抹去段删除。在Lucene中,不会被删除的文件从段,只是标记为删除。分部在合并过程中,创建一个新的分部,没有那些删除。此标志只允许合并段删除。默认为 false。【设置为true docs才会合并】
refresh如果刷新后进行优化。默认为 true
flush如果冲洗后进行优化。默认为 true
wait_for_merge申请应等待合并结束。默认为 true。注意,合并有可能是一个非常繁重的操作,所以它可能是有意义运行它设置为 。【最好设置为false,默认true请求就会阻塞在那里,直到完成】 

优化API一个调用,可以应用到多个索引,或者所有索引

 

 

$ curl -XPOST 'http://localhost:9200/kimchy,elasticsearch/_optimize'

$ curl -XPOST 'http://localhost:9200/_optimize'

参数使用方法: http://localhost:9200/indexName/_optimize?only_expunge_deletes=true&wait_for_merge=false 

 

1. 多线程程序插入,可以根据服务器情况开启多个线程index  

速度可以提高n倍, n>=2  

2. 如果有多台机器,可以以每台设置n个shards的方式,根据业务情况,可以考虑取消replias  

curl -XPUT 'http://10.1.*.*:9200/dw-search/' -d '{  
    "settings" : {  
        "number_of_shards" : 20,  
        "number_of_replicas" : 0  
    }  
}'  
这里设置20个shards, 复制为0,如果需要replicas,可以完成index后再修改为replicas>=1  
原文:http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index.html  

3. 提高ES占用内存  

内存适当调大,初始是256M, 最大1G,  
调大后,最小和最大一样,避免GC, 并根据机器情况,设置内存大小,  
$ bin/elasticsearch -f -Xmx4g -Xms4g -Des.index.storage.type=memory  
原文:http://www.elasticsearch.org/guide/reference/setup/installation.html  

4. 减少shard刷新间隔  

curl -XPUT 'http://10.1.*.*:9200/dw-search/_settings' -d '{  
    "index" : {  
        "refresh_interval" : "-1"  
    }  
}'  

完成bulk插入后再修改为初始值  
curl -XPUT 'http://10.1.*.*:9200/dw-search/_settings' -d '{  
    "index" : {  
        "refresh_interval" : "1s"  
    }  
}'  

5. 设置一个shard的段segment最大数  

可以减少段文件数,提高查询速度  
curl -XPOST 'http://10.1.*.*:9200/dw-search/_optimize?max_num_segments=5'  
注意:有时候可能需要多次执行  
原文:http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings.html  
原文:http://www.elasticsearch.org/guide/reference/index-modules/merge.html  

6. 去掉mapping中_all域  

Index中默认会有_all的域,这个会给查询带来方便,但是会增加索引时间和索引尺寸  
"_all" : {"enabled" : false}  
原文:http://www.elasticsearch.org/guide/reference/mapping/all-field.html  
curl -XPOST 'http://10.1.*.*:9200/dw-search/pt_normal/_mapping' --data-binary @pt_normal_properties.mapping  

7. 设置source为压缩模式或者disable  

compress=true这个能大大减少index的尺寸  
disable将直接没有_source域  

8. 增加merge.policy.merge_factor数  

设置merge.policy.merge_factor到30,初始是10  
增加这个数需要更多的内存,bulk index可以调大这个值.  
如果是即时索引,应该调小这个值  

原文:http://www.elasticsearch.org/guide/reference/index-modules/merge.html 

9. 修改Client获得方式

Node node = nodeBuilder().client(true).node(); 
Client client = node.client() 
相比transport client更快 
测试效果,速度提高不明朗,且报错。去除 

10. warmers 


当ElasticSearch服务器启动之后,业务系统中要使用的索引数据暂时没有导入到内存中,因此当用户进行第一次数据搜索时,会因为数据导入耗时很久,而严重影响用户的使用体验。为了解决该问题,可以使用warmer工具。通过ElastiSearch提供的工具,可以register/delete/get特定名称的warmer。通常情况下,warmer包含的请求需要载入大量的索引数据(例如在数据搜索中需要针对特定字段的排序操作,或者用到一些聚合sum,min,max函数的查询等),这样才能达到预热的效果。 
具体调用示例如下(下面的warmer是针对索引名为test的warmer,warmer定义的名字为warmer_1): 
curl -XPUT localhost:9200/test/_warmer/warmer_1 -d '{ 
    "query" : { 
        "match_all" : {} 
    }, 
    "aggs" : { 
        "aggs_1" : { 
            "terms" : { 
                "field" : "field" 
            } 
        } 
    } 
}' 


七、设置Filter cache

缓存是提高性能的很重要的手段,es中的filter cache能够把搜索时的filter条件的结果进行缓存,当进行相同的filter搜索时(query不同,filter条件相同),es能够很快的返回结果。这是因为第一次计算完filter后,es就把结果存储到了缓存中,下次搜索时,es就不用再计算。

Es的filter cache有两种,一种是node级别的cache(filter cache默认类型),一种是index级别的filter cache。Node级别的cache被整个node共享,并且可以使用百分比设置,对应的属性为 indices.cache.filter.size,这个属性的值可以是百分比,也可以是具体的大小。Index级别的cache,顾名思义,就是针对单个索引的大小。Es官方并不推荐使用这种设置,因为谁也无法预测索引级别的缓存到底有多大(可能非常大,超过了node的对内存),一个索引可能分布在多个node上面,而多个node的结果如果汇总到一个node上,其结果可想而知。

八、设置Field cache


当对字段排序或者对字段做聚合(如facet)时,字段缓存(Field cache)非常重要。Es会将这些待排序或者聚合字段都加载到内存,以提高对这些字段的快速访问。注意,将字段都加载到内存是非常耗费资源的,所以,你应该保证field cache足够大,以足以将所有的结果都缓存起来,下次排序或facet时不用再次从磁盘进行加载。


可以通过设置 indices.fielddata.cache.size为具体的大小,比如2GB,或者可用内存的百分比,比如40%。请注意,这个属性是node级别(不是index级别的).当这个缓存不够用时,为了跟新的缓存对象腾出空间,原来缓存的字段会被挤出来,这会导致系统性能下降。所以,请保证这个值足够大,能够满足业务需求。另外,如果你没有设置这个值,es默认缓存可以无限大。所以,在生产环境注意要设置这个值。

同时,我们也可以为field cache指定过期时间,系统默认缓存不过期。可以通过设置indices.fielddata.cache.expire为10m,表示缓存10分钟过期。Es建议,最好不要设置过期时间,因为将字段加载到内存是很浪费资源的。


九、设置circuit breaker

Circuit breaker,断路器。这个和field cache有关系。断路器可以估算待加载的field的大小。通过断路器,可以防止将特别大的field加载到内存,导致内存溢出。断路器发现待加载的filed超过java的对内存时,会产生一个异常,防止field的继续加载,从而起到保护系统的作用。有两个属性可以设置断路器,一个是 indices.fielddata.breaker.limit,这个值默认是80%。这个值可以动态修改,通过集群设置的api就可以修改。80%就是说,当待加载的field超过es可用堆内存的80%时,就会抛一个异常。

另一个属性是 indices.fielddata.breaker.overhead,默认值为1.03,es将使用这个值乘以field实际的大小作Field估算值。


十、设置Index Buffers

indices.memory.index_buffer _size,这个值默认为10%,即堆内存的10%会被用作index时的缓存,这个值可以设置百分比也可以是固定的大小。缓冲自然是越大越好。但记得千万不能超过可用的对内存,并且要跟filter cache和filed cache保证在一个合理的比例。



十一、设置Index Refresh rate(索引刷新频率)

index.refresh_interval,默认为1秒。即被索引的数据,1秒之后才能够被搜索到。这个时间越小,搜索和索引的性能就越低。这个时间越大,索引和搜索的性能就越高。es建议,在bulk index非常大的索引数据时,将此值设置为-1,索引完毕之后再将此值修改回来。


十二、综合考虑

记住,对ES来说,缓存(caches)与缓冲(buffers)是提高索引(index)和搜索(query)性能的关键因素。

 

在我们优化es之前,我们必须时刻牢记一点,es需要足够多的内存,越多越好。但是,也不能把所有的内存都分配给es。分配给es的内存最好是保持在物理内存的50-60%左右,因为os也需要内存支持用户进程,比如分配线程,io缓存等。但是,物理内存的50-60%也不是唯一标准。假如你的内存有256G,即便和OS预留10%的内存,也有25G,足够操作系统使用。另外,最好设置Xmx和Xms一样大,避免heap size的resizing。

做性能测试时,在相同的情形下,测试结果应该是可以重现的。你做的任何参数的修改,都应该使用进行性能测试,看性能是否有所提高。以性能测试为检验标准,是我们进行优化的必要前提。


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值