Синхронизация индексов Lucene.net между несколькими серверами приложений - PullRequest
14 голосов
/ 03 июня 2009

мы разрабатываем архитектуру поиска для корпоративного веб-приложения. Мы будем использовать Lucene.net для этого. Индексы не будут большими (около 100 000 документов), но служба поиска должна быть всегда в курсе и всегда быть в курсе событий. В индекс будут постоянно добавляться новые документы и одновременный поиск. Поскольку у нас должна быть высокая доступность для поисковой системы, у нас есть 2 сервера приложений, которые предоставляют службу WCF для выполнения поиска и индексации (копия службы работает на каждом сервере). Затем сервер использует API lucene.net для доступа к индексам.

Проблема в том, что было бы лучшим решением для постоянной синхронизации индексов? Мы рассмотрели несколько вариантов:

  • Использование одного сервера для индексации и имея 2-й сервер доступа к индексы через SMB: нет, не можем сделать, потому что мы иметь единую точку отказа положение;

  • Индексирование на оба сервера, по сути, запись каждого индекса дважды: вероятно, плохая производительность и возможность десинхронизации, если, например. сервер 1 индексирует ОК, а серверу 2 не хватает места на диске или что-то еще;

  • Использование SOLR или KATTA для переноса доступа к индексам: нет, у нас не может быть запущен tomcat или аналогичный на серверах, у нас есть только IIS.

  • Хранение индекса в базе данных: я обнаружил, что это можно сделать с помощью Java-версии Lucene (модуль JdbcDirectory), но я не смог найти ничего похожего для Lucene.net. Даже если бы это означало небольшое снижение производительности, мы бы выбрали этот вариант, потому что он чисто решит проблему параллелизма и синхронизации с разработкой mininum.

  • Использование модуля вклада Lucene.net DistributedSearch: я не смог отправить одну ссылку с документацией по этому поводу. Я даже не знаю, глядя на код, что делает этот код, но мне кажется, что он фактически разделяет индекс на несколько машин, а это не то, что нам нужно.

  • rsync и друзья, копируя индексы назад и вперед между двумя серверами: это кажется нам хакерским и подверженным ошибкам, и, если индексы растут большими, это может занять некоторое время, и в этот период мы возвращать либо поврежденные, либо непоследовательные данные клиентам, поэтому нам нужно разработать специальную политику блокировки, которую мы не хотим.

Я понимаю, что это сложная проблема, но я уверен, что многие люди сталкивались с этим раньше. Любая помощь приветствуется!

Ответы [ 5 ]

7 голосов
/ 03 июня 2009

Похоже, что лучшим решением было бы проиндексировать документы на обоих серверах в свою собственную копию индекса.

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

2 голосов
/ 22 февраля 2012

Я знаю, что это старый вопрос, но я только что натолкнулся на него и хотел дать свои 2 цента всем, кто ищет советы по реализации на нескольких серверах.

Почему бы не сохранить индексные файлы в общей папке NAS? Чем он отличается от хранения индекса в базе данных, которую вы рассматривали? База данных может быть реплицирована для обеспечения высокой доступности, как и NAS!

Я бы настроил два сервера приложений, которые у вас за балансировщиком нагрузки. Любой входящий запрос на индексирование будет индексировать документы в определенной папке компьютера на NAS. То есть на NAS будет столько же индексов, сколько и на серверах приложений. Когда поступит запрос на поиск, вы будете выполнять многоиндексный поиск с помощью Lucene. В Lucene есть встроенные конструкции (MultiSearcher), и производительность по-прежнему отличная.

1 голос
/ 13 июня 2009

в мире Java мы решили эту проблему, поместив MQ перед индексом (ами). Вставка была завершена только тогда, когда бин, извлеченный из очереди, был успешным, в противном случае он просто откатывал любое выполненное действие, помеченное в документе как ожидающее, и позже было повторено попытка

1 голос
/ 03 июня 2009

+ 1 для ответа Шона Карпентера. Индексирование на обоих серверах кажется самым разумным и безопасным выбором.

Если индексируемые документы являются сложными (Word / PDF и другие), вы можете выполнить некоторую предварительную обработку на одном сервере, а затем передать ее на серверы индексирования, чтобы сэкономить некоторое время обработки.

Решение, которое я использовал ранее, включает создание фрагмента индекса на одном сервере, затем rsync его передачу на серверы поиска и объединение фрагмента с каждым индексом, используя IndexWriter.AddIndexesNoOptimize. Вы можете создавать новый блок каждые 5 минут или всякий раз, когда он достигает определенного размера. Если вам не нужно иметь абсолютно обновленные индексы, это может быть решением для вас.

0 голосов
/ 09 ноября 2013

То, как мы синхронизируем наши серверы с балансировкой нагрузки, каждый из которых имеет собственную копию Lucene, - это выполнение задачи на каком-либо другом сервере, который выполняется каждые 5 минут и дает команду каждому серверу с балансировкой нагрузки обновить свой индекс до определенная отметка времени.

Например, задача отправляет отметку времени «12/1/2013 12: 35: 02.423» на все серверы с балансировкой нагрузки (задача отправляет отметку времени через строку запроса на веб-страницу на каждом сайте с балансировкой нагрузки) затем каждый сервер использует эту временную метку для запроса к базе данных всех обновлений, которые произошли с момента последнего обновления до этой временной метки, и обновляет свой локальный индекс Lucene.

Каждый сервер также хранит метку времени в БД, поэтому он знает, когда каждый сервер последний раз обновлялся. Таким образом, если сервер переходит в автономный режим, когда он возвращается в оперативный режим, в следующий раз, когда он получит команду отметки времени, он получит все пропущенные обновления, пока он был отключен.

...