"Предельная производительность" - термин, который мы придумали вместе с моим коллегой в 2002 г. применительно к одной из составляющих моей концепции построения систем баз данных, обладающих хорошей масштабируемостью и высокой производительностью. Эту тему я обсуждал на протяжении последних нескольких лет и хочу ненадолго к ней вернуться.
Поистине, чем больше вещи меняются, тем больше они остаются неизменными. Сегодня SQL Server и любая другая существующая на рынке крупная технология баз данных значительно более совершенны, чем 5 лет назад, но я продолжаю снова и снова совершать одни и те же простые ошибки.
Моя концепция настройки предельной производительности имеет два центральных элемента.
Во-первых, следует предполагать, что исходный код будет работать в условиях, значительно более напряженных, чем ожидается изначально. Возможно, предельный уровень производительности никогда не понадобится, но значительно проще сразу разработать эффективное приложение, чем исправлять его недостатки после развертывания. Во-вторых, никогда не следует забывать, что масштабирование проще выполнять на уровне приложений, чем на уровне базы данных. Рассмотрим, какое отношение эти принципы настройки экстремальной производительности имеют к ежедневной практике построения систем.
Во-первых, заметим, что предельная производительность не предполагает выполнения особых контрольных задач по определению числа транзакций в секунду. Понятие "предельная" означает сверхвысокий уровень расширяемости, но обсуждаемые здесь проблемы возникают и в "нормальных" системах не в меньшей степени, чем в системах, потребляющих столько же электроэнергии, сколько дом, в котором я живу.
Я следую первому правилу настройки предельной производительности - предполагаю, что приложение будет функционировать в условиях, значительно более напряженных, чем ожидается изначально. Я зарабатываю на жизнь как консультант по SQL Server. Многие проблемы, в решении которых мне довелось помогать клиентам за последние 15 лет, выросли из безобидных рассуждений в среде группы разработки такого типа: "Об этом нечего беспокоиться, эта система никогда не будет работать в таком напряженном режиме". Как избежать проблемы недостаточной производительности? В основном это - вопрос здравого смысла. Не следует пользоваться комбинациями быстрого вызова, известными низкой эффективностью, просто потому, что когда-нибудь это может привести к созданию узких мест. Кроме того, следует протестировать системы с использованием подходящего количества данных.
Безусловно, выполнение всестороннего теста на определение производительности требует больших усилий. Сторонние поставщики еще не нашли способа облегчить эту задачу. Честно говоря, меня это отчасти устраивает. Большая часть моего заработка связана с оказанием помощи клиентам в решении проблем производительности, и если независимые поставщики в конце концов облегчат задачу предупреждения возникновения таких проблем, мне придется искать другое занятие.
Что касается второго правила настройки предельной производительности, может возникнуть вопрос: "Неужели масштабирование проще выполнять на уровне приложений, чем на уровне базы данных?"
Безусловно. По сравнению с SQL Server, компания Oracle продвинулась несколько дальше в области распределенных вычислений, однако ни одному из поставщиков баз данных пока не удалось реализовать легкое масштабирование «фермы» Web-серверов, расширяемой просто путем добавления новых серверов. Масштабирование сервера базы данных часто требует замены старого сервера на принципиально новый. Разработка приложения, позволяющего выполнять масштабирование базы данных - трудная задача. Но всегда следует помнить, что масштабирование группы серверов приложений выполнять проще, чем масштабирование сервера базы данных. Не буду называть имена, но мне довелось работать с клиентом, чьи специалисты по разработке систем (к счастью, давно уже не работающие) включили почти все - в полном смысле этого слова - в базу данных. Результатом стала специфическая система с организацией очереди, с широким использованием курсоров, на удивление сложными метаданными и массой других проблем, плохо решаемых на уровне базы данных. Выполнение работы, которая может быть сделана на уровне приложений, в базе данных, даже если таковая способна решать поставленные перед ней задачи, нарушает принципы настройки предельной производительности.
Я наблюдал, как клиенты безуспешно пытаются решить проблему производительности на стороне серверной базы данных путем значительной переработки кода, что может оказаться трудным и болезненным занятием. Если бы изначально определенные часто используемые хранимые процедуры были спроектированы в качестве компонентов среднего уровня, решением стало бы добавление к имеющейся группе серверов еще одного Web-сервера, приобретаемого по доступной цене.
Хотя эти хранимые процедуры могли бы вначале обеспечивать более высокую пропускную способность, чем компоненты среднего уровня, иногда лучше тщательно взвесить возможные последствия различных "если".
Отчасти хотелось бы утверждать, что предотвращение подавляющего большинства проблем с производительностью - действительно лишь вопрос здравого смысла, планирования и тестирования. Однако я занимаюсь настройкой производительности уже свыше 10 лет и помог не одной сотне клиентов в решении крупных и мелких вопросов. Я знаю, что предотвратить проблему производительности сложнее, чем просто сказать, что "это - вопрос здравого смысла". Большинство моих клиентов - грамотные специалисты, и если бы предотвратить проблемы производительности было просто, они бы уже это сделали. Но верно также и то, что следовать некоторым из основных правил проще, чем может показаться. Я постоянно убеждаюсь, что придерживаться концепции экстремальной производительности относительно просто, и это может помочь избежать многих неприятностей с производительностью из-за неожиданно выявляющихся ошибок в типовых средах баз данных. Совсем как в рекламе: попробуй - тебе понравится!
Брайан Моран, brian@solidqualitylearning.com