2010 г.
Дом на песке
Пэт Хелланд, Дейв Кэмпбел
Перевод: Сергей Кузнецов
Назад Содержание Вперёд
5. Ослабление абстракции
OK... Тогда, может быть, сработает более свободная абстракция!
В старой модели предполагалось, что работа может производиться только в одном порядке выполнения. Классическая система баз данных, работающая в основном узле, обеспечивала изоляцию в форме "единственной системы записи" (single system of record). Эта единственная история предусматривает низкоуровневую семантику операций чтения и записи, расчитанную на "воспроизведение истории".
В нашем новом мире историю в точности воспроизвести невозможно, и мы должны принимать во внимание возможность переупорядочивания работы. Это означает, что мы не можем полностью знать точное состояние системы. Это также означает, что семантика корректности и переупорядочивания должна основываться не на свойствах системы (т.е. операциях чтения и записи), а на бизнес-операциях, поддерживаемых приложением.
В разд. 5 анализируется ряд различных аспектов асихронной установки контрольных точек и то, как это влияет на разработку приложений. Сначала будет обсуждаться влияние асинхронности на нашу возможность знать истинное состояние приложения. Затем мы рассмотрим вероятностные бизнес-правила и покажем, что асинхронная установка контрольных точек не позволяет их точно соблюдать. Мы обсудим влияние коммутативности бизнес-правил. Далее мы рассмотрим разделение работы и идемпотентные операции при наличии разделенного состояния. После этого мы проанализируем возможность выбора средств синхронной установки контрольных точек состояния, если для некоторой конкретной операции риск слишком велик. Вслед за этим мы рассмотрим, как система может справиться с непредвиденными проблемами, и когда может потребоваться человеческое вмешательство. Затем мы обсудим, каким образом асихронное соблюдение правил иногда приводит к плохим результатам. В заключение мы отмечаем, что либо нужно обеспечивать синхронные контрольные точки с резервными копиями, либо следует быть готовым к извинениям за поведение системы...
5.1 Асинхронность и истинность
Обсудим эти осиротевшие транзакции из примера с доставкой журнала, застрявшие в чреве отказавшей системы. Они наверняка не влияют на ситуацию до тех, пор, пока отказавшая система (или центр данных) остается недоступным. Когда же эта система вновь обретет работоспособность, целью любой политики восстановления будет анализ работы, которой соответствует заключительная часть журнала, и определение того, что с ней делать! Резервная система продолжала работать, и может быть проблематично заново воспроизвести эту работу. Единственный способ сберечь эту работу состоит в том, чтобы удостовериться, что ее повторное выполнение не в исходном порядке не принесет вреда. В некоторых случаях "повисшая" работа просто отбрасывается из-за отсутствия механизма для ее воспроизведения! Это является частью неявной модели согласованности при доставке журнала без восстановления потерянной работы.
В примере с доставкой журнала мы видим редкие случаи переупорядочивания работ, когда они теряются, а потом восстанавливаются. В более общем случае мы видим независимую работу, выполняемую в отсоединенном (или слабо подсоединенном) узле, которая может быть переупорядочена, когда становится видимой другим системам, имеющим отношение к этой работе.
Более глубокое наблюдение состоит в том, что следующие два вещи являются связанными:
-
переход от синхронной к асинхронной установке контрольных точек для уменьшения задержки и
-
утрата непререкаемой истины.
|
Когда у нас была централизованная машина с синхронной установкой контрольных точек, мы знали один и только один ответ в каждый момент времени. Но если допустить изолированность работы в недоступной резервной системе (бывшей до своего отказа основной системой), то истина становится неизвестной.
5.2 Вероятностные бизнес-правила
При наличии асинхронной установки контрольных точек появляются временные промежутки (окна) такие, что если в этом промежутке времени происходит сбой, то уже выполненная работа может быть потеряна или отложена. Если отказывает основная система, то внутри нее может остаться завершенная работа, данные о которой еще не были переданы в резервную систему. Эта работа либо теряется, либо откладывается (т.е. воспроизводится после восстановления работоспособности бывшего основного узла).
Если в основной системе используется асинхронная установка контрольных точек, и к поступающей от приложения работе применяется некоторое бизнес-правило, то это правило необходимо является вероятностным. Основной системе, независимо от ее намерений, не может быть точно известно, сохранит ли она работоспособность для поддержки бизнес-правил.
В тех случаях, когда резервная система, участвующая в соблюдении этих бизнес-правил, асинхронным образом связывается с первичной системой, соблюдение правил неминуемо становится вероятностным!
Анализ затрат и результатов показывает, что выгода от сокращения задержки при асинхронной установке контрольных точек перевешивает возможные потери из-за неприменения бизнес-правил, обобщающих отказоустойчивый алгоритм.
Распределенность + асинхронность → вероятности обеспечения применения правил
|
Мы наблюдаем появление приложений, в которых разобщенность еще больше увеличивается для достижения экономической выгоды от слабо связанного параллелизма и автономной работы. В таких приложениях меньше задержек, больше параллелизма и доступности. Зато они чаще делают ошибки и позже устаняют беспорядок. Иногда это идет на пользу!
5.3 Коммутативность и бизнес-правила
Во многих приложениях можно сформулировать свойственные им бизнес-правила и допустить изменение порядка выполнения различых операций. Когда эти операции выполняются в раздельных системах, и порядок их выполнения может изменяться, важно соблюдать эти бизнес-правила.
К числу примеров бизнес-правил относятся следующие: "Нельзя резервировать билеты на авиарейс в объеме, более чем на 15% превышающем число мест в самолете" или "Нельзя допускать овердрафт на текущем счете".
Депозитарные блокировки в сериализуемых базах данных
Депозитарные блокировки (escrow locking) – это схема, позволяющая повысить уровень параллелизма транзакций с сохранением их классического ACID-поведения.
Если допустить наличие набора коммутативных операций (таких как увеличение и уменьшение), то можно использовать "журнализацию операций" ("operation logging”). При журнализации операций не сохраняются старое и новое значения соответствующего поля, а запись в журнале содержит данные типа "Транзакция T1 вычла $10". Если транзакцию T1 потребуется аварийно завершить, система просто увеличит значение этого поля на $10, а не будет восстанавливать его значение до выполнения данной операции. Таким образом, работа нескольких транзакций может перемежаться, пока в них выполняются только коммутативные операции. Если в какой-либо операции по отношению к данному полю выполняется операция чтения, которая коммутативной не является, она портит всю картину и останавливает параллельную работу.
Депозитарные блокировки можно реализовать совместно с ограничениями, поддерживающими бизнес-правила. Рассмотрим операции увеличения и уменьшения с заданными ограничениями на минимальное и максимальное значения соответствующего поля. От системы просто требуется отслеживать эти значения и при их достижении задерживать фиксацию транзакций. Выполнение новой операции может быть задержано, если оно МОЖЕТ привести к недопустимому значению поля.
У депозитарных блокировок имеется четкая семантика, поскольку они поддерживаются централизованным образом, и при этом соблюдаются ограничения бизнес-правил.
|
Этот подход похож на описанный в [9] метод депозитарных блокировок. При применении этого метода допускается выполнение коммутативных операций, если только они не нарушают ограничений системы. Депозитарные блокировки представляют собой пессимистическую схему блокировок, строго поддерживающую сериализуемое поведение транзакций. Метод депозитарных блокировок был реализован в NonStop SQL компании Tandem в конце 1980-х гг. для поддержки высокопропускных транзакций с операциями увеличения и уменьшения.
Операции записи в базу данных не коммутативны!
Построение произвольного приложения поверх системы хранения данных препятствует переупорядочиванию операций. Желательной слабой связанности можно достичь только при использовании коммутативных операций. Операции приложения могут быть коммутативными, операции записи не коммутативны. Система хранения (т.е. операции чтения и записи) – это неудобная абстракция...
|
5.4 Идемпотентность и разделяемые потоки работ
Важно обеспечивать идемпотентность одиночных операций. Это следует учитывать при разработке приложений, допускающих асинхронность, поскольку идемпотентность операций способствует отказоустойчивости и допускает слабую связанность, что, в свою очередь, позволяет снизить задержку, облегчает масштабирование и дает возможность автономной работы.
Каждая операция должна производить одно и только одно воздействие, даже если она выполняется (или просто журнализуется) в нескольких репликах. Бронирование одной комнаты в гостинице должно (с высокой вероятностью) приводить к тому, что постоялец получит в точности одну комнату. Заказ в режиме онлайн одной книги не должен (очень часто) приводить к отправке заказчику двух книг.
Чтобы это гарантировать, приложение обычно связывает с каждой работой уникальный номер, или идентификатор. Это связывание происходит на входе в систему (т.е. независимо от того, в какой реплике эта работа будет выполняться изначально)3. Когда запрос данной работы двигается по сети, каждая реплика может легко опознать, что уже встречала эту операцию, и не выполнять работу повторно.
Иногда поступающая работа стимулирует выполнение другой работы. Например, обработка заказа на покупку может привести к планированию доставки. Обработкой
этого заказа и даже планированием доставки могут заняться, например, две реплики. При наличии уникальной идентификации заказа на покупку на входе в систему этот избыток энтузиазма со стороны реплик системы можно выявлять по мере того как информация распространяется по сети. Ниже, при обсуждении согласованности "рано или поздно" (eventual consistency) мы увидим, как это можно проделать (вероятностным образом).
Уникальный идентификатор работы ("uniquifier") играет две важные роли:
-
используется в качестве ключа при разделении работы в масштабируемой системе;
-
позволяет системе выявлять повторное выполнение одного и того же запроса; в результате работа становится идемпотентной.
5.5 Насколько вы склонны к риску?
Во всех этих случаях мы исходим из предположения, что для обсуждаемых приложений недопустимы расходы на знание полной истины. Следовательно, мы разрабатываем систему и в особенности приложения, выполняемые в этой системе, в расчете на то, что они, вероятно, будут предоставлять пользователям отличный сервис и время от времени будут нарушать бизнес-правила, свойственные приложениям.
Заметим, что можно иметь несколько бизнес-правил с разными гарантиями. Для некоторых операций классическая согласованность может быть предпочтительнее доступности (т.е. они будут выполняться медленнее, порождать задержку и всегда приводить к гарантированным результатам). Другие операции могут быть более "кавалеристскими". Некоторые примеры:
-
Локально выплачивать деньги по чеку на сумму, меньшую $10000. Если сумма чека превосходит $10000, произвести проверку с использованием всех реплик.
-
Планировать доставку книги "Гарри Поттер", исходя из локальной оценки наличия. В отличие от этого, для доставки одного и только одного экземпляра Библии Гутенберга требуется строгая координация!
Основная идея состоит в том, что доступность (и ее спутники – возможность автономной работы и сокращение времени задержки) можно балансировать с классическими понятиями согласованности. Эту балансировку часто можно применять к многим разным аспектам на многих уровнях гранулярности одного приложения.
|
5.6 Волнения и жалобы (но не слишком частые)
И что же делать, если при работе приложения ДЕЙСТВИТЕЛЬНО нарушаются бизнес-правила? Обычно приложения разрабатываются таким образом, чтобы вероятность таких нарушений была мала (поскольку они вызывают существенные эксплуатационные расходы). Но, тем не менее, рано или поздно это случится!
Справляться с нарушениями бизнес-правил лучше всего следующим образом:
-
послать информацию о возникшей проблеме заинтересованному человеку (по электронной почте или как-нибудь еще);
-
если это слишком расточительно, написать некоторое специализированное для данной области бизнеса программное обеспечение, позволяющее снизить вероятность возникновения подобных проблем.
Хотя такой подход может показаться слишком упрощенным, именно ему следуют разработчики приложений, наталкиваясь на проблемные ситуации. Это также говорит о том, что при отсутствии обобщений бизнес-правил, возможности обеспечения коммутативности бизнес-операций и бизнес-сложностей, вызываемых работой чрезмерно усердных приложений, невозможно говорить с бизнесом о последствиях проблем, вызываемых нарушением бизнес-правил, или о каких-либо компенсационных действиях.
5.7 Запоминания, предположения и извинения
Можно утверждать, что весь компьютинг в действительности распадается на три категории: запоминания, предположения и извинения [16, 19]. Идея состоит в том, что все делается в локальном режиме с применением некоторой части глобального знания. Вы знаете, что вы узнаете, когда выполнится некоторое действие. Поскольку вы обладаете только частью знания, ваши действия на самом деле являются только предположениями. При подключении знаний какой-либо реплики может возникнуть очень неприятная ситуация. Согласование действий реплики и ее двойника может привести к пониманию, что требуется расчистка завала. При этом может возникнуть потребность в извинении за поведение основной системы (или ее реплики).
Итак, рассмотрим три эти аспекта:
-
Запоминания: Ваша локальная реплика видит то, что видит, и (следует надеяться) запоминает это. В стоимость распространения этого знания входят сетевые и вычислительные расходы, а также расходы, вызываемые задержкой ответа (в том случае, когда вы ожидаете потверждение от резервной системы на свою операцию запоминания).
-
Предположения: Всякий раз, когда в приложении предпринимается некоторое действие на основе локальной информации, это действие может оказаться ложным. Так случается в системах с доставкой журнала, где действие журнализуется локально, и имеется только высокая вероятность получения журнала резервной системы до отказа основной системы и перехвата управления. Поэтому предположение об обоснованности действия можно считать разумным, но нельзя считать его бесспорным. В любой системе, допускающей отход от абсолютной истины, бесспорность действия можно только предполагать. Качество этого предположения зависит от требований бизнеса.
-
Извинения: Если вы совершаете некоторую ошибку (из-за аномалий репликации или из-за того, что Федеральное управление гражданской авиации запретило полеты ваших самолетов, и вы не можете выполнить свои обязательства перед пассажирами, забронировавшими на них места), вы приносите свои извинения. Потребность в извинениях возникает в любом бизнесе. Как отмечалось выше, извинения перед клиентами за работу программного обеспечения, приведшую к бизнес-проблемам, могут отправляться вручную. В качестве альтернативы, некоторые извинения могут генерироваться специально разработанным кодом приложения, а при возникновении заранее непредусмотренных "нехороших" ситуаций пользователям направляется просьба о помощи.
В слабо связанном мире, в котором доступность предпочтительнее согласованности, весь компьютинг лучше всего представлять как состоящий из запоминаний, предположений и извинений.
5.8 Синхронные контрольные точки ИЛИ извинения!
Итак, в разд. 5 мы отмечаем, что имеются следующие варианты разработки:
-
вы можете использовать сихронные контрольные точки и подвергать пользователей задержкам, или
-
вы можете использовать асинхронные контрольные точки, снижать время задержек и иметь дело с измененной семантикой приложений.
Эта измененная семантика означает, что вам не всегда известна точная истина, поскольку работу может перехватить партнер. Она означает, что может потребоваться понимание вероятностной природы соблюдения бизнес-правил и возможности переупорядочивания операций. Тем не менее, имеется вариант применения бизнес-критериев (например, наличие чека на сумму больше $10000), которые вызывают применение синхронной установки контрольных точек. Кроме того, полностью приемлемо допущение человеческого вмешательства в разрешение некоторых проблем, если это происходит настолько редко, что не противоречит соображениям экономеческой целесообразности.
Коротко говоря, выбор этих вариантов зависит от их значимости для бизнеса.
3Искушенный читатель поймет, что при этом проблема идемпотентности перемещается в сообщение, поступающее от клиента в точку входа. Повторные посылки одного и того же сообщения приводят к тому, что его обработкой начинают заниматься несколько разных реплик. Если у этой работы нет побочных эффектов (например, если она сводится к чтению каких-либо данных), то ее можно без проблем выполнить несколько раз. Если же работа производит побочные эфффекты, то обычно для исключения ее дублирования производится координация на основе куки (cookie) или идентификатора пользователя.
Для исключения повторной обработки идентификатор запроса должен функционально зависеть только от запроса в понимании серверной системы. Это возможно, если уникальный идентификатор генерируется вне сервера (например, контрольный номер (check number), обсуждаемый в подразделе 6.2), или если сервер вычисляет его некоторым предсказуемым образом (как это обсуждалось в подразделе 2.1).
Назад Содержание Вперёд