【问题标题】:Elasticsearch query performanceElasticsearch 查询性能
【发布时间】:2013-08-16 00:46:12
【问题描述】:

我正在使用 elasticsearch 来索引两种类型的对象 -

数据详情

合约对象 ~ 60 个属性(对象大小 - 120 字节) 风险项目对象 ~ 125 个属性(对象大小 - 250 字节)

合同是风险项的父项 (_parent)

我在单个索引中存储了 2.4 亿个此类对象(2.1 亿个风险项,3000 万份合约)

索引大小为 - 322 gb

集群详情

11 m2.4x.large EC2 盒子 [68 GB 内存,1.6 TB 存储,8 核](1 盒子是负载均衡器节点,node.data = false) 50个碎片 1个副本

elasticsearch.yml

node.data: true
http.enabled: false
index.number_of_shards: 50
index.number_of_replicas: 1
index.translog.flush_threshold_ops: 10000
index.merge.policy.use_compound_files: false
indices.memory.index_buffer_size: 30%
index.refresh_interval: 30s
index.store.type: mmapfs
path.data: /data-xvdf,/data-xvdg

我正在使用以下命令启动 elasticsearch 节点 - /home/ec2-user/elasticsearch-0.90.2/bin/elasticsearch -f -Xms30g -Xmx30g

我的问题是我正在对风险项目类型进行以下查询,并且返回数据大约需要 10-15 秒,共 20 条记录。

我正在以 50 个并发用户的负载和大约 5000 个并行发生的风险项的批量索引负载运行此程序。

查询(加入父子)

http://:9200/contractindex/riskitem/_search*

{
    "query": {
        "has_parent": {
            "parent_type": "contract",
            "query": {
                "range": {
                    "ContractDate": {
                        "gte": "2010-01-01"
                    }
                }
            }
        }
    },
    "filter": {
        "and": [{
            "query": {
                "bool": {
                    "must": [{
                        "query_string": {
                            "fields": ["RiskItemProperty1"],
                            "query": "abc"
                        }
                    },
                    {
                        "query_string": {
                            "fields": ["RiskItemProperty2"],
                            "query": "xyz"
                        }
                    }]
                }
            }
        }]
    }
}

一个表的查询

Query1(此查询大约需要 8 秒。)

 <!-- language: lang-json -->

    {
        "query": {
            "constant_score": {
                "filter": {
                    "and": [{
                        "term": {
                            "CommonCharacteristic_BuildingScheme": "BuildingScheme1"
                        }
                    },
                    {
                        "term": {
                            "Address_Admin2Name": "Admin2Name1"
                        }
                    }]
                }
            }
        }
    }



**Query2** (This query takes around 6.5 seconds for Top 10 records ( but has sort on top of it)

 <!-- language: lang-json -->

    {
        "query": {
            "constant_score": {
                "filter": {
                    "and": [{
                        "term": {
                            "Insurer": "Insurer1"
                        }
                    },
                    {
                        "term": {
                            "Status": "Status1"
                        }
                    }]
                }
            }
        }
    }

有人可以帮助我如何提高此查询性能吗?

【问题讨论】:

  • 我也对答案感兴趣。您是否尝试过文档之间的其他类型的关系?我指的是嵌套对象。我可能是错的,但我会说父子关系是一种“查询连接”。嵌套对象位于同一个 Lucene 块中,因此搜索查询可能更快。
  • 我还有一个问题......为什么Xms30g -Xmx30g而不是更多?
  • 对象非常大,嵌套对象会占用大量空间。
  • 此外,当任何子对象发生变化时,它还需要重新索引整个文档,而我们的用例大部分时间子文档都会发生变化
  • 您是否考虑过使用数字过滤器进行日期查询?

标签: elasticsearch


【解决方案1】:

您是否尝试过自定义路由?如果没有自定义路由,您的查询需要在所有 50 个分片中查找您的请求。使用自定义路由,您的查询知道要搜索哪些分片,从而提高查询的性能。更多here

您可以通过在 _routing 字段中包含路由值来为每个批量项目分配自定义路由,如bulk api docs 中所述。

【讨论】:

  • 除了自定义路由,我们还有哪些其他选择?
  • 正如jackdbernier 在他的评论中提到的那样,增加堆大小将有助于提高性能。这个thread 现在已经快一年了,但它的信息可能仍然很好。例如,Elasticsearch 团队在这里建议将 heap_size 设置为总内存的 60%。因此,在您的情况下,请尝试将堆增加到 40g。
  • 我们的正常查询也比较慢,我已经用它编辑了我的帖子。
【解决方案2】:

我们使用位集进行了更改。

我们运行 50 个并发用户(只读)一小时。我们所有查询的执行速度都提高了 4 到 5 倍,但父子查询(有问题的查询)除外,它已从 7 秒下降到 3 秒。

我还有一个包含 has_child 的查询。任何其他人有任何其他反馈,我们可以进一步改进此反馈或其他查询。

{
    "query": {
        "filtered": {
            "query": {
                "bool": {
                    "must": [{
                        "match": {
                            "LineOfBusiness": "LOBValue1"
                        }
                    }]
                }
            },
            "filter": {
                "has_child": {
                    "type": "riskitem",
                    "filter": {
                        "bool": {
                            "must": [{
                                "term": {
                                    "Address_Admin1Name": "Admin1Name1"
                                }
                            }]
                        }
                    }
                }
            }
        }
    }
}

【讨论】:

  • 有人可以评论/帮助吗?
  • 基本上用 BOOL 替换你的 AND/OR 过滤器。利用位集。不知道为什么,但只是这样做,看看它是否更快。
猜你喜欢
  • 2014-04-09
  • 2014-12-25
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 2021-05-06
  • 2021-12-03
  • 1970-01-01
相关资源
最近更新 更多