#mysql #ruby-on-rails #database #solr #document-oriented-db
#mysql #ruby-on-rails #База данных #solr #document-oriented-db
Вопрос:
У меня возникли некоторые проблемы с производительностью базы данных MySQL из-за ее нормализации.
Большинство моих приложений, использующих базу данных, должны выполнять несколько тяжелых вложенных запросов, что в моем случае занимает много времени. Выполнение запросов с индексами может занимать до 2 секунд. Без индексов около 45 секунд.
Решение, с которым я столкнулся несколько месяцев назад, заключалось в использовании более быстрой и линейной базы данных на основе документов, в моем случае Solr, в качестве основной базы данных. Как только что-то было изменено в базе данных MySQL, Solr был уведомлен.
Это сработало действительно здорово. Все запросы с использованием базы данных Solr заняли всего около 3 мс.
Цифры выглядят хорошо, но у меня возникли некоторые проблемы.
- Огромная база данных
Объем базы данных MySQL составляет около 200 МБ, база данных Solr содержит около 1,4 Гб данных. Каждый раз, когда мне нужно изменить таблицу / столбец, базу данных необходимо переиндексировать, что в этом примере заняло более 12 часов.
- Сложно визуализировать как объект Solr, так и объект Active Record (MySQL) без промокания.
Представление полагается на определенный объект. Не важно, является ли сам объект объектом Active Record или объектом Solr, если он может вызывать набор атрибутов для ит.
Вот так.
# Controller
@song = Song.first
# View
@song.artist.urls.first.service.name
Проблема в моем случае заключается в том, что данные, возвращаемые из Solr, являются плоскими, как это.
{
id: 123,
song: "Waterloo",
artist: "ABBA",
service_name: "Groveshark",
urls: ["url1", "url2", "url3"]
}
Это заставляет меня создавать активный объект записи, который может быть передан в представление.
Мой вопрос
Есть ли лучший способ решить проблему? Было бы неплохо создать какую-нибудь супер-пупер быструю первичную базу данных, доступную только для чтения, которая может быстро обрабатывать сложные запросы.
Комментарии:
1. У вас есть идентификационные номера в каждой таблице?
Ответ №1:
Обновление отдельных полей Solr
О переиндексации всего при изменении схемы: Solr пока не поддерживает обновление отдельных полей, но по этому поводу есть проблема JIRA, которая до сих пор не решена. Однако, сколько раз вы меняете схему?
MongoDB
Если вы можете обойтись без СУБД (без объединений, схемы, транзакций, ограничений внешнего ключа), идеально подойдет база данных на основе документов, такая как MongoDB или CouchDB. (вот хорошее сравнение между ними)
Зачем использовать MongoBD:
- данные находятся в собственном формате (вы можете использовать ORM mapper, такой как Mongoid, непосредственно в представлениях, поэтому вам не нужно адаптировать свои записи, как вы делаете с Solr)
- динамические запросы
- очень хорошая производительность при неполнотекстовых поисковых запросах
- без схемы (нет необходимости в миграции)
- встроенная, простая в настройке репликация
Зачем использовать SOLR:
- расширенный, очень эффективный полнотекстовый поиск
Зачем использовать MySQL
- объединения, ограничения, транзакции
Решения
Итак, решения (комбинации) будут:
-
Используйте MongoDB Solr
- но вам все равно нужно будет переиндексировать все при изменении схемы
-
Используйте только MongoDB
- но отказаться от поддержки расширенного полнотекстового поиска
-
Используйте MySQL в конфигурации master-slave, и баланс считывается с подчиненных устройств (с использованием плагина, такого как octupus) Solr
- сложность настройки
-
Сохранить текущую настройку, денормализовать данные в MySQL
- беспорядочно
Медленность переиндексации Solr
Объем базы данных MySQL составляет около 200 МБ, база данных Solr содержит около 1,4 Гб данных. Каждый раз, когда мне нужно изменить таблицу / столбец, базу данных необходимо переиндексировать, что в этом примере заняло более 12 часов.
Переиндексация 200 МБ БД в Solr НЕ ДОЛЖНА занимать 12 часов! Скорее всего, у вас есть и другие проблемы, такие как:
MySQL:
- проблема n 1
- индексы
SOLR:
- фиксация после каждого запроса — это настройка по умолчанию, если вы используете плагин, такой как sunspot, но он убивает производительность
Из http://outoftime.github.com/pivotal-sunspot-presentation.html:
- По умолчанию Sunspot :: Rails фиксирует в конце каждого запроса, который обновляет индекс Solr. Отключите это.
- Используйте функцию автоматической фиксации Solr. Это настроено в solr/conf/solrconfig.xml
- Будьте рады предполагаемой несогласованности. Не используйте поиск, где результаты должны быть актуальными.
- другие проблемы с настройкой (http://wiki.apache.org/solr/SolrPerformanceFactors#Indexing_Performance )
Посмотрите на журналы для получения более подробной информации
Ответ №2:
Вместо того, чтобы помещать ваши данные в Solr для выравнивания записей, почему бы вам просто не создать отдельную таблицу в вашей базе данных MySQL, оптимизированную для доступа только для чтения.
Также вы, кажется, противоречите себе
Представление полагается на определенный объект. Не важно, является ли сам объект объектом Active Record или объектом Solr, если он может вызывать набор атрибутов для ит.
Проблема в моем случае заключается в том, что данные, возвращаемые из Solr, являются плоскими… Это заставляет меня создавать поддельный объект активной записи, который может быть отображен с помощью представления.
Комментарии:
1. Я не уверен, что вы подразумеваете под «противоречащей» частью. В представлении требуется объект, который выглядит следующим
@song.artist.urls.first.service.name
образом . Solr этого не предоставляет, поэтому я должен создать ее самостоятельно. Другими словами, представлению все равно, является ли объект объектом AR, пока существует только что упомянутый атрибут.2. Хорошо, теперь это имеет смысл. Думал, вы говорили, что вам всегда нужно конвертировать в AR-объект, потому что вы создавали поддельный, и незадолго до этого вы сказали, что ваше мнение не волнует… Теперь я вижу, поскольку ему просто нужен атрибут.