Синхронизация индексов Lucene.net на нескольких серверах приложений
мы разрабатываем архитектуру поиска для корпоративного веб-приложения. Для этого мы будем использовать Lucene.net. Индексы не будут большими (около 100 000 документов), но служба поиска всегда должна быть всегда и всегда быть актуальной. В индекс будут добавлены новые документы и одновременный поиск.
Поскольку у нас должна быть высокая доступность для поисковой системы, у нас есть 2 сервера приложений, которые предоставляют службу WCF для выполнения поиска и индексирования (копия службы выполняется на каждом сервере). Затем сервер использует lucene.net API для доступа к индексам.
Проблема в том, что было бы лучшим решением для постоянного поддержания индексов? Мы рассмотрели несколько вариантов:
-
Использование одного сервера для индексирования и
наличие второго сервера для доступа к
индексы через SMB: нет, потому что мы
иметь единственную точку отказа
ситуация;
-
Индексирование на оба сервера, по существу, запись каждого индекса дважды: возможно, отвратительная производительность и возможность desync, если, например. индексы сервера 1 ОК и сервер 2 исчерпывает дисковое пространство или что-то еще,
-
Использование SOLR или KATTA для переноса доступа к индексам: нет, мы не можем иметь tomcat или аналогичный запуск на серверах, у нас есть только IIS.
-
Сохранение индекса в базе данных: я нашел, что это можно сделать с помощью java-версии Lucene (модуль JdbcDirectory), но я не нашел ничего подобного для Lucene.net. Даже если это означало небольшой удар производительности, мы пошли бы на эту опцию, потому что это решило бы решить проблему concurrency и синхронизации с мини-разработкой.
-
Использование Lucene.net DistributedSearch Contrib module: я не смог зарегистрировать одну ссылку с документацией об этом. Я даже не знаю, просматривая код, что делает этот код, но мне кажется, что он фактически разбивает индекс на несколько машин, чего мы не хотим.
-
rsync и друзья, копируя индексы назад и вперед между двумя серверами: это кажется хакерским и подверженным ошибкам нам, и, если индексы становятся большими, может занять некоторое время, и в течение этого периода мы будем возвращать коррумпированные или несогласованные данные клиентам, поэтому нам нужно разработать специальную политику блокировки, которую мы не хотим.
Я понимаю, что это сложная проблема, но я уверен, что перед этим столкнулись многие люди. Любая помощь приветствуется!
Ответы
Ответ 1
Кажется, что лучшим решением было бы проиндексировать документы на обоих серверах в свою собственную копию индекса.
Если вы беспокоитесь о том, что индексирование будет продолжаться на одном сервере и не сработает на другом, вам нужно будет отслеживать успех/сбой для каждого сервера, чтобы вы могли повторно использовать неудавшиеся документы, когда проблема решена. Это отслеживание будет сделано за пределами Lucene в любой системе, которую вы используете, чтобы представить документы для индексации Lucene. В зависимости от того, насколько важна полнота индекса для вас, вам также может потребоваться удалить сбойный сервер из любого используемого балансировочного устройства нагрузки, пока проблема не будет устранена, а индексирование переработало любые выдающиеся документы.
Ответ 2
+1 для ответа Шона Карпентера. Индексирование на обоих серверах кажется самым безопасным и безопасным выбором.
Если индексируемые документы сложны (Word/PDF и их сортировки), вы можете выполнить некоторую предварительную обработку на одном сервере, а затем предоставить это серверам индексирования, чтобы сохранить некоторое время обработки.
Решение, которое я использовал ранее, предполагает создание блока индексов на одном сервере, затем rsync
переход на серверы поиска и объединение блока в каждый индекс с помощью IndexWriter.AddIndexesNoOptimize
. Вы можете создать новый кусок каждые 5 минут или всякий раз, когда он достигнет определенного размера. Если вам не нужно иметь абсолютно свежие индексы, это может быть для вас решением.
Ответ 3
в java-мире, мы решили эту проблему, поставив MQ перед индексом (es). Вставка была завершена только тогда, когда bean вытащил из очереди успешно, иначе он просто отбросил все действия, которые потребовались, помеченные в документе как ожидающие, и снова попытался выполнить его
Ответ 4
Я знаю, что это старый вопрос, но я просто наткнулся на него и хотел дать 2 цента для тех, кто ищет советы по многосерверной реализации.
Почему бы не сохранить файлы индекса в общей папке NAS? Как это отличается от хранения индекса в базе данных, которую вы рассматривали? База данных может быть реплицирована для высокой доступности, и поэтому может быть NAS!
Я бы настроил два сервера приложений, которые у вас есть за балансировщиком нагрузки. Любой запрос индекса, который входит, будет индексировать документы в отдельной папке компьютера на NAS. То есть на NAS будет столько индексов, сколько серверов приложений. Когда приходит запрос на поиск, вы будете выполнять поиск по нескольким индексам с использованием Lucene. У Lucene есть встроенные конструкторы (MultiSearcher), и производительность по-прежнему отличная.
Ответ 5
Как мы храним наши балансированные нагрузки серверы синхронно, каждый со своей собственной копией Lucene, должен иметь задачу на каком-то другом сервере, который каждые 5 минут запускает каждый сервер с балансировкой нагрузки, чтобы обновить свой индекс до определенная метка времени.
Например, задача отправляет отметку времени "12/1/2013 12: 35: 02.423" всем серверам с балансировкой нагрузки (задача отправляет временную метку с помощью запроса на веб-страницу на каждом балансировочном веб-сайте), то каждый сервер использует эту метку времени для запроса базы данных для всех обновлений, которые произошли с момента последнего обновления до этой метки времени, и обновляет свой локальный индекс Lucene.
Каждый сервер также сохраняет временную метку в db, поэтому он знает, когда последний сервер обновлялся. Поэтому, если сервер отключается, когда он возвращается в сеть, в следующий раз, когда он получает команду timestamp, он будет захватывать все обновления, которые он пропустил, когда он был в автономном режиме.