Elasticsearch严重依赖于文件系统缓存,以加快搜索速度。一般,您应确保至少有一半的可用内存分配给文件系统缓存,以便Elasticsearch能够将索引的热区保留在物理内存中。node
若是搜索是受CPU限制的,那就加大CPU。ES对CPU的要求,使用多核CPU优于单核CPU。算法
若是搜索是在I/O上受限制的话,就须要提供更多的内存和更快的硬盘。SSD硬盘性能优于机械硬盘,本地硬盘性能优于远程虚拟硬盘。express
文档应该建模设计,是搜索尽量的快。避免使用 nested(慢几倍)和父子关系(慢百倍),能够经过对文档进行非规范化的建模设计来达到相同的目的,解决问题。缓存
query_string
或 multi_match
查询目标的字段越多,它的速度就越慢。数据结构
您应该利用查询中的模式来优化数据索引的方式。例如:你有一个类型的文档全部文档都包含一个字段 price
,而且你大多数查询的时候都是使用比较固定的大小范围查询或者聚合,此时若是把这个时间分为预索引到文档中,而且使用terms
聚合查询会更快。app
例如,你有一类型的数据以下less
PUT index/_doc/1 { "designation": "spoon", "price": 13 }
而且你搜索的时候常用如下范围查询elasticsearch
GET index/_search { "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 10 }, { "from": 10, "to": 100 }, { "from": 100 } ] } } } }
此时你就应该在文档索引时添加一个price_range
字段,而且映射成keyword类型的性能
PUT index { "mappings": { "_doc": { "properties": { "price_range": { "type": "keyword" } } } } } PUT index/_doc/1 { "designation": "spoon", "price": 13, "price_range": "10-100" }
而后查询、聚合的时候就使用这个新的字段来代替price
的range
聚合优化
GET index/_search { "aggs": { "price_ranges": { "terms": { "field": "price_range" } } } }
有些字段虽然是数字类型的,可是实际上并非都要映射为数字类型。ES可以经过数字类型优化range
查询,可是terms
查询使用keyword
更适合。通常的像ISBN(国际标准书号)这样的标识符(ID)都是适合映射为keyword
而不是数字的。
一般,应避免使用脚本。若是绝对须要它们,则应首选painless和expressions引擎。
对日期字段的查询now
一般是不可缓存的,由于匹配一直是在变化的。可是,就用户体验而言,切换到舍入日期一般是能够接受的,而且具备更好地利用查询缓存的好处。
例以下面的查询
PUT index/_doc/1 { "my_date": "2016-05-11T16:30:55.328Z" } GET index/_search { "query": { "constant_score": { "filter": { "range": { "my_date": { "gte": "now-1h", "lte": "now" } } } } } }
可使用下面的查询代替
GET index/_search { "query": { "constant_score": { "filter": { "range": { "my_date": { "gte": "now-1h/m", "lte": "now/m" } } } } } }
在这种状况下,咱们四舍五入为分钟,所以,若是当前时间为16:31:29
,则范围查询将匹配my_date
字段值介于15:31:00
和16:31:59
之间的全部内容。并且,若是多个用户在同一分钟内运行包含此范围的查询,则查询缓存能够帮助加快速度。用于舍入的时间间隔越长,查询缓存能够提供的帮助越多,可是请注意,过于激进的舍入也会损害用户体验。
只读的索引将从合并到单个段中受益 。对于基于时间的索引,一般是这种状况:只有当前时间范围的索引才能获取新文档,而较旧的索引则为只读。
提示
不要合并正在写入的索引。
全局序数词是一种数据结构,用于在keyword
字段上运行terms
聚合 。它们被延迟加载到内存中,由于Elasticsearch不知道terms
聚合中将使用哪些字段,而哪些字段则不会。您能够经过以下所述配置映射,让Elasticsearch在刷新时紧急加载全局序数词:
PUT index { "mappings": { "_doc": { "properties": { "foo": { "type": "keyword", "eager_global_ordinals": true } } } } }
若是从新启动运行Elasticsearch的计算机,则文件系统缓存将为空,所以,操做系统须要一些时间才能将索引的热区加载到内存中,以便快速进行搜索操做。您可使用该index.store.preload
设置明确告诉操做系统哪些文件应该急切地加载到内存中,具体取决于文件扩展名 。
索引排序可能有用,以便使链接更快,但以稍微慢一些的索引为代价。在索引排序文档中阅读有关它的更多信息。
有多个能够帮助提升搜索性能的缓存,例如 文件系统缓存, 请求缓存或查询缓存。可是全部这些缓存都在节点级别维护,这意味着若是您连续两次运行相同的请求,具备一个或多个副本,并使用默认路由算法round-robin,则这两个请求将转到不一样的分片副本,从而阻止了节点级缓存的帮助。
因为搜索应用程序的用户一般会依次运行相似的请求(例如为了分析索引的较窄子集),所以使用标识当前用户或会话的首选项值能够帮助优化缓存的使用。
除了提升弹性以外,副本还能够帮助提升吞吐量。例如,若是您有一个单碎片索引和三个节点,则须要将副本数设置为2,以便总共拥有3个碎片副本,以便利用全部节点。
如今,假设您有一个2碎片索引和两个节点。在一种状况下,副本数为0,这意味着每一个节点都拥有一个分片。在第二种状况下,副本数为1,这意味着每一个节点都有两个分片。哪一种设置在搜索效果方面效果最好?一般,每一个节点的分片总数较少的设置会更好地执行。这样作的缘由是,它为每一个分片提供了更多的可用文件系统缓存份额,而且文件系统缓存多是Elasticsearch的第一性能因素。同时,请注意,在单节点故障的状况下,没有副本的安装会失败,所以在吞吐量和可用性之间要进行权衡。
那么正确的副本数是多少?若是您的集群中有num_nodes节点,则总共有 num_primaries主要分片,而且若是您但愿max_failures一次最多能处理节点故障,那么适合您的副本数是 max(max_failures, ceil(num_nodes / num_primaries) - 1)。
当存在多个数据副本时,elasticsearch可使用一组称为自适应副本选择的条件来根据响应时间,服务时间和包含每一个碎片副本的节点的队列大小来选择最佳数据副本。这能够提升查询吞吐量并减小大量搜索应用程序的延迟。