一般建议
- 不要返回大的结果集
Elasticsearch 作为搜索引擎,适合返回匹配的前N个少量的数据,但是不适合返回大量。如果想全部返回,用 Scroll API - 避免大文档
默认的http.max_content_length设置为100MB,Elasticsearch将拒绝索引任何大于该限制的文档。您可修改该设置,但Lucene仍然有大约2GB的限制。 - 将精确搜索与词干混合
在搜索的时候通常用词干进行搜索,比如搜索skiing
,将会搜索到包含ski
或者 skis
的文档,但是如果用户想精确搜索skiing
呢?要想满足这两个要求,最后用两个字段,一个用户词干的搜索,一个用于精确的搜索。 - 相同的条件,评分排序不对的问题
搜索请求会转发到分片组中的任何一个,假如主分片刚完成合并,而副本还未执行,那么此时分片组中分片之间的文档数量就不同(执行Meger的会删除已经标记删除的文档,没有Merge的不会。而标记为删除的文档,也会影响评分排序),假如两次刚好访问到不同的分片,那么最后的结果也就不同。解决此问题的推荐方法是使用一个标识,详见(preference)。 - 相关性不对
解决办法:a:设置一个分片 b:使用 dfs_query_then_fetch
调整索引速度调整索引速度
调整搜索速度
- 为文件系统缓存提供尽量多的内存
- 使用更快的硬件;SSD CPU...
- 文档建模,避免联合查询(join),嵌套查询,父子关系查询
- 搜索尽可能少的字段;如果经常在几个字段中查询,那么最好把这几个字段整合成一个字段 copy-to
- 预索引数据;比如根据price进行范围聚合查询,那么在索引的时候可以添加一个字段price_range,这样在聚合查询的时候就可以用price_range。这个和搜索模式有很大的关联性。
- 考虑将数字类型映射为关键字;数字类型对于范围查询比较好,关键词查询对于Term查询比较好。
- 避免脚本
- 搜索日期时进行舍入;例如:
"lte": "now"
改为 "lte": "now/m"
,舍入到分钟。用于舍入的间隔越长,查询缓存可以提供的帮助越多,但要注意过于激进的舍入也可能会损害用户体验。 - 强制合并只读索引
- 预加载全局序列;全局序列是一种数据结构,用于在
keyword
字段上运行terms
聚合。它们被懒惰地加载到内存中,您可以通过配置映射来告诉Elasticsearch在刷新时加载哪些全局序数。 - 预热文件系统缓存;使用index.store.preload设置的文件扩展名,您可以明确地告诉操作系统应该将哪些文件加载到内存中。但是如果缓存不足,或者索引太大,那么搜索也会慢,慎用。
- 使用索引排序来加速连词搜索;会使索引速度减慢。详见
- 使用
preference
优化缓存利用率;使用标识可以帮助优化缓存的使用 - 副本可能有助于提高吞吐量,但并非总是如此。更多的副本需要更多的文件系统缓存,而文件系统缓存是搜索性能的第一要素。副本计算公式:max(max_failures, ceil(num_nodes / num_primaries) - 1);max_failures:允许同时挂掉的最多机器;num_nodes:机器总数;num_primaries:主分片数。
- 打开自动副本选择;根据每个分片副本的节点的响应时间,服务时间和队列大小来选择最佳数据副本。
转载于:https://my.oschina.net/5icode/blog/2873043