Справочная информация :
я создал веб-приложение, которое я хотел бы иметь возможность достаточно хорошо масштабировать. Я знаю, что я не Google или Twitter, но мое приложение использует довольно большой объем данных для каждого пользователя и, следовательно, предъявляет довольно высокие требования к данным. Я хочу быть готовым достаточно хорошо масштабироваться, не перестраивая все позже.
Я считаю себя разработчиком программного обеспечения, а не экспертом по базам данных. Вот почему я публикую здесь. Надеюсь, кто-то с большим опытом работы с базами данных может дать мне совет.
С относительно большим количеством пользователей, но не похожими на номера Facebook, я ожидаю, что у меня будет БД, которая выглядит следующим образом:
Один "Большой стол":
- 250 миллионов записей
- 20 столбцов
- Примерно 100 ГБ данных
- Имеет индексированный внешний ключ bigint (20)
- Имеет индексированный столбец varchar (500) string_id
- Имеет int (11) столбец «значение»
4 другие таблицы:
- 10 миллионов записей каждая
- Примерно 2 - 4 ГБ данных каждый
- каждая из этих таблиц имеет 4 - 8 столбцов
- один столбец является datetime date_created
- один столбец является столбцом varchar (500) string_id
- один или два столбца из каждой из этих таблиц будут выбраны в объединении
Одна из этих таблиц используется для хранения средних значений: ее схема - bigint (20) id, varchar (20) string_id, datetime date_created, float average_value
Что я хочу сделать - два относительно дорогих запроса:
Рассчитать новые средние значения:
- Используя внешний ключ, выберите до нескольких миллионов отдельных записей из большой таблицы.
- Вычислите новое среднее, группируя по string_id.
- Вставьте результаты в таблицу средних значений.
- В настоящее время этот запрос использует два соединения.
Создайте ненормализованные записи только для чтения для обслуживающих пользователей:
- Используйте внешний ключ, чтобы выбрать от 1 000 до 40 000 записей из большой таблицы.
- Присоединитесь к каждой из четырех других таблиц в самой новой записи с помощью столбца идентификатора строки.
- Вставьте результаты в ненормализованную таблицу.
- Эти записи предназначены для внешнего интерфейса для отображения информации пользователям.
- В настоящее время этот запрос использует четыре объединения.
Я планирую запускать каждый из этих дорогих запросов в пакетной серверной базе данных, которая отправит свои результаты на внешний сервер БД в режиме реального времени, который обрабатывает запросы от пользователей. Эти запросы будут выполняться через равные промежутки времени. Я не решил, как часто. Средний запрос может быть сделан, возможно, один раз в день. Запрос на нормализацию должен выполняться чаще - возможно, каждые несколько минут.
Каждый из этих запросов в настоящее время выполняется в MySQL за несколько секунд на очень низкоуровневой машине с набором данных со 100K записями в «большой таблице». Я обеспокоен как своей способностью к масштабированию, так и стоимостью масштабирования.
Вопросы :
- Этот подход кажется правильным? Что-то явно не так с точки зрения общей картины?
- Является ли СУБД подходящим инструментом или я должен смотреть на другие решения для «больших данных», как что-то из семейства Hadoop? Я склонен использовать RDBMS, потому что данные структурированы и хорошо вписываются в реляционную модель. Однако в определенный момент я понимаю, что я больше не смогу использовать СУБД. Это правда? Когда будет необходим этот переключатель?
- Это будет работать? Могут ли эти запросы выполняться в разумные сроки? Я могу подождать, возможно, несколько часов для запроса № 1, но запрос № 2 должен завершиться через несколько минут.
- Что я должен рассмотреть с точки зрения аппаратного обеспечения? Какие могут быть узкие места в моей оперативной памяти и процессоре? Я предполагаю, что хранение индексов в оперативной памяти важно. Есть ли что-то еще, что я должен рассмотреть?
- В какой-то момент мне, вероятно, придется разделить мои данные и использовать несколько серверов. Похоже, мой вариант использования уже относится к этой категории, или я смогу какое-то время масштабировать одну машину по вертикали? Будет ли это работать с 10x данными? 100x?
Ответы:
Вы пытались собрать больше данных и сравнить их? 100K строк несущественно. Попробуйте 250M или 500M, как вы ожидаете, вы должны справиться и посмотреть, где узкие места.
СУБД может многое сделать, если вы внимательно относитесь к ограничениям и пытаетесь работать с сильными сторонами системы. Они исключительно хороши в одних вещах и ужасны в других, поэтому вам нужно будет экспериментировать, чтобы убедиться, что они подходят.
Для некоторых задач пакетной обработки вы действительно не можете разбить плоские файлы, загружая данные в оперативную память, разбивая их, используя серию циклов и временных переменных, и сбрасывая результаты. MySQL никогда не сможет сравниться с такой скоростью, но при правильной настройке и правильном использовании он может достигать порядка величины.
Что вы хотите сделать, это выяснить, как ваши данные могут быть разделены. У вас есть один большой набор данных со слишком большим количеством перекрестных ссылок, чтобы его можно было разделить, или есть естественные места для его разделения? Если вы сможете разбить его на части, у вас не будет одной таблицы с целой кучей строк, но потенциально много значительно меньших. Меньшие таблицы с гораздо меньшими индексами, как правило, работают лучше.
С аппаратной точки зрения вам нужно будет проверить, как работает ваша платформа. Иногда память необходима. В других случаях это дисковый ввод-вывод. Это действительно зависит от того, что вы делаете с данными. Вам нужно будет внимательно следить за использованием вашего процессора и искать высокий уровень ввода-вывода, чтобы узнать, в чем проблема.
По возможности делите ваши данные между несколькими системами. Вы можете использовать MySQL Cluster, если вы чувствуете себя смелым, или просто раскрутить много независимых экземпляров MySQL, где каждый хранит произвольную часть полного набора данных, используя некоторую схему разделения, которая имеет смысл.
источник
Сводные таблицы.
Каждый день вычисляйте совокупную информацию для данных дня. Поместите это в «сводную» таблицу (ы). Делайте ваши запросы против них. Легко в 10 раз быстрее.
Для дальнейшего обсуждения, пожалуйста, предоставьте
Некоторые очевидные вещи ...
"Меньше -> больше кешируется -> быстрее
источник
Для обслуживания ваших данных переднего плана, если нет постоянных гобов и вставок, вы действительно не сможете использовать триггеры для вставки в материализованные представления, которые синхронизируются с внутренним, но оптимизированы для обслуживания данных. Конечно, в этих триггерах нужно сводить к минимуму объединения и т. Д. Одна из стратегий, которую я использовал, состоит в том, чтобы ставить эти вставки / обновления в промежуточную таблицу, а затем отправлять их позже каждую минуту или около того. Отправлять одну запись намного проще, чем 4 ГБ. Потоковая передача 4 ГБ данных занимает много времени, даже если вы можете быстро найти нужные записи.
Я согласен с Тэдманом. Лучше всего профилировать данные, которые вы ожидаете, в той системе, которая вам нужна.
источник