2015-06-07 5 views
1

Мне нужно найти большую таблицу статей научного журнала для некоторых статей, которые у меня есть в отдельном файле. Мой подход заключается в создании индекса поиска из большой таблицы с помощью Whoosh, а затем поиск каждой статьи разделенного файла в индексе. Это хорошо работает, но занимает слишком много времени (~ 2 недели). Поэтому я хотел немного ускорить работу, выполнив многопроцессорную обработку, и именно там я боюсь.Многопроцессорный поиск без дублирующего индекса в памяти

Существенная часть моей «простой» поиск без многопроцессорной выглядит следующим образом:

articles = open('AuthorArticles.txt', 'r', encoding='utf-8').read().splitlines() 

fs = FileStorage(dir_index, supports_mmap=False) 
ix = fs.open_index() 
with ix.searcher() as srch: 
    for article in articles: 
     # do stuff with article 
     q = QueryParser('full_text', ix.schema).parse(article) 
     res = srch.search(q, limit=None) 
     if not res.is_empty(): 
     with open(output_file, 'a', encoding='utf-8') as target: 
      for r in res: 
       target.write(r['full_text']) 

Теперь, что я конкретно хочу добиться того, что индекс загружается в память, а затем несколько процессов доступа к нему и поиска для статей. Моя попытка до сих пор выглядит следующим образом:

articles = open('AuthorArticles.txt', 'r', encoding='utf-8').read().splitlines() 

def search_index(article): 
    fs = FileStorage(dir_index, supports_mmap=True) 
    ix = fs.open_index() 
    with ix.searcher() as srch: 
     result = [] 
     for a in article 
     # do stuff with article 
     q = QueryParser('full_text', ix.schema).parse(q) 
     res = srch.search(q, limit=None) 
     if not res.is_empty(): 
      for r in res: 
       result.extend[r['full_text']] 
    return result 

if __name__ == '__main__': 
    with Pool(4) as p: 
     results = p.map(search_index, articles, chunksize=100) 
     print(results) 

Но, насколько я понимаю, таким образом каждый отдельный процесс загружает индекс в памяти (который не будет работать, так как индекс достаточно велик).

Есть ли способ, которым я могу добиться того, что мне нужно относительно простым способом? В основном все, что я хочу сделать, - это поиск индекса с использованием всей вычислительной мощности.

+0

Не могли бы вы дать короткий образец 'AuthorArticles.txt', поэтому я делаю тесты? –

ответ

1

Вы можете использовать multiprocessing shared ctypes для обмена информацией между процессами. Вы можете пройти lock=False до Value или Array, если вам нужен только доступ для чтения.

Возможно, этот ответ может помочь вам двигаться дальше:
How to combine Pool.map with Array (shared memory) in Python multiprocessing?

0

Если вы используете mmap (с параметром access равным ACCESS_READ) «читать» файл, подсистема виртуальной памяти вашей операционной системы будет убедитесь, что в память будет загружена только одна копия.

Поскольку вы инициализируете FileStoragesupports_mmap=True, он будет использовать mmap, и ваша проблема должна быть решена. :-)

+0

Отлично! Большое спасибо за вашу помощь, попробуем это. Это работает для каждой ОС одинаково? – smint75

+0

Как вы можете видеть в документации, параметры для 'mmap' отличаются между платформами POSIX и ms-windows. Если 'FileStorage' учитывает это, это должно быть хорошо. Проверьте исходный код. –