Как улучшить параллелизм из кода Python для упругой вставки? - PullRequest
0 голосов
/ 02 марта 2019

Я получил несколько документов (размером около 300o/doc), которые я хотел бы вставить в свой индекс ES с помощью библиотеки python, я получил огромную разницу во времени между кодом и использованием curl, очевидно, что это нормально, ноХотелось бы знать, можно ли улучшить время (по сравнению с соотношением времени) * Опция

  1. curl занимает около 20сек для вставки и все время 10сек (для печати результата ES, но после вставки 20секундных данных)

    curl -H "Content-Type: application/json" -XPOST 
            "localhost:9200/contentindex/doc/_bulk?" --data-binary @superfile.bulk.json 
    
  2. С опцией python я достиг 1мин20 как минимум, используя настройку 10000/16/16 (chunk/thread/queue)

    import codecs
    from collections import deque
    from elasticsearch import Elasticsearch
    from elasticsearch.helpers import parallel_bulk
    
    es = Elasticsearch()
    
    def insert_data(filename, indexname):
        with codecs.open(filename, "r", encoding="utf-8", errors="ignore") as fic:
            for line in fic:        
                json_line = {}
                json_line["data1"] = "random_foo_bar1"
                json_line["data2"] = "random_foo_bar2"
                # more fields ...        
                yield {
                    "_index": indexname,
                    "_type": "doc",
                    "_source": json_line
                }
    
    if __name__ == '__main__':
        pb = parallel_bulk(es, insert_data("superfile.bulk.json", "contentindex"), 
                           chunk_size=10000, thread_count=16, queue_size=16)
        deque(pb, maxlen=0)
    

Факты

  • Я получил машинус 2 процессорами xeon 8-core и 64GB ram
  • Я перепробовал несколько значений для каждого [100-50000]/[2-24]/[2-24]

Вопросы

  • Можно ли еще улучшить время?

  • Если нет, то должен ли я придумать способ записи данных в файл, а затем использовать процесс для команды curl?

—————————

Если я пробую только часть анализа, это займет 15 секунд:

tm = time.time()
array = []

pb = insert_data("superfile.bulk.json", "contentindex") 
for p in pb:
   array.append(p)
print(time.time() - tm)            # 15

pb = parallel_bulk(es, array, chunk_size=10000, thread_count=16, queue_size=16)
dequeue(pb, maxlen = 0)
print(time.time() - tm)              # 90

1 Ответ

0 голосов
/ 01 мая 2019

После моего тестирования:

  1. curl работает быстрее, чем клиент Python, очевидно, что curl реализован лучше.

  2. После дополнительного тестирования и игры с параметрами я могу сделать вывод:

    1. Производительность индекса Elasticsearch зависит от конфигурации индекса и всего кластера.Вы можете повысить производительность, сопоставив поля в индексе правильно.
    2. Мой лучший подход состоял из 8 потоков и блока из 10000 элементов.Это зависит от конфигурации index.index_concurrency , которая по умолчанию равна 8.

    3. Я думаю, что использование многоузлового кластера с отдельным главным узлом должно повысить производительность.

    4. Для получения дополнительной информации вы можете прочитать замечательную статью из двух частей, которую я нашел: здесь и здесь

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