Большая вычислительная нагрузка в агрегированном скрипте metri c в Elasticsearch - PullRequest
0 голосов
/ 23 января 2020

У меня следующая проблема. Я индексирую документы в Elasticsearch, где каждый документ представлен списком элементов (в моем случае целые числа), длина списка может варьироваться между документами. Например, doc1: [1,2,5], doc2: [2,3,5,6] и др. c. Соответствующее поле называется items . Затем я выполняю агрегацию метри c с помощью сценария следующим образом:

metrics = es.search(index=index, body= 
    {"query" : {
        "match_all" : {}
        },
            "aggs": {
                "frequent_pairs": {
                    "scripted_metric": {
                        "init_script" : "state.transactions = [];",
                        "map_script" : "state.transactions.add([params['_source']['items']);", 
                        "combine_script" : naive_script, 
                        "reduce_script" : reduce_cnt
            }
        }
    }
})

Отображение просто распределяет различные списки элементов по разным шардам. Затем мне нужно выполнить тяжелые вычисления в каждом шарде, а именно вычислить все подмножества размера 3 в каждом документе и подсчитать их количество в шарде на карте ha sh. (Я знаю, ElasticSearch не предназначен для такого рода вычислений, но он мне нужен для приложения.)

Но это работает только тогда, когда либо списки документов короткие, либо общее количество документов мало , Что происходит, так это то, что многие осколки не сообщают о результатах. Я уже увеличил пространство кучи до 8 ГБ, назначил больше шардов и увеличил значение тайм-аута:

es = Elasticsearch([{'host':'localhost','port':9200, 'timeout': 1000000, "max_retries":10, "retry_on_timeout":True}])

Это в некоторой степени улучшило результаты, но все же многие шарды не возвращают никаких результатов и точной настройки параметры не помогают. Есть ли какое-либо решение или ES не следует использовать для таких дорогих вычислений? Я использую ES 7.5.2, и я буду рад предоставить более подробную информацию по запросу.

naive_script = """
HashMap itemsets = new HashMap(); 
    int nr_trans = 0;
    for (t in state.transactions){ 
        nr_trans += 1;
        int l = t.length;
        for (int i=0; i<l; i++){
            for (int j = i+1; j<l; j++){
                for (int k = j+1; k < l; k++){
                    String s = Integer.toString(t[i]) + "," + Integer.toString(t[j]) + "," + Integer.toString(t[k]) + ",";
                    int val = 0;
                    if (itemsets.containsKey(s)){
                        val = itemsets.get(s);
                    }
                    itemsets.put(s, val + 1);
                }
            }
        }
    }
    def res = [];
    res.add(itemsets);
    res.add(nr_trans);
    return res;//itemsets;
"""

1 Ответ

1 голос
/ 24 января 2020

Проблема в том, что безболезненный язык сценариев позволяет выполнять только до 1 000 000 операторов в oop. Обсуждается решение, позволяющее пользователю изменять настройки на уровне кластера, но, по-видимому, оно еще не выпущено: https://github.com/elastic/elasticsearch/issues/28946 Кто-нибудь знает что-то еще об этом или как-то наоборот? Я постараюсь узнать больше информации и опубликую ее здесь, если мне это удастся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...