Как правильно приготовить питоном параллельную индексацию в ElasticSearch?
Есть задача - максимально быстро создать индекс в Elasticsearch.
На входе - данные, приготовленные питоном.
На выходе - созданный с нуля индекс.
Инфраструктура пока самая простая - один нод ES, один индекс, один шард без реплик.
Данных немного, 100К документов, но есть геоданные, ES индексирует единицы документов в секунду.
Кормление ES идет с помощью elasticutils в цикле (т.е. синхронно) в bulk режиме.
Проблема - построение индекса занимает 10 часов, хотелось бы время уменьшить в разы (целевое значение - 1 час).
При этом инфраструктура не упирается ни в CPU, ни в память, ни в IO.
Из 8 ядер, которые сейчас выделены на этот сервер, в среднем нагружены 2.
IO не проседает, загрузка в районе 0.
Памяти выделено 18GB, свободно в среднем 8GB, т.е. тоже всё ок.
Т.е. получается, что проблема не в инфраструктуре, а в настройках всей связки индексации.
Потенциальные места для улучшений:
1) из питона кормить ES асинхронно (например, с помощью celery)
2) оптимизировать структуру хранения индекса в ES (много шардов, etc)
3) оптимизировать настройки ES (хз что тут можно улучшить, пулы и так есть в избытке)
Как думаете, в какие направления лучше всего копать?
index_concurrency смотрели? По идее должно быть 8 и 8 ядер нагружены. index.merge.scheduler.max_thread_count вроде как если у вас нет затыка по IO то можно наращивать.
Кстати странно. У меня в ES (по ошибке) приходило 1-2к логов (документов) в секунду. Сервер был слабенький но удар спокойно держал. Правда индекс считался раз в сутки и я не заметил как что и как с ним было. Удалил все лишнее без разборов.
Единственное, что хоть как-то помогло загрузить все ядра - это увеличение кол-ва шардов (был один, стало 4).
Большее кол-во шардов не дает прироста, меньшее - не загружает все ядра.
При этом так до конца и не понял, почему. Т.е. в принципе можно попробовать обьяснить - могут быть блокировки шардов на запись при индексации, но вроде как по доке такого поведения быть не должно.
100 тыс документов это совсем не много.
Я до 250 тыс индексировал, индексация занимает всего несколько минут на слабеньком VDS. (про геоданные не в курсе)
Какой у вас сердний размер документа? Вы все поля индексируете?
Я при создании индекса указываю
Вопрос был не в том, как ускорить индексацию одного документа, а как ускорить индексацию большого пакета данных за счет более оптимальной загрузки имеющихся мощностей (которые явно не упираются ни в один из понятных мне инфраструктурных ограничений).
Если говорить о том, как мы кормим индекс - да, у нас есть вариант, описанный вами - отключает рефреш индекса, чтобы он не подготавливал его к поиску при загрузке каждого документа.
Что касается такой медленной скорости обработки документа - да, там подавляющее время занимает довольно аккуратный геоиндекс, если его убрать или сильно загрубить - время индексации падает на несколько порядков.