ElasticSearch медленно извлекает документы - PullRequest
2 голосов
/ 11 июля 2019

Я использую Java_API для извлечения записей из ElasticSearch, для извлечения 100000 документов (запись / строка) в приложении Java требуется примерно 5 секунд.

Это медленно для ElasticSearch?или это нормально?

Вот настройки индекса:

enter image description here

Я пытался повысить производительность, но безрезультатно, вот что я сделал:

  • Установите для кучи ElasticSearch значение 3 ГБ, оно было 1 ГБ (по умолчанию) -Xms3g -Xmx3g

  • Миграция ElasticSearch на SSD с 7200 об / мин HardДиск

  • Извлечение только одного файла вместо 30

Вот мой код реализации Java

private void getDocuments() {
        int counter = 1;
        try {
            lgg.info("started");
            TransportClient client = new PreBuiltTransportClient(Settings.EMPTY)
                    .addTransportAddress(new TransportAddress(InetAddress.getByName("localhost"), 9300));

            SearchResponse scrollResp = client.prepareSearch("ebpp_payments_union").setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
                    .setQuery(QueryBuilders.matchAllQuery())                 
                    .setScroll(new TimeValue(1000))
                    .setFetchSource(new String[] { "payment_id" }, null)
                    .setSize(10000)
                    .get();

            do {
                for (SearchHit hit : scrollResp.getHits().getHits()) {
                    if (counter % 100000 == 0) {
                        lgg.info(counter + "--" + hit.getSourceAsString());
                    }
                    counter++;
                }

                scrollResp = client.prepareSearchScroll(scrollResp.getScrollId())
                        .setScroll(new TimeValue(60000))
                        .execute()
                        .actionGet();
            } while (scrollResp.getHits().getHits().length != 0);

            client.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

Я знаю, что TransportClient устарело, я пробовал также RestHighLevelClient, но это ничего не меняет.

Знаете ли вы, как получить лучшую производительность?

Должен ли я что-то изменить в ElasticSearch или изменить свой код Java?

Ответы [ 2 ]

1 голос
/ 15 июля 2019

Я вижу три возможных оси для оптимизации:

1 / сортировка документов по ключу _doc:

Запросы прокрутки имеют оптимизации, которые делают их быстрее при сортировке заказ _док. Если вы хотите перебрать все документы независимо от порядок, это наиболее эффективный вариант:

( источник документации )

2 / уменьшите размер страницы, 10000 кажется высоким значением. Можете ли вы сделать дифференциальный тест с уменьшенными значениями, такими как 5000/1000?

3 / Убрать фильтрацию источника

.setFetchSource (new String [] {"payment_id"}, null)

Выполнение фильтрации источника может быть затруднено, поскольку узлу упругости необходимо прочитать источник, преобразовать его в объект и затем отфильтровать. Так вы можете попытаться удалить это? Загрузка сети увеличится, но это сделка:)

1 голос
/ 11 июля 2019

Устранение неполадок и настройка производительности сложно сделать без понимания всего, что с этим связано, но это не кажется слишком быстрым. Поскольку это кластер из одного узла, вы столкнетесь с некоторыми проблемами с производительностью. Если бы это был производственный кластер, у вас было бы по крайней мере реплика для каждого шарда, который также можно использовать для чтения.

Несколько других вещей, которые вы можете сделать:

  • Индексируйте ваши документы на основе вашего наиболее часто просматриваемого атрибута - при этом все документы с одинаковым атрибутом будут записываться в один и тот же шард, поэтому ES будет меньше читать (это не поможет, так как у вас есть один шард)
  • Добавление нескольких осколков реплики, чтобы вы могли распределять чтения между узлами в кластере (опять же, на самом деле необходимо иметь кластер)
  • Не используйте главную роль в тех же блоках, что и ваши данные - если у вас средний или большой кластер, у вас должны быть поля, которые не master или data, но являются блоками, к которым ваше приложение подключается поэтому они могут управлять мета-работой для поиска и позволять узлам данных фокусироваться на данных.
  • Используйте «query_then_fetch» ​​- если вы не используете взвешенный поиск, то вам, вероятно, следует придерживаться DFS.
...