Школа анализа
и проектирования
информационных систем Бескова и Богачёвой
new
🔥  Регулярные онлайн-конференции школы SE по проектированию информационных систем для бизнеса. Подробнее
Теперь в SE доступна оплата обучения в рассрочку для частных лиц. Выберите обучение и разделите его стоимость на удобные платежи с Яндекс Сплит.
Теперь в SE доступна оплата обучения в рассрочку для частных лиц. Выберите обучение и разделите его стоимость на удобные платежи с Яндекс Сплит.
Теперь доступна оплата обучения в рассрочку для частных лиц. Выберите обучение и разделите его стоимость на удобные платежи с Яндекс Сплит.
🚀 Все воркшопы школы
за 60 тыс. руб!

Уникальная возможность посетить все воркшопы школы по одному абонементу. Экономия 109 тыс. руб.

Подробнее
Инна Александрова по материалам вебинара Ани КРХ

Приемы масштабирования баз данных и повышения производительности систем

Введение
В этой статье мы рассмотрим несколько основных приёмов, покрывающих 90% задач масштабирования высоконагруженных (highload) систем. При разработке высоконагруженных систем необходимо продумывать много нюансов: архитектура системы, структура хранилища, актуальность используемых технологий, возможности аппаратных ресурсов и многое другое. В статье сделаем упор на базы данных — рассмотрим методы оптимизации и повышения производительности работы с данными.

Материал будет полезен тем, кто:

  • хочет проектировать системы, пригодные к масштабированию без существенных изменений в архитектуре;
  • столкнулся с проблемами роста системы и хочет узнать основные способы решения;
  • ищет способы оптимизации производительности в своих проектах.
Время на чтение статьи: 20 минут
Не любите читать? Посмотрите видео.

Что такое масштабирование

Представим, что мы выпустили на рынок MVP (Minimum Viable Product — Минимально жизнеспособный продукт), который условно имеет такую архитектуру:
Управление требованиями и управление архитектурой ИТ
Рис.1 — Исходная архитектура системы
В реальности архитектура (даже у MVP) будет несколько сложнее, но для примера упростим ее до двух частей:
  • backend-приложение, в котором хранится логика системы;
  • база данных.
Предположим, что наш MVP стал успешен на рынке и привлёк много пользователей. Это привело к нестабильной работе системы: страницы загружаются медленно, возникают ошибки. В таком случае необходимо позаботиться о масштабировании системы.

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

Основные методы масштабирования систем

В нашем примере система состоит из двух частей, соответственно проблема в одной из них. Определить, где она кроется можно разными способами: по ошибкам в логах или по графикам утилизации ресурсов сервера (CPU и память).

Масштабирование бэкенда

Если в рамках мониторинга проблема обнаружена на стороне приложения, то нам необходимо масштабировать бэкенды


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


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


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

Оптимизация базы данных

Мы выделили для backend дополнительные сервера, но с вероятностью 90% не получили необходимый результат, потому что в большинстве случаев низкая производительность бывает вызвана проблемами в хранилище, а не в приложении, поэтому нужно попытаться оптимизировать ее.
Настройки СУБД
Первый пункт, требующий внимания — настройки СУБД (системы управления базой данных).

Настройки СУБД — это набор параметров в конфигурационном файле. Часто они по умолчанию выставлены неоптимально.

Например, в PostgreSQL дефолтные значения предназначены для работы с минимальными ресурсами, чтобы СУБД можно было развернуть даже на серверах с маленькой мощностью. Изменить их довольно просто.

На примере PostgreSQL рассмотрим три настройки, которые сильно влияют на производительность БД. Их значения зависят от:
  • типа носителя, на котором хранятся данные (жёсткий диск HDD или твердотельный накопитель SSD);
  • количества оперативной памяти, выделенной под сервер хранилища.
Полезные ссылки

How to tune PostgreSQL for memory
Индексирование
Ещё один шаг — применение индексов. Индексирование — один из основных способов ускорения запросов к базе данных.
Работая с хранилищем, не забывайте индексировать данные в таблицах. При выборе способа и ключа индексации учитывайте распределение данных и типовые запросы, которые планируете выполнять к БД.

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

Примерно так работает индексирование. При запросе к реляционной БД, проиндексированной методом B-tree, механизм спускается по бинарному дереву, как показано на иллюстрации. Бинарный поиск имеет алгоритмическую сложность O(log(n)), то есть на 1000 записей нужно выполнить в среднем всего 10 операций, чтобы дойти по дереву индекса до искомого значения и это эффективнее перебора всех значений подряд.
Управление требованиями и управление архитектурой ИТ
Рис.2 — Пример индекса B-tree для набора численных значений
Оптимизация запросов
Под оптимизацией запросов подразумевается изменение структуры SQL-запросов без изменения структуры хранения данных.

Пример запроса с простым синтаксисом:
SELECT *
FROM items
WHERE category IN (1, 3, 15)
ORDER BY priority DESC
LIMIT 3
Этот запрос можно заменить на приведённый ниже, упростив логику обработки данных для БД.
SELECT *
FROM (SELECT *
      FROM (SELECT *
            FROM items
            WHERE category = 1
            ORDER BY priority DESC
            LIMIT 3) x
      UNION ALL
      SELECT *
      FROM (SELECT *
            FROM items
            WHERE category = 5
            ORDER BY priority DESC
            LIMIT 3) x
      UNION ALL
      SELECT *
      FROM (SELECT *
            FROM items
            WHERE category = 13
            ORDER BY priority DESC
            LIMIT 3) x
      ) y
ORDER BY priority DESC
LIMIT 3
Такая замена позволит снизить время выполнения запроса с 6208 мс до 0.140 мс.

Для освоения искусства оптимизации запросов вам понадобится научиться:
  • читать план запроса, подготовленный планировщиком запросов по команде EXPLAIN (ANALYZE);
  • запрашивать и интерпретировать статистику БД;
  • разбираться в том, как СУБД читает и обрабатывает данные.
Денормализация данных
Под денормализацией понимается приведение структуры данных к удобному для чтения виду. При этом допускается нарушение правил нормализации данных, они могут быть избыточными или задублированными.

Денормализация позволяет ускорить чтение, но работать с данными будет сложнее: они занимают больше места, а структуру денормализованных таблиц сложнее менять при развитии базы.

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

Мы можем ввести дополнительную таблицу, хранящую рассчитанную заранее сумму заказов каждого пользователя.

Так возникает необходимость поддерживать консистентность данных — их согласованность в двух таблицах: таблице с заказами и в таблице с суммой заказов пользователей. Это решается несколькими способами:

  • записывать данные в обе таблицы транзакционно (одновременно);

  • обновлять данные во второй таблице в асинхронном режиме (фоново), пересчитывая суммы заказов на основе первой таблицы. Такой вариант подходит, если допустима небольшая задержка обновления данных по суммам заказов.
Необходимость поддержания консистентности данных усложняет логику системы и такой подход должен быть оправдан. Использовать денормализацию нужно когда вы точно уверены, что правильно настроенные индексы и оптимизированные запросы уже не обеспечивают необходимую скорость запросов.



Кэширование

Кэширование представляет собой технологию временного хранения данных и подходит для часто запрашиваемых и редко меняющихся данных (в маркетплейсе — список брендов или категории товаров). Для их отображения не обязательно каждый раз делать запрос в базу.

Можно использовать In-Memory базы данных, например Redis или Memcached. Эти базы хранят данные прямо в оперативной памяти, что обеспечивает очень быстрое чтение информации.

С внедрением кэш-хранилища архитектура нашего маркетплейса из примера изменится следующим образом:

Управление требованиями и управление архитектурой ИТ
Рис.3 — Архитектура системы после внедрения кэш-хранилища

Репликация

Другой механизм оптимизации — репликация хранилища. Репликация заключается в разворачивании дополнительных баз (реплик) и постоянном копировании (репликации) на них данных с главной (мастер) базы.

Архитектура системы будет выглядеть следующим образом:
Управление требованиями и управление архитектурой ИТ
Рис.4 — Архитектура системы при применении репликации
При этом запись данных производится только в мастер-базу, а реплики используются исключительно для чтения.

Шардирование

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

Шардирование можно применять не только для увеличения производительности, но и в случаях, когда объем данных настолько большой, что они физически не помещаются на сервере из-за аппаратных ограничений.
Шардирование — деление данных на сегменты с хранением их на разных серверах. При шардировании необходимо определить ключ (признак), по которому данные будут делиться. В нашем примере с маркетплейсом можно поделить товары по бренду. Необходимо выделить дополнительную базу для хранения метаданных — информации о том, на каком шарде хранятся данные по каждому бренду.
Управление требованиями и управление архитектурой ИТ
Рис.5 — Архитектура системы при применении шардирования

Резюме

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

  2. 90% проблем с производительностью информационной системы заключаются в БД.

  3. Начинать оптимизацию базы нужно с наиболее простых действий: подбор оптимальных настроек СУБД, оптимизация SQL-запросов, внедрение индексов. Это может дать значительный прирост производительности при грамотном подходе.

Воркшоп Дарьи Колесовой из Яндекса


«От проектирования до эксплуатации:

реляционные БД и SQL-запросы для аналитика

(на примере PostgreSQL)»

8 часов в выходные 17-18 февраля

Ждём начинающих ИТ-специалистов, которые хотят:
  • научиться проектировать физическую модель реляционной БД, наполнять её данными и
  • делать базовые SQL-запросы к ней (операторы SELECT, WHERE, LIKE, ORDER BY, GROUP BY, HAVING, JOIN)
Ваш промокод: SQL50 даст скидку 50%

Ответы на вопросы

  • Вопрос:
    Всегда ли нужна база с метаданными при шардировании?
    Ответ:
    Использовать метабазу необязательно. Данные могут разноситься по шардам не только по какому-то смысловому ключу, как в примере с брендами в статье. Например, письма в Яндекс.Почта хранятся более чем на 20 шардах без использования метабазы. В каждом письме есть хэш пользователя, указывающий на нужный шард.

    В PostgreSQL существует расширение PL/Proxy — механизм, упрощающий работу с базами данных при масштабировании; промежуточный слой между базой данных и приложением. Приложению не обязательно знать в каком узле находятся нужные данные, оно направит запрос к proxy, а proxy самостоятельно определит, к какому узлу нужно сделать запрос данных.
  • Вопрос:
    Какие есть советы для геораспределения? Есть ли смысл располагать дата-центры ближе к пользователю?
    Ответ:
    Желательно, чтобы ping (время реакции на запрос) между приложением и БД был как можно меньше. Расположение дата-центров ближе к пользователю не имеет особого смысла, пользователь не заметит миллисекунды задержки.

    Размещение данных в разных дата-центрах может также применяться для отказоустойчивости: если произойдет авария в одном из дата-центров, его заменят расположенные в других местах.
  • Вопрос:
    Почему на ваших проектах в основном используется PostgreSQL?
    Ответ:
    В основном по двум причинам:
    1. PostgreSQL — зрелое решение, в котором решены многие проблемы и задачи.
    2. Меньшая стоимость по сравнению с другими СУБД.
  • Вопрос:
    Допустим, что в БД реализовано шардирование, но запросы затрагивают все данные. Будет ли в таком случае прирост производительности?
    Ответ:
    Зависит от того, как вы отправляете запросы к шардам. Если запросы отправляются параллельно, то прирост производительности будет, даже когда запросы затрагивают данные на всех шардах.
  • Вопрос:
    Можно ли использовать репликацию совместно с денормализацией?
    Ответ:
    Все перечисленные в статье методики можно использовать совместно.

■ Другие статьи по теме Базы данных

Показать еще