我们有一个双节点集群(私有云中的VM,64GB内存,每个节点8个核心CPU,CentOS),一些小索引(~1万个文档)和一个带有~220万个文档的大索引(2个)碎片,170GB的空间)。 24GB内存分配给每个盒子上的弹性搜索。
文件结构:
{
'article_id': {
'index': 'not_analyzed',
'store': 'yes',
'type': 'long'
},
'feed_id': {
'index': 'not_analyzed',
'store': 'yes',
'type': 'string'
},
'title': {
'index': 'analyzed',
'type': 'string'
},
'content': {
'index': 'analyzed',
'type': 'string'
},
'lang': {
'index': 'not_analyzed',
'type': 'string'
}
}
运行以下查询大约需要1-2秒:
{
"query" : {
"multi_match" : {
"query" : "some search term",
"fields" : [ "title", "content" ],
"type": "phrase_prefix"
}
},
"size": 20,
"fields" :["article_id", "feed_id"]
}
我们此时是否达到了硬件限制,或者是否有办法优化查询或数据结构以提高性能?
提前致谢!
答案 0 :(得分:6)
您可能会遇到硬件的限制,但您可以先对查询进行一些操作以帮助优化它。
最大扩展
我要做的第一件事是限制max_expansions
。前缀查询的工作方式是生成与查询中的最后一个标记匹配的前缀列表。在您的搜索查询“某个搜索字词”中,最后一个标记“term”将使用“term”作为前缀种子进行扩展。您可以生成如下列表:
前缀扩展流程在您的发布列表中运行,查找与种子前缀匹配的任何单词。默认情况下,此列表是无限制的,这意味着您可以生成非常大的扩展列表。
第二阶段使用扩展将原始查询重写为一系列term
个查询。扩展列表越大,根据索引评估的术语越多,速度也相应降低。
如果将扩展过程限制在合理的范围内,则可以保持速度并且通常仍然可以获得良好的前缀匹配:
{
"query" : {
"multi_match" : {
"query" : "some search term",
"fields" : [ "title", "content" ],
"type": "phrase_prefix",
"max_expansions" : 100
}
},
"size": 20,
"fields" :["article_id", "feed_id"],
}
你必须玩你想要多少次扩展。这是速度和召回之间的权衡。
<强>过滤强>
通常,您可以添加的另一件事是过滤。如果您可以过滤某些类型的标准,则可以大幅提高速度。目前,您的查询正在针对整个索引(250米文档)执行,这需要进行大量评估。如果您可以添加减少该数字的过滤器,您可以看到大大改善的延迟。
在一天结束时,查询评估的文档越少,查询运行得越快。过滤器会减少查询将看到的文档数,缓存数,运行速度等等。
您的情况可能没有任何适用的过滤器,但如果确实如此,它们确实可以提供帮助!
文件系统缓存
这个建议完全取决于系统的其他部分。如果您没有充分利用堆(24gb),因为您正在进行简单的搜索和过滤(例如,不进行faceting / geo / heavy Sorts / scripts),您可以将堆重新分配给文件系统缓存。
例如,如果最大堆使用率达到12gb,那么将堆大小减少到15gb可能是有意义的。您释放的额外10gb将返回操作系统并帮助缓存段,这将有助于提高搜索性能,只需更多操作无盘。