Шестая лекция нашего курса «Анализ требований к информационным системам» подходит к завершению. На очереди пятый модуль, в котором мы обратим наше внимание на аспекты проектирования, о которых не говорили ранее. Осталось не так много деталей анализа требований, о которых мы поговорим в нашем курсе, но, безусловно, мы рассмотрим те из них, которые дополнят общую картину деятельности и будут вам полезны при выполнении практических задач по проектированию и анализу.
Сегодня мы будем говорить о высоконагруженных и многопользовательских приложениях, а точнее, о том, как проектировать такие системы, на что обращать внимание и что выделять для того, чтобы ваши системы получились качественными и оправдывающими ожидания заинтересованных сторон. Высоконагруженные и многопользовательские приложения отличаются от простых информационных систем тем, что для подобных приложений требуется уделять дополнительное внимание тем аспектам, которые составляют основу высокопроизводительной обработки данных. О таких приложениях и основных аспектах фокусировки мы и поговорим сегодня.
Основные аспекты, на которые следует обратить внимание, когда мы говорим о высоконагруженных и многопользовательских приложениях, – это надежность выполнения транзакций, количество одновременно работающих в системе пользователей и возможность увеличения производительности в тех местах, которые оказываются наиболее загруженными при выполнении рутинных бизнес-операций. Современный виток развития отрасли информационных технологий предлагает несколько решений этих проблем, самым популярным из которых является создание приложения в виде сервисов или микросервисов. Это архитектурные паттерны, которые получили широкую известность как сервис-ориентированная архитектура или микросервисная архитектура. Эти типы архитектур позволяют отслеживать наиболее перегруженные части бизнес-операций и гибко масштабировать их за счет увеличения инфраструктурных мощностей. Дополнительные аспекты, на которые нужно обратить внимание и о которых следует поговорить, – это принципы обработки информации. Сейчас эти принципы широко обсуждаются в виде двух теорем. Первая – ACID. Это набор требований к транзакционной системе (или ее модулю), которая должна обеспечить надежную и предсказуемую работу. Эти требования выражаются в атомарности, согласованности, устойчивости и изоляции. Вторая теорема – CAP, или теорема Брюера. Это опытным путем выведенное утверждение о том, что при реализации систем, поддерживающих распределенные вычисления, возможно обеспечить не более двух из трех следующих свойств – согласованность данных во всех вычислительных узлах в один момент времени, доступность системы в любой момент времени, а также устойчивость к разделению на несколько изолированных модулей, которое не должно приводить к некорректности отклика от системы.
Когда речь заходит о высоконагруженных и многопользовательских приложениях, важно понять, почему они выделяются в отдельную категорию систем и в чем ценность от такого выделения. Высоконагруженное многопользовательское приложение – самоописательная категория информационных систем. Их назначение – автоматизировать и выполнять работу большого количества пользователей под высокими системными нагрузками. Это характеризует зрелые приложения с большим количеством пользователей. И вот тут очень тонкая грань: а какое количество пользователей считается большим? Можно ли в самом начале понять, что вот это приложение будет высоконагруженным и многопользовательским, а это – нет? И почему важно это понимать? А понимать это надо затем, чтобы правильным образом выстроить архитектуру приложения. Чем выше нагрузки, тем большее внимание уделяется компонентам, слоям системы и их взаимодействиям. Если в среднепользовательском приложении не так важны отдельные детали, используемые базы данных и способ учета информации, то чем более критичная система, тем эти детали становятся все более и более важными. А ведь трудно себе представить высоконагруженную и многопользовательскую систему, которая выполняет функции, не критичные для своих пользователей. Основные аспекты, которые выходят на первый план, – надежность в выполнении транзакций и операций, надежность по учету данных, возможность гибкого горизонтального и вертикального масштабирования в зависимости от нагрузки на систему, а также удобство сопровождения и развития системы.
Первый аспект, который мы должны разобрать, – надежность, точнее, надежность при работе с данными. В этом плане есть две основных технологии – SQL и NoSQL. Идея, лежащая в основе баз данных, появилась задолго до создания компьютеров. Она представлена шкафами, в которых хранились документы, и библиотеками. До появления баз данных такие хранилища документов были лучшим из того, что тогда существовало. С развитием компьютеров развивались и решения для хранения данных. В 1970-х годах Эдгар Кодд, инженер из IBM, опубликовал статью о системе реляционных баз данных. Его идеи привели к революции в обработке данных, так как данные рассматривались как «объекты». Этот подход, в сочетании с возникновением объектно-ориентированных языков программирования, сделал возможным разработку приложений, основанную на данных. Это показало программистам, как одни данные связаны с другими, и дало возможность связывать вместе разные «объекты», пользуясь различными типами отношений между объектами. Так и появился SQL. А в 1998 году, вскоре после того, как бурно развился Интернет и упала стоимость хранилищ данных, появилось понятие NoSQL (Not only SQL, (не только SQL)). NoSQL базы данных были предназначены для более крупных объемов данных, чем SQL базы данных, – для тех, которые сложно структурировать, используя реляционный подход. Это позволило быстрее обрабатывать более масштабные наборы данных, имеющих различную структуру. Базы данных NoSQL были гибче, чем типичные SQL базы данных.
SQL масштабируется вертикально, то есть путем увеличения производительности за счет использования более мощных серверов. SQL базы данных сложнее масштабировать, чем NoSQL базы данных.
NoSQL масштабируется горизонтально, то есть путем добавления дополнительных узлов к уже существующим, использующимся узлам. Это упрощает масштабирование – при необходимости можно быстро как повысить, так и понизить мощность системы. Кроме того, это означает, что владелец NoSQL базы данных может увеличивать ее мощность практически неограниченно. SQL базы данных строже, они не такие гибкие, как NoSQL базы данных, но они отлично подходят для организации работы с теми данными, обращение с которыми требует единообразия и четких схем данных. NoSQL базы данных, с другой стороны, гораздо гибче, они дают возможность работать с разными структурами данных в различных сценариях. Это делает их универсальнее.
Следующий аспект, о котором нужно поговорить, – надежность в исполнении процессов, которая ведет к надежности и последовательности в организации процессной деятельности и к последовательному совершенствованию всех бизнес-процессов, задействованных в формировании итоговой ценности. Два главных подхода, проверенные временем, которые помогают компаниям в этом, – LIN и Six Sigma. Методология Lean Six Sigma появилась в результате объединения методов бережливого производства (Lean), основой которого является сокращение потерь и ускорение процессов, и Six Sigma, основой которого является улучшение качества и повышение удовлетворенности клиентов. Оба метода имеют длительную историю успешного применения, однако именно опыт их совместного использования продемонстрировал достижение наибольшего эффекта. В настоящее время методология Lean Six Sigma успешно применяется лидирующими компаниями мира во всех секторах экономической деятельности. Суть этих подходов состоит в том, что необходимо последовательно добиваться упрощения процессов и их разбиения на универсальные, взаимозаменяемые этапы, для которых требуется минимальная специализация ресурсов. Да, эти подходы имеют ограничения, но это ориентир, опираясь на который необходимо выстраивать основную работу. Так станет возможным параллельное выполнение последовательных этапов, формирующих ценность с минимальным дублированием рабочих функций. Этот подход необходимо положить в основу любой автоматизации.
Упрощение процессов и повышение надежности при работе над транзакциями и данными приводят нас к понятию информационного сервиса, то есть такого информационного объекта, в котором заложена логика, реализующая определенный процесс. У каждого сервиса есть аудитория, которая складывается из участников или потребителей результатов бизнес-процесса. Автоматизированный в сервисе процесс должен иметь ограниченную зону воздействия. Это помогает сфокусироваться на самом процессе и не вовлекать в него сторонние процессы. Владельцы процесса должны быть LIN-центричны и постоянно думать над оптимизацией и развитием своего процесса. Понятие сервиса развилось и преобразовалось в понятие сервис-ориентированной архитектуры. Сервис-ориентированная архитектура (SOA) – это метод разработки программного обеспечения, который использует программные компоненты, называемые сервисами, для создания бизнес-приложений, реализующих бизнес-процессы. Каждый сервис предоставляет бизнес-возможности, и сервисы также могут взаимодействовать друг с другом на разных платформах и разных языках программирования. Разработчики применяют эту методику для многократного использования сервисов в различных системах или объединения нескольких независимых сервисов для выполнения сложных задач. Например, несколько бизнес-процессов в организации требуют функциональности аутентификации пользователя. Вместо того чтобы переписывать код аутентификации для всех бизнес-процессов, вы можете создать единый сервис аутентификации и использовать его повторно для всех приложений. Подобным образом почти все системы в организации здравоохранения, такие как системы управления пациентами и системы электронных медицинских карт, нуждаются в регистрации пациентов. Эти системы могут вызывать единый общий сервис для выполнения задачи регистрации пациента.
Сервис-ориентированная архитектура появилась на основе эволюции понятия монолита. Монолит не выделял отдельные сервисы, он автоматизировал деятельность в целом и представлял собой сквозную автоматизацию какой-то деятельности. У этого подхода по мере развития обнаружилось много недостатков, главным из которых была сложность развития. Ответом на этом стали сервисы. Каждый сервис имеет ограниченный бизнес-контекст. В целом сервис-ориентированная архитектура представляет собой спецификацию бизнес-процессов по конкретным сервисам, где каждый отдельный сервис можно заменить более легко, чем заменить отдельный компонент монолита, реализующий подобную функциональность. Главным недостатком сервис-ориентированной архитектуры становится ее потенциальное разрастание и стремление к монолитному образованию.
Главными недостатками сервис-ориентированной архитектуры являются сложность масштабирования, постепенное разрастание и, как следствие, создание запутанного кома функциональности. Преимущества – это удобство развития и сопровождения, спецификация общей логики по набору отдельных сервисов и, как следствие, самодостаточность автоматизируемой бизнес-области.
Сервис-ориентированная архитектура, таким образом, не является идеалом развития архитектурных подходов, а стала промежуточным звеном в развитии архитектурных шаблонов. Очень быстро ей на смену пришла микросервисная архитектура, призванная нивелировать недостатки предыдущей. Основной недостаток сервиса – постепенное усложнение логики и разрастание. Бизнес-процессы развиваются, становятся более сложными и комплексными, и параллельно с этим должен разрастаться сервис. Как с этим бороться? Микросервисный подход в самом начале постулирует, что каждый бизнес-процесс должен складываться из этапов. Как бы ни разрастался сам автоматизируемый процесс, его этапы не будут разрастаться. Они могут добавляться, но само понятие этапа процесса – это понятие, ограниченное по приносимой ценности. Если в развитии процесса можно выделить этап, который приносит ценность, самодостаточен, заменяем, работает с набором уникальных данных, которые нужны для продолжения других этапов, то мы выделили микросервисы. Они должны добавляться и изменяться, но не расширяться.
Микросервисный подход – виток в развитии сервисно-ориентированной архитектуры. Так шаг за шагом, эволюционируя, мы переходим от общего к частному, к более конкретным группам пользователей со своими задачами и показателями эффективности. Так становится более просто сфокусироваться на конкретном действии или наборе действий, которое должно вносить ценность в общий результат деятельности подразделения или бизнес-единицы. Главный недостаток микросервисов заключается в том, что со временем их может стать очень много и их необходимо оркестровать, ими необходимо эффективно управлять, поддерживать их, развивать и направлять их развитие.
В качестве основных недостатков микросервисного подхода выделяют сложность оркестровки, управления и конфигурирования и необходимость постоянного мониторинга за всеми имеющимися микросервисами. В качестве преимуществ выделяют гибкую настройку бизнес-процессов за счет возможности использования наиболее подходящих микросервисов, а также возможность гибкого масштабирования производительности. Мы можем выделить дополнительные мощности тем микросервисам, которые в этом нуждаются, а не всей системе в целом. К тому же каждый микросервис сосредоточен на нуждах конкретного клиента. Так можно более просто и целенаправленно удовлетворять конкретные ожидания.
Тут давайте немного пофантазируем. Мы обсудили с вами тему архитектурных шаблонов. Каждый шаблон решает определенную задачу. В совокупности шаблоны помогают построить систему, в которой основные функции будут реализованы в соответствии с лучшими практиками отрасли. Шаг за шагом отрасль эволюционировала и предлагала все более и более сложные решения проблем, с которыми каждый аналитик, разработчик, архитектор сталкиваются при выполнении своих функциональных обязанностей. Отрасль эволюционировала, и, чтобы она продолжала это движение, нам надо учиться придумывать и применять все более и более новые практики, которые будут делать нашу с вами профессиональную жизнь более сложной и интересной. В этом и заключается работа с требованиями – работа над стройным зданием архитектуры информационных систем будущего. В ней будет много вызовов, с которыми мы справимся, потому что именно мы с вами двигаем эволюцию этой архитектуры вперед. Теперь, чтобы логически завершить тему высоконагруженных и многопользовательских приложений, нам осталось рассмотреть три очень важных аспекта.
Первый аспект – транзакции, представляющие собой завершенные бизнес-операции, которые состоят из нескольких действий. В совокупности эти действия, обернутые в транзакцию, приносят ценность для пользователя. Как вы понимаете, одна транзакция может быть реализована путем взаимодействия нескольких микросервисов или единым сервисом. Основная задача транзакции – обеспечить согласованность данных и действий в рамках процесса, выполняемого в информационной системе. Транзакция позволяет зафиксировать и согласованно изменить бизнес-данные. Но у транзакции есть ряд недостатков, которые логически следуют из ее свойств: чем надежнее транзакция, тем дольше она выполняется, чем быстрее транзакция – тем она менее надежна. В работе с транзакциями нужно находить оптимальное сочетание скорости и надежности, чтобы обеспечить формирование нужного результата.
Теперь поговорим о свойствах, которыми должна обладать каждая транзакция. ACID (акроним из слов «атомарность», «согласованность», «изолированность» и «надежность») – это набор требований, которые обеспечивают сохранность данных, используемых во время транзакции. Атомарность гарантирует, что каждая транзакция будет выполнена полностью или не будет выполнена совсем. Промежуточные состояния не допускаются. Теперь о согласованности. Транзакция, достигающая своего нормального завершения и тем самым фиксирующая свои результаты, сохраняет согласованность базы данных. Другими словами, каждая успешная транзакция по определению фиксирует только допустимые результаты. Далее – изолированность. Во время выполнения транзакции параллельные транзакции не должны оказывать влияния на ее результат. И надежность – если пользователь получил подтверждение от системы, что транзакция выполнена, он может быть уверен, что сделанные им изменения не будут отменены из-за какого-либо сбоя.
Ну и последний аспект на сегодня – основной связующий аспект для построения высоконагруженных и многопользовательских систем. Вернее, даже не аспект, а теорема. С точки зрения теоремы CAP, распределенные системы в зависимости от пары практически поддерживаемых свойств из трех возможных распадаются на три класса – CA, CP, AP. То есть любая распределенная система может поддержать только два из трех принципов. В системе класса CA во всех узлах данные согласованы и обеспечена доступность, при этом система жертвует устойчивостью к распаду на секции. Такие системы возможны на основе технологического программного обеспечения, поддерживающего транзакционность в смысле ACID. Система класса CP в каждый момент обеспечивает целостный результат и способна функционировать в условиях распада, но достигает этого в ущерб доступности: может не выдавать отклик на запрос. Устойчивость к распаду на секции требует обеспечения дублирования изменений во всех узлах системы, в связи с чем отмечается практическая целесообразность использования в таких системах распределенных пессимистических блокировок для сохранения целостности. В системе класса AP не гарантируется целостность, но при этом выполнены условия доступности и устойчивости к распаду на секции. Хотя системы такого рода стали известны задолго до формулировки принципа CAP, рост популярности решений с этим набором свойств связан именно с распространением теоремы CAP.
Подведем итоги пятого модуля. Высоконагруженные многопоточные пользовательские приложения имеют много аспектов, которые необходимо учитывать при проектировании. Информационные системы с заданными характеристиками функционирования, у которых много пользователей, эволюционно развиваются, и на каждом витке развития уточняются неполные данные, дополняются аспекты, критичные для сопровождения и развития систем. Текущий виток развития накопил и осмыслил много данных, которые не всегда согласованы между собой, но при этом важны для того, чтобы спроектировать и запустить в эксплуатацию востребованный цифровой продукт. При проектировании мы должны думать о согласованности критичных бизнес-данных и о наших пользователях, их удобстве и выполнении необходимых бизнес-операций. До встречи на последнем, шестом модуле!
1. Проектирование высоконагруженных систем — это поиск компромисса между скоростью, надежностью и согласованностью данных.
2. Архитектурная мысль движется в сторону большей декомпозиции (микросервисы), что позволяет точечно управлять нагрузкой и упрощает разработку, но усложняет эксплуатацию.
3. Не существует единственного правильного выбора между SQL и NoSQL; решение зависит от специфики данных и бизнес-задач конкретного приложения.
4. Теоремы ACID и CAP задают фундаментальные рамки и ограничения, которые нельзя игнорировать при создании распределенных и транзакционных систем.
1. Чем высоконагруженное приложение отличается от обычного с точки зрения проектирования? На какие три главных аспекта нужно обратить внимание?
2. В чем принципиальная разница между SQL и NoSQL базами данных с точки зрения масштабирования и структуры данных?
3. Какие недостатки монолитной архитектуры призвана была решить сервис-ориентированная архитектура (SOA)?
4. В чем ключевое различие между сервисом (в SOA) и микросервисом? Какие новые проблемы создает микросервисный подход?
5. Что означает акроним ACID? Кратко опишите каждое из свойств транзакции.
6. Сформулируйте теорему CAP (Брюера). Какие классы систем (по сочетанию свойств) из нее вытекают?