Google Analytics

воскресенье, 20 сентября 2009 г.

SQL базы данных не масштабируются

Вольный перевод статьи "SQL Databases Don't Scale" Adam Wiggins.
Вопрос, на который я часто отвечаю: "Как вы масштабируете SQL базу данных?". Есть масса вещей, которые я мог сказать об этом: использование кэширования, шардинга и других техник по снятию нагрузки с базы данных. Но реальный ответ: "Не масштабируется". SQL базы данных фундаментально не масштабируемы, и не существует никакой волшебной эльфиской пыли, которой мы или кто-нибудь может посыпать на них, чтобы сделать их масштабируемыми.

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

Чтобы считаться истинной масштабируемостью, техника должна соответствовать следующим критериям:
  1. Горизонтальное масштабирование: больше серверов создадите, больше возможностей получите.
  2. Прозрачность для приложения: бизнес логика приложения должна быть изолирована от масштабируемых серверных ресурсов.
  3. Нет единой точки отказа: не должно быть ни одного сервера, потеря которого, является причиной остановки приложения.
Как пример из мира аппаратного обеспечения RAID5, дающий истинное масштабирование:

  1. Горизонтальная масштабируемость: вы можете запустить RAID5 с 4, 12 или 20 дисками; больше дисков дают большее пространство и лучшую производительность.
  2. Прозрачность для приложения: приложения используют RAID как единое устройство. Мой текстовый редактор не заботит, что загрузка или сохранение файла происходит с раздельных физических дисков.
  3. Нет единой точки отказа: вы можете выдернуть диск и массив продолжит функционировать (хотя с потерей производительности, известной как "degraded mode"). Замените диск и все восстановиться само.

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

Вертикальное масштабирование

Один из путей масштабировать SQL базу данных, купить "большой ящик". Это обычно называется "вертикальным масштабированием". Я иногда называю это: масштабирование по закону Мура. Какие проблемы с этим методом?

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

Я знаю много людей, кто достиг вершины на последней точке (обычно где-нибудь около 256-ядерного Sun сервера) и сейчас они загнаны в угол. Сидят скрестив пальцы и надеются, что рост остановиться.
Да, вы можете поместить SQL базу данных в "большой ящик", тем самым расширев себе габариты. Но это нарушает пункт 1 моего списка истинной масштабируемости.

Декомпозиция, aka шардинг

Шардинг делит ваши данные по некоторым видам специфичных для приложения границ. Например, вы можете сохранять пользователей чьи имена начинаются с А-М в одной базе данных, а с Н-Я в другой. Или использовать выражение от идентификатора пользователя как номер базы данных.
Это требует глубокой интеграции в приложение и тщательного планирования разделяющих схем отностильно схем баз данных и вида запросов, которые вы хотите выполнять. В итоге большие проблемы.
Пока шардинг форма горизонтального масштабирования, это нарушение пункта 2: нет прозрачности для бизнес логики приложения.
Серьезные проблемы в декомпозиции SQL баз данных это отношения, большинство значений в реляционных базах данных храниться в виде отношений. Однажды вы разделите записи на несколько серверов, разделите множество отношений, которые вынуждены будете реконструировать на клиентской стороне. Шардинг разрушает большинство из значений в реляционной базе данных.

Подчиненные для чтения

MySQL имеет важную особенность - легко конфигурируемую master-slave репликацию, где вы имеете подчиненный сервер с базой данных только для чтения, который реплицирует все происходящее на основном сервере баз данных в реальном времени. Затем, вы можете создать, маршрутизирующий прокси между клиентами и вашей базой данных (или использовать интелектуальную маршрутизацию в клиентской библиотеке), который посылает любые запросы на чтение(SELECT) на один из подчиненных серверов, пока запросы на запись(INSERT, UPDATE, DELETE) посылаються на основной.
PostgreSQL имеет репликацию под названием Slony, думаю, она более обременительна в настройке, чем репликаци MySQL. Год назад, я даже сделал простую master-slave репликацию, с помощью 50-строчного Perl скрипта, который читал данные из лога запросов и зеркалировал все запросы на запись на подчиненные сервера. И так master-slave репликаиция возможна где угодно, с различной степенью головной боли при установке и поддержке.
Техника подчиненный для чтения это лучшая альтернатива для масштабирования SQL баз данных. Ее можно назвать масштабируемой на стороне чтения, и прозрачной для приложения. Эта техника используется на множестве больших инсталяций MySQL.
И еще, это все еще ограниченая техника. Основной сервер это бутылочное горлышко, для приложений с большим количеством операций записи. И она не соответствует пункту 3 определений истинной масштабируемости: единая точка отказа. Эта проблема не только, когда база данных падает, но и когда вы поддерживаете ее. Переключение одного из подчиненных серверов в режим основного, позволит вам востановиться относительно быстро, но это переключение требует личного присутствия системных администраторов.
Эту технику можно назвать горизонтальной масштабируемостью производительности чтения, но она уже не является таковой для записи и объема. Горизонтальная масштабируемость должна распространяться и на выполнение запросов и на хранилище данных. Это также, как вы можете увеличить пространство хранилища при RAID, добавив достаточно дисков. И вы можете получить RAID, который имеет лучшую производительность, чем любой единичный жесткий диск на рынке. Подчиненные для чтения сервера требуют полных копий базы данных, поэтому вы все еще имеет ограничение в количестве хранимых данных.

Долгосрочное решение

Куда мы пришли? Некоторые могут ответить: "пробуйте масштабировать SQL базы данных". Я не соглашусь с таким мнением. Когда сотни компаний и тысячи блестящих программистов и системных администраторов пытались решить проблему двадцать лет и все еще не нашли очевидного решения, которое бы приняли все, это говорит мне, что проблема нерешаема. Мы можем решить эту проблему только переопределяя вопрос.

1 комментарий:

  1. Автор лукавит:
    > Нет единой точки отказа: не должно быть ни одного сервера, потеря которого, является причиной остановки приложения.
    > пример из мира аппаратного обеспечения RAID5, дающий истинное масштабирование

    выход из строя raid-контроллера блокирует работу всего массива и в общем случае ведёт к потере данных.

    ОтветитьУдалить