Представьте, что вам надо организовать крупное событие с участием нескольких десятков, а то и сотен человек. Пусть это будет, например, слет костровых бойскаутских организаций Америки. И пусть он будет проходить ежегодно. Какого размера оргкомитет вам потребуется и во сколько это обойдется? К счастью, есть простой выход. Современные технологии позволяют создавать инфраструктурные платформы, способные сводить воедино огромные объемы самой разнородной информации и обеспечивать удобный доступ к ней из любой точки мира. Чудо? Нет, просто технология, которая работает. N + 1 совместно с компанией Personify Inc., разрабатывающей инфраструктурный сервис Wild Apricot (да-да, площадка для слета американских бойскаутов — их рук дело), расскажет о сердцевине подобной платформы — базах данных и системах работы с ними.


Зачем нужны таблицы

Появление современных (реляционных) баз данных принято относить к 1970 году, когда вышла статья Эдгара Кодда с описанием их математической модели. Если вы хоть раз в жизни видели табличку в Excel или Google Sheet, вы уже представляете себе такую модель. Она предполагает, что каждая запись (строка) в базе имеет определенное число полей (по числу столбцов).

Благодаря этому модель данных, или «схема» (schema), вполне могла существовать отдельно от физической копии. Зная, как устроена ваша таблица, можно было заранее выбрать необходимый диапазон для считывания, оформить «срез» данных, нужный именно сейчас, а затем быстро и оптимизировано считать его с физического устройства.

Для реляционных баз данных был разработан язык SQL (structured query language), который де-факто стал стандартным для этой модели. Список реализаций реляционных баз данных до сих пор остается внушительным, и в описании большинства из них присутствует аббревиатура SQL.

А как еще можно организовывать данные в базе? Если всерьез задаться этим вопросом, то обнаружится, что реляционная модель подходит отнюдь не для всех задач. В ней действует единая модель доступа к любому значению: системе надо знать название самой таблицы, значение первичного ключа (его аналог — номер строки) и название столбца. Значит, все записи должны быть стандартизированы.

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

Почему Wild Apricot?

Над развитием сервиса Wild Apricot работают специалисты в области создания и поддержки клиентских баз данных. Поскольку они поднимали свой сервис с нуля, им пришлось на своем опыте узнать все подводные камни, связанные с разработкой подобных проектов. В результате они научились создавать продукты для множества совершенно разных клиентов, чьи запросы к базам данных порой отличаются кардинально: что общего у канадского «Ордена сыновей Италии», Ассоциации парков штата Онтарио, Бизнес-сети женщин из Долины реки Махок и Североамериканской организацией писателей — обозревателей пива? Только одно — всю свою деятельность в сети они выстраивают на продуктах сервиса Wild Apricot. Поэтому свои вопросы о базах данных мы адресовали его разработчикам.


Данных становится все больше

В момент создания и активного развития SQL сложно было представить, насколько в будущем вырастут объемы информации, подлежащей хранению. Поэтому неудивительно, что сейчас реляционные базы уже не годятся для постоянно меняющихся и быстрорастущих проектов.

Такие базы данных хорошо приспособлены для «вертикального» масштабирования, то есть последовательного наращивания таблиц за счет добавления новых строк. Вертикальное масштабирование на физическом уровне — это просто еще более мощный сервер, еще более крупный диск. Но когда счет данных идет на петабайты, ни один, пусть и «очень большой» сервер с такими объемами не справится. И тогда придется задуматься о «горизонтальном» масштабировании, то есть дроблении базы на фрагменты.

Для горизонтального распределения реляционная модель в общем, и SQL в частности, приспособлена уже не так хорошо. Конечно, вы можете один раз физически разделить большую базу данных на 10 баз поменьше. Но в какой-то момент нагрузка на них опять разбалансируется и данные снова придется «перетасовывать». Потребуется писать «надстройки», сочетающие в себе привычный SQL-синтаксис с более продвинутой и динамичной моделью горизонтального масштабирования.

Комментарий разработчиков Wild Apricot

Примерно так у нас и произошло. Дело было даже не том, что SQL не хватало, а в самой схеме базы данных: она связанная. В первую очередь это стало заметно на функционале Custom Fields, когда администраторы сами создают поля своим пользователям для заполнения. Число этих полей быстро разрослось и стало проблемой.

Точно так же из-за схемы данных нет возможности запустить отдельную физическую базу для «крупных» клиентов, так что само их наличие стало понижать производительность всего сервиса.

То есть сам по себе MSSQL как продукт отлично выдерживает нагрузки и мы точно не упираемся в его физические ограничения. Проблема была именно в изначальной схеме хранения данных.


Когда данных слишком много

Как только сервис упирается в проблему масштаба, меняется все. В частности, возникают проблемы с «железом» и «софтом». Серверы больше не помещаются в серверную и едут на отдельную хостинговую площадку, а простой и надежной модели бэкенда по принципу «сервер крутит базу данных» становится недостаточно.

Накопившийся объем данных становится слишком велик, чтобы работать на одном сервере, необходимо разнести его на несколько нод (node). А еще чем дальше, тем труднее проводить в базе операции, которые не сводятся к простому «поиск/запись/удаление». Пример — полнотекстовый поиск. Хоть он и реализован в базах данных на основе SQL, их функциональности может быть недостаточно, когда число разносортных запросов начинает сильно расти.

Из-за числа запросов и сам по себе доступ к базе данных превращается в «бутылочное горлышко», и для решения этой задачи приходится создавать отдельный сервис.

Комментарий разработчиков Wild Apricot

Помимо отсутствия схемы, еще не хватало шардирования. Ведь хранение контента — это прежде всего объем, без горизонтального масштабирования не выжить. В процессе обсуждения стало ясно, что мы имеем дело с очень разнородными данными и документо-ориентированая система управления базами данных решила бы эту задачу очень хорошо.

В итоге мы остановились на MongoDB, у которого уже само название (от 'huMONGOus' — «огроменный») говорит об отличном потенциале к распределенности. Документ-ориентированность этой базы в итоге позволила упростить обработку сложных запросов, а нативно реализованный шардинг (sharding) — разнести нагрузку по нескольким серверам, к чему мы исходно и стремились.

Примерно в 2009 году появились технологии, которые сейчас объединены под названием NoSQL. Единственное общее у этих систем, как следует из названия, — их «нереляционность» и отсутствие SQL в качестве центрального механизма. Это и есть ответ на вопрос: «Если не табличками, то как?»

Охватить сразу все существующие NoSQL-базы — титаническая задача, поэтому ограничимся основными типами.

Самая обширная группа NoSQL-БД строится по модели «ключ-значение» (key-value), очень похожей на хеш-таблицы в таком языке программирования, как C#. Каждому объекту присваивается уникальный ключ, по которому он может быть (целиком) найден.

Под «значением» можно понимать что угодно, от короткой записи с несколькими полями до изображения или даже веб-страницы. Но при отсутствии внутренней структуры (schema), присущей реляционной модели, здесь не получится легко «пройти» по всем объектам со сложным запросом и быстро составить компактную форму для выдачи.

Другой NoSQL-подход — это «колоночные», или «столбцовые», модели. Их идея крайне проста: что если сместить фокус со строки на столбец? Такая модель, например, позволяет в каждой записи (строке) иметь произвольное число полей, но при этом данные из одного столбца физически хранятся «вместе», таким образом оставляя без надобности поля вроде NULL и экономя место.

В этом случае обмен между жесткой структурой и гибкостью не настолько очевиден, как в предыдущем, но и «цена» его, в терминах эффективности системы, не столь высока. Преимущество «колоночной» базы заключается и в скорости ее работы, когда необходимо считать данные только по одному показателю. Например, подобные задачи регулярно возникают в аналитических приложениях, когда необходимо подсчитывать определенные метрики.

Как быть с двумя другими задачами: асинхронной обработкой и продвинутым поисковым сервисом? Сейчас для этого уже существуют готовые решения, как открытые, так и коммерческие. Пример системы для управления очередями — ActiveMQ, реализующая «общение» между клиентом и различными сервисами. Что касается поиска, то роль «внутреннего Google» вполне может взять на себя ElasticSearch, который специализируется на полнотекстовом поиске по документам и так же нативно реализует шардинг.

Комментарий разработчиков Wild Apricot

Шардинг в простейшем случае — это дробление базы данных на частично или полностью независимые осколки. Для реляционных баз шардинг часто воспринимается как костыль: как уже говорилось выше, таблицы приходится дробить в полуручном режиме, что снижает выгоду от такого решения. Но в такой базе, как MongoDB, шардинг реализован нативно и максимально эффективно сочетается с используемой моделью данных.


Как улететь в облако

Удачное сочетание подходящих баз данных и сервисов, обеспечивающих их взаимодействие, позволяет решить проблемы бэкенда для больших объемов данных. Или так только кажется?

Действительно, эта модель предполагает и масштабируемость, и распределенность, и гибкость по отношению к разнородным данным, а значит, легкое внедрение нового функционала. Но она все еще не дает полной свободы. Остаются точки «заземления» вроде хостинговых площадок и физических серверов. Поэтому следующий логический шаг — отказ от физического построения бэкенда и переход на чистый язык технологий. Речь идет об облачных сервисах.

Понятно, что «облаку» тоже нужны машины. Но при переходе на него они перестают быть проблемой самой компании. Остается только на сто процентов виртуальный мир сервисов, из которых нужно собрать бэкенд, и он заработает.

Комментарий разработчиков Wild Apricot

Переехав на облачные сервисы, мы получили прирост в скорости работы сервиса в три раза. Также получили увеличенную в десятки раз скорость подъема серверов для обслуживания, что позволило публиковать версии Wild Apricot в четыре раза чаще. Так что в нашем случае переезд дал только плюсы, никакого «trade off» не было. Единственное, что было, — это мандраж от неизвестного.

Меньше чем за семьдесят лет базы данных прошли путь от перфокарт до облака — и это явно не конечная остановка. Последний виток развития систем управления базами данных начался совсем недавно, и от того, с какой скоростью развивается эта индустрия, сейчас просто захватывает дух.

Тем интереснее за этим следить.

А еще вы можете проверить свои навыки в работе с языком C#, который используют разработчики сервиса Wild Apricot, с помощью нашего теста «Организуйте это немедленно!»


Тарас Молотилин

Нашли опечатку? Выделите фрагмент и нажмите Ctrl+Enter.