⚠️ Эта страница автоматически переведена, и перевод может быть несовершенным.

Improvements in Manticore Search 2.7: local indexes management

Общий доступ к ресурсам до настоящего момента осуществлялся с помощью RW‑блокировок. При высокой нагрузке использование блокировок могло приводить к проблемам при попытке изменить индексы. Чтобы преодолеть эти проблемы, нам пришлось переосмыслить взаимосвязь между потоками и индексами.

Индексы могут быть большими или даже огромными, и они общие для всех рабочих процессов. На многоядерном процессоре можно одновременно запускать множество запросов, и они распределятся по ядрам, используя один и тот же индекс. Это просто и понятно. Однако иногда требуется обновить индексы. Бесшовное переключение работало довольно хорошо со старыми fork‑рабочими: мы просто загружали новые файлы индекса, оставляя работающие форки обслуживать старые. И в один момент новые запросы переходят к форкам, которые уже используют новый загруженный индекс. Таким образом, нет задержек в обслуживании: вы просто бесшовно переходите со старого индекса на новый. Рабочие, использующие старую версию, завершатся (или упадут), и в итоге предыдущий индекс будет освобождён.

В случае потоковых рабочих использовался простой механизм RW‑блокировок — 'shared-exclusive locks' —, где многие общие рабочие (читающие) могут одновременно получать доступ к ресурсу, но один эксклюзивный рабочий (пишущий) может его изменять. Поэтому индексы всегда были либо 'shared' между запросами, либо 'locked' при ротации. Они загружались в начале и освобождались в конце. При ротации один поток загружал новый индекс, но ему требовался эксклюзивный доступ к дескриптору активного индекса. Однако запросные рабочие имеют общий доступ, и никто не останавливает их от получения новых задач. Это означает, что при высокой нагрузке вы просто не можете выполнить 'seamless' ротацию из‑за последнего шага — атомарного переключения старого индекса на новый.

В новой модели, представленной в версии 2.7, индексы теперь живут между потоками независимо, аналогично старому случаю с 'fork', поскольку они больше не являются ни 'shared', ни 'locked', а просто immutable. Это упрощает работу: рабочий просто не заботится о 'lock' или 'share' индекса, он просто использует его. Когда необходимо выполнить ротацию (загрузить новый индекс), демон делает это без учёта работающих запросов (и их потоки также не учитывают 'writer'). В конце концов ротация просто переключает указатель активного индекса на новый (загруженный), и затем всё работает как с форками: старые запросы продолжают использовать предыдущий индекс, новые направляются только на загруженный. Единственная ситуация, когда всё ещё используется эксклюзивная блокировка, — это выполнение UPDATE‑ов.

Еще одно преимущество новой модели заключается в том, что мы можем менять тип индекса «на лету» с помощью перезагрузки конфигурации. Раньше изменение типа индекса не всегда было возможно простым изменением конфигурационного файла и попыткой перезагрузки (по сигналу HUP), например, переключить индекс 'plain' на 'distributed' или 'distributed' на 'template'. Теперь, когда вы перезагружаете новую конфигурацию, где всё из старого индекса сохраняет своё имя, демон сначала разбирает новую. Затем, если её можно использовать сразу (что происходит с шаблонами и распределёнными индексами), он без проблем меняет их местами. В случае, когда новые индексы являются 'heavy' (т.е. их необходимо предварительно загрузить в ОЗУ, что может занять несколько минут), процесс ротации откладывается до их загрузки. «deferred» означает, что вызывающий получает ответ 'ok', '(all rotated)'. Но фактические рабочие продолжают отправлять все новые запросы к старым индексам, пока новый индекс окончательно не загрузится и не станет активным.

Установить Manticore Search

Установить Manticore Search