如何在 Vespa 上快速聚合?

How to make aggregations fast on Vespa?

我们的一个索引中有 60M 个文档。托管在 4 节点集群上。

我想确保配置针对文档的聚合进行了优化。

这是示例查询:

select * from sources * where (sddocname contains ([{"implicitTransforms": false}]"tweet")) | all(group(n_tA_c) each(output(count() as(count))));

字段 n_tA_c 包含字符串数组。这是示例文档:

        {
            "fields": {
                "add_gsOrd": 63829,
                "documentid": "id:firehose:tweet::815347045032742912",
                "foC": 467,
                "frC": 315,
                "g": 0,
                "ln": "en",
                "m": "ya just wants some fried rice",
                "mTp": 2,
                "n_c_p": [],
                "n_tA_c": [                        
                    "fried",
                    "rice"
                ],
                "n_tA_s": [],
                "n_tA_tC": [],
                "sN": "long_delaney1",
                "sT_dlC": 0,
                "sT_fC": 0,
                "sT_lAT": 0,
                "sT_qC": 0,
                "sT_r": 0.0,
                "sT_rC": 467,
                "sT_rpC": 0,
                "sT_rtC": 0,
                "sT_vC": 0,
                "sddocname": "tweet",
                "t": 1483228858608,
                "u": 377606303,
                "v": "false"
            },
            "id": "id:firehose:tweet::815347045032742912",
            "relevance": 0.0,
            "source": "content-root-cluster"
        }

n_tA_c 属性的模式为 fast-search

    field n_tA_c type array<string> {
        indexing: summary | attribute
        attribute: fast-search
    }

简单词聚合查询20s不回来。并且超时。我们需要确保减少延迟的额外检查清单是什么?

$ curl 'http://localhost:8080/search/?yql=select%20*%20from%20sources%20*%20where%20(sddocname%20contains%20(%5B%7B%22implicitTransforms%22%3A%20false%7D%5D%22tweet%22))%20%7C%20all(group(n_tA_c)%20each(output(count()%20as(count))))%3B' | python -m json.tool
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100   270  100   270    0     0     13      0  0:00:20  0:00:20 --:--:--    67
    {
        "root": {
            "children": [
                {
                    "continuation": {
                        "this": ""
                    },
                    "id": "group:root:0",
                    "relevance": 1.0
                }
            ],
            "errors": [
                {
                    "code": 12,
                    "message": "Timeout while waiting for sc0.num0",
                    "source": "content-root-cluster",
                    "summary": "Timed out"
                }
            ],
            "fields": {
                "totalCount": 0
            },
            "id": "toplevel",
            "relevance": 1.0
        }
    }

这些节点是 aws i3.4x 大盒子。(16 核,120 GB)

我可能会遗漏一些愚蠢的东西。

您要求每个唯一值及其 count(),因为您的分组表达式不包含任何 max(x) 限制,这是一个非常 cpu 和网络密集型任务来计算和限制组要​​快得多,例如

all(group(n_tA_c) max(10) each(output(count() as(count))));

一般评论: 与任何其他服务引擎一样,使用 vespa 时,重要的是要有足够的内存,例如禁用交换,这样您就可以索引和搜索数据而不会遇到高内存压力。

每种文档类型将使用多少内存取决于多个因素,但是使用属性定义的字段数量和每个节点的文档数量很重要。冗余和可搜索副本的数量也起着重要作用。

对整个语料库进行分组是内存密集型的(内存带宽读取属性值),cpu 密集型,当存在高扇出时也是网络密集型的(在此处查看更多关于精度的信息 http://docs.vespa.ai/documentation/grouping.html 这可以限制每个节点返回的组数)。

在从其他答案和更多文档帮助中的对话中汇总要注意的检查点。

<persearch>16</persearch>

线程数 persearch 默认为 1。

以上更改,确保查询在超时前返回结果。但了解到 Vespa 不是为具有主要目标的聚合而设计的。写入和搜索的延迟远低于在相同硬件上具有相同规模的 ES。但是对于相同的聚合查询,与 ES 相比,聚合(特别是多值字符串字段)更 CPU 密集且延迟更多。