Итак, в качестве своего первого сообщения на своем же блоге хотел бы немного рассказать об устранении узких мест в SOA-приложениях при помощи такого великолепного средства для относительно простого масштабирования web-приложений, как распределенное кеширование.
В свое время SOA архитектура вызвала своего рода взрыв в Web-разработке. Этот тип архитектуры стал стандартным путем для разработки чрезвычайно масштабируемых приложений. SOA позволяет вам распределить приложения между несколькими местоположениями, несколькими подразделениями внутри одной организации и т.д. и т.п. Кроме того эта архитектура позволяет заново использовать один и тот же код и что более важно обеспечивать взаимодействие между различными бизнесс-процессами.
Обычно мы с вами разворачиваем SOA приложение в виде Web-фермы. Целью таких действий естественно является попытка заставить обрабатывать большее количество траффика чем вы можете сгенерировать. Отсюда возникает вполне резонный вопрос: какие варианты вы должны иметь для повышения производительности и масштабируемости вашего SOA приложения??
Кроме того, что SOA сама по себе прекрасно масштабируется Вы должны учесть много аспектов для достижения хорошей масштабируемости. Некоторые их них касаются того как Вы пишете код, но большинство все-таки относятся к области хранения хранения и доступа к данным.
SOA приложение состоит из 2-х компонентов: сервисы и клиентские приложения. В качестве клиентских приложений могут выступать Web-приложения, другие сервисы или сторонние приложения, базирующиеся на SOA сервисах.
В идеале сервисы должны как можно более независимыми. Независимость в данном случае означает, что они не разделяют какие-либо общие данные среди множества вызовов, позволяя вам запускать такие сервисы на множестве компьютеров. SOA архитектура может быть спокойно разнесена между несколькими серверами либо несколькими датацентрами. Но, есть одно но, как и любое другое приложение SOA приложение имеет дело с данными и это может быть проблемой. Как раз доступ к данным может быть узким местом. Бутылочные горышки обычно вовлекают в себя данные приложения, хранящиеся обычно в виде реляционной структуры. Если SOA приложение также использует сессионные данные - это также может быть потенциальной проблемой.
Базирование одних сервисов на других также является источником низкой масштабируемости и производительности. Скажем, Ваш сервис обращается к одному сервису, а тот в свою очередь обращается к другому. Эти сервисы могут быть в одной интранет сети либо распределены по всему интернету. В этом случае Вы не можете эффективно проводить масштабирование вашего приложения, этот вариант бутылочного горлышка представлен на изображении ниже:
Есть несколько методик для повышения производительности вашего SOA приложения.
Одна из них это заставить ваше приложение использовать "редкие" обращения к Web-методам. Просто напросто уменьшите частоту обращений вашего приложения к вашим Web-сервисам. Это неплохой вариант, если ваше приложение и ваши сервисы работают не на одном компьютере или не в рамках одного датацентра. Чем реже вы обращаетесь к своему сервису тем выше производительность.
Другой выход - использовать асинхронные вызовы web-методов поддерживаемые платформой .NET. Это позволит вашему приложению заниматься более приоритетными работами в то время пока обрабатывается web-вызов.
Стоимость сериализации также немаловажный фактор. Отсюда правило: не сериализируйте ненужные данные. Вы должны отправлять только необходимые данные, позволяя тем самым контролировать тип применяемой сериализации.
Для SOA приложений, разработанных на базе Windows Communication Foundation для обмена сообщениями можно воспользоваться протоколами HTTP, TCP и именованными каналами.
Если ваши клиент и сервис разработаны при помощи WCF и будут работать на одной машине, то именованные каналы естественно окажутся наиболее подходящим выбором, так как используют общую память.
TCP великолепный вариант если ваши клиент и сервис разработаны на WCF но работают на разных машинах в пределах одной интранет сети. TCP быстрее чем HTTP, но TCP оставляет открытым соединение на протяжение нескольких вызовов, поэтому вы не сможете перенаправить WCF вызов на другой сервер. При реализации NetTcpBinding, использующий пулы соединений, вы можете сбрасывать соединения довольно таки часто с целью перенаправления вызовов на другой сервер, тем самым эмулируя балансировку нагрузки :).
Если же ваши клиент и сервисы не базируются на WCF или же они хостятся в разных местах, то HTTP это Ваш лучший выбор. Конечно же HTTP не такой быстрый как TCP, но он предлагает прекрасную масштабируемость за счет балансировки нагрузки.
Применение кеширования может реально повысить производительность SOA приложения. Когда Вы обращаетесь к какому-либо методу сервиса, Вы можете закешировать результат. Поэтому последующие вызовы будут получать уже кешированный результат.
Кеширование результата на клиентской стороне позволит вам уменьшить количество обращений к сервису. Это уменьшит давление на сервисный уровень и улучшит масштабируемость. Конечно в этом случае необходимо дополнительно разрабатывать политику по удалению устаревших элементов из кеша.
Наиболее оптимального повышения производительности можно достичь, используя распределенное кеширование на сервисном уровне. Узкие места не всегда можно убрать при помощи всех вышеописанных методик, так как большинство из них сконцентрированы на уровне хранения и доступа к данным. В большинстве сценариев сервисы "живут" в нагрузочно-сбалансированной среде, тем самым позволяя проводить собственное масштабирование с большим успехом, к сожалению масштабировать хранилище данных намного сложнее.
Вы можете масштабировать сервисный уровень путем добавления большего количества серверов в кластер, тем самым увеличивая вычислительную способность. Но все эти SOA транзакции будут иметь дело с одним и тем же хранилищем данных. Тем самым хранение и доступ к данным станет очень серьезным узким местом системы.
Уровень хранения данных может быть улучшен на нескольких уровнях. SOA сервисы имеют дело с 2-мя типами данных. Одни - это сессионные данные, другие данные приложения, находящиеся в базе данных (см. изображение ниже). И те и другие приводят к значительному падению производительности.
Главный недостаток провайдеров хранения сессий в том, что он не предназначен для работы в нагрузочно-сбалансированной среде. Намного более удачный подход заключается в разрешении Asp.NET compatibility mode. Это позволит Вам выбрать OutProc, StateServer, SqlServer или распределенный кеш для хранения сессионных данных.
StateServer и SqlServer мягко говоря не дают оптимального результата. Распределенный кеш является значительно более лучшим вариантом, так как он позволяет реплицировать данные между несколькими участниками кластерами повышая тем самым надежность.
Итак, мы с вами добрались до наиболее серьезного узкого места - это проблема доступа и хранения данных приложения. И опять же для разрешения этой проблемы прибегнем к помощи распределенного кеша. Распределенный кеш используется для кеширования подмножества данных, которые в данный момент необходимы сервису в течении определенного промежутка времени. Кроме того масштабируемость самих сервисов может повышаться косвенно путем повышения масштабируемости распределеного кеша (за счет добавления дополнительных аппаратных ресурсов в кластер). Если вы будете использовать распределенный кеш как прослойку между сервисным уровнем и базой данных, то резко повысите мастабируемость и производительность.
Простейшая логика: перед там как идти в бд за очередной порцией данных, проверьте их наличие в кеше. Если вы получили промах кеша, необходимо взять данные из базы, положить в кеш и отдать их клиенту.
Политика устаревания определяет как долго данные должны оставаться в кеше прежде чем они будут удалены оттуда. Вы можете применить один из двух методов: абсолютное устаревание и скользящее.
Так как ваши данные, предварительно сохраненные в кеше, могут быть изменены в базе данных другим пользователем, необходимо каким-то образом синхронизировать данные в кеше с данными в базе. Если у вас есть возможность приблизительно определить как долго ваши данные будут оставаться актуальными, то можно задать для них абсолютное устаревания. Например, Вы можете задать правило: "удалить этот элемент из кеша через 10 минут, начиная с текущего момента". В случае же скользящего устаревания данные остаются актуальными пока их кто-то использует. Например, вы можете задать правило: "удалить этот элемент из кеша если к нему никто не обращался в течении 10 минут".
Enterprise Service Bus (ESB) это инфраструктура для Web сервисов, которая опосредует коммуникацию между компонентами. ESB это удобный и мощный способ для асинхронного разделения данных между несколькими приложениями. Однако, ESB не предназначена для использования между организациями. Обычно SOA еще на уровне проектирования разбивается на несколько составных частей, при чем эти части должны разделять данные между собой, в таком случае ESB идеальный кандидат для внедрения :).
Существует множество вариантов построения ESB. На рисунке ниже представлен вариант с использованием распределенного кеша. Множество слабо связанных приложений или сервисных компонентов могут использовать ее для расшаривания данных со своими соседями по шине.
Распределенный кеш по своему устройству базируется на компьютерном кластере. Это повышает его масштабируемость. В дополнение хороший распределенный кеш реплицирует данные для повышения надежности. Кроме того хороший распределенный кеш предлагает интеллектуальный механизм по распространению событий.
Существует 2 вида событий, которые должен поддерживать распределенный кеш, чтобы быть пригодным для ESB. В первую очередь любое клиентское приложение должно иметь возможность закреплять свой интерес к какому либо элементу таким образом, что изменение или удаление этого элемента повлечет за собой немедленное оповещение подключенного приложения. Во вторых, кеш должен позволять приложениям генерировать в ESB кастомные события таким образом, что все подключенные к шине и заинтересованные в этом событии приложения были немедленно оповещены о нем, в независимости где они находятся (речь идет о области действия интранет сети).
При помощи ESB, большинство операций по обмену данными могут быть значительно улучшены. Кроме того задача реализации асинхронного разделения данных на базе обычного WCF сервиса является нетривиальной задачей. Но ESB делает этот процесс значительно более простым. Вы имеете возможность создать даже такие ситуации, когда ESB сама отправляет данные клиентами, которые предварительно проявили интерес к ним.
Топология кеша - термин, используемый для определения того как данные хранятся в распределенном кеше. Существует несколько таких топологий, я раскрою 3 основных: секционированный кеш, секционированно-реплицированный кеш и реплицированный кеш.
Первые 2 топологии играют большую роль в сценариях масштабируемости. В обоих случаях кеш разбивается на несколько секций, после чего каждая секция сохраняется на отдельном сервере из кластера. Секционированно-реплицированный кеш дополнительно имеет реплику каждой секции на другом сервере из кластера. Эти 2 топологии наиболее подходят для транзакционных данных (где частота записи данных практически совпадает с частотой их чтения) так как путем добавления дополнительных серверов в кластер вы не только повышаете количество вмещаемых транзакций, вы также увеличиваете дисковое пространство кеша, так как все секции вместе взятые формируют единое представление кеша.
Согласно 3-й топологии каждый кеш дублируется на каждом сервере кластера. Это значит такая топология предлагает высокую доступность данных и очень хороша для очень интенсивных операций чтения. Она практически не подходит для систем с интенсивным обновлением данных, потому что обновления выполняются синхронно и не так быстро по сравнению с другими топологиями.
Как показано на рисунке ниже секционно-реплицированный кеш идеальный вариант для масштабируемости и высокой доступности.
Высокая доступность может быть улучшена за счет так называемого динамической кластеризации, что означает возможность добавления или удаления дополнительных серверов в кластер в рантайме без остановки кеша или клиентских приложений.
Как видите, крайне тяжело эффективно увеличивать производительность SOA приложение когда данные находятся в хранилище недостаточно масштабируемом. Это тот случай когда очень помогает распределенное кеширование. Надеюсь техники, описанные в этой статье, помогут вывести Ваши SOA приложения на новый уровень масштабируемости.
В свое время SOA архитектура вызвала своего рода взрыв в Web-разработке. Этот тип архитектуры стал стандартным путем для разработки чрезвычайно масштабируемых приложений. SOA позволяет вам распределить приложения между несколькими местоположениями, несколькими подразделениями внутри одной организации и т.д. и т.п. Кроме того эта архитектура позволяет заново использовать один и тот же код и что более важно обеспечивать взаимодействие между различными бизнесс-процессами.
Обычно мы с вами разворачиваем SOA приложение в виде Web-фермы. Целью таких действий естественно является попытка заставить обрабатывать большее количество траффика чем вы можете сгенерировать. Отсюда возникает вполне резонный вопрос: какие варианты вы должны иметь для повышения производительности и масштабируемости вашего SOA приложения??
Кроме того, что SOA сама по себе прекрасно масштабируется Вы должны учесть много аспектов для достижения хорошей масштабируемости. Некоторые их них касаются того как Вы пишете код, но большинство все-таки относятся к области хранения хранения и доступа к данным.
В поисках бутылочных горлышек
SOA приложение состоит из 2-х компонентов: сервисы и клиентские приложения. В качестве клиентских приложений могут выступать Web-приложения, другие сервисы или сторонние приложения, базирующиеся на SOA сервисах.
В идеале сервисы должны как можно более независимыми. Независимость в данном случае означает, что они не разделяют какие-либо общие данные среди множества вызовов, позволяя вам запускать такие сервисы на множестве компьютеров. SOA архитектура может быть спокойно разнесена между несколькими серверами либо несколькими датацентрами. Но, есть одно но, как и любое другое приложение SOA приложение имеет дело с данными и это может быть проблемой. Как раз доступ к данным может быть узким местом. Бутылочные горышки обычно вовлекают в себя данные приложения, хранящиеся обычно в виде реляционной структуры. Если SOA приложение также использует сессионные данные - это также может быть потенциальной проблемой.
Базирование одних сервисов на других также является источником низкой масштабируемости и производительности. Скажем, Ваш сервис обращается к одному сервису, а тот в свою очередь обращается к другому. Эти сервисы могут быть в одной интранет сети либо распределены по всему интернету. В этом случае Вы не можете эффективно проводить масштабирование вашего приложения, этот вариант бутылочного горлышка представлен на изображении ниже:
Пишем код правильно для решения проблем с производительностью
Одна из них это заставить ваше приложение использовать "редкие" обращения к Web-методам. Просто напросто уменьшите частоту обращений вашего приложения к вашим Web-сервисам. Это неплохой вариант, если ваше приложение и ваши сервисы работают не на одном компьютере или не в рамках одного датацентра. Чем реже вы обращаетесь к своему сервису тем выше производительность.
Другой выход - использовать асинхронные вызовы web-методов поддерживаемые платформой .NET. Это позволит вашему приложению заниматься более приоритетными работами в то время пока обрабатывается web-вызов.
Стоимость сериализации также немаловажный фактор. Отсюда правило: не сериализируйте ненужные данные. Вы должны отправлять только необходимые данные, позволяя тем самым контролировать тип применяемой сериализации.
Выбор правильного коммуникационного протокола.
Для SOA приложений, разработанных на базе Windows Communication Foundation для обмена сообщениями можно воспользоваться протоколами HTTP, TCP и именованными каналами.
Если ваши клиент и сервис разработаны при помощи WCF и будут работать на одной машине, то именованные каналы естественно окажутся наиболее подходящим выбором, так как используют общую память.
TCP великолепный вариант если ваши клиент и сервис разработаны на WCF но работают на разных машинах в пределах одной интранет сети. TCP быстрее чем HTTP, но TCP оставляет открытым соединение на протяжение нескольких вызовов, поэтому вы не сможете перенаправить WCF вызов на другой сервер. При реализации NetTcpBinding, использующий пулы соединений, вы можете сбрасывать соединения довольно таки часто с целью перенаправления вызовов на другой сервер, тем самым эмулируя балансировку нагрузки :).
Если же ваши клиент и сервисы не базируются на WCF или же они хостятся в разных местах, то HTTP это Ваш лучший выбор. Конечно же HTTP не такой быстрый как TCP, но он предлагает прекрасную масштабируемость за счет балансировки нагрузки.
Используйте кеширование для повышения клиентской производительности.
Применение кеширования может реально повысить производительность SOA приложения. Когда Вы обращаетесь к какому-либо методу сервиса, Вы можете закешировать результат. Поэтому последующие вызовы будут получать уже кешированный результат.
Кеширование результата на клиентской стороне позволит вам уменьшить количество обращений к сервису. Это уменьшит давление на сервисный уровень и улучшит масштабируемость. Конечно в этом случае необходимо дополнительно разрабатывать политику по удалению устаревших элементов из кеша.
Распределенное кеширование для масштабируемости сервисов.
Наиболее оптимального повышения производительности можно достичь, используя распределенное кеширование на сервисном уровне. Узкие места не всегда можно убрать при помощи всех вышеописанных методик, так как большинство из них сконцентрированы на уровне хранения и доступа к данным. В большинстве сценариев сервисы "живут" в нагрузочно-сбалансированной среде, тем самым позволяя проводить собственное масштабирование с большим успехом, к сожалению масштабировать хранилище данных намного сложнее.
Вы можете масштабировать сервисный уровень путем добавления большего количества серверов в кластер, тем самым увеличивая вычислительную способность. Но все эти SOA транзакции будут иметь дело с одним и тем же хранилищем данных. Тем самым хранение и доступ к данным станет очень серьезным узким местом системы.
Уровень хранения данных может быть улучшен на нескольких уровнях. SOA сервисы имеют дело с 2-мя типами данных. Одни - это сессионные данные, другие данные приложения, находящиеся в базе данных (см. изображение ниже). И те и другие приводят к значительному падению производительности.
Хранение сессионных данных в распределенном кеше.
Главный недостаток провайдеров хранения сессий в том, что он не предназначен для работы в нагрузочно-сбалансированной среде. Намного более удачный подход заключается в разрешении Asp.NET compatibility mode. Это позволит Вам выбрать OutProc, StateServer, SqlServer или распределенный кеш для хранения сессионных данных.
StateServer и SqlServer мягко говоря не дают оптимального результата. Распределенный кеш является значительно более лучшим вариантом, так как он позволяет реплицировать данные между несколькими участниками кластерами повышая тем самым надежность.
Кеширование данных приложений.
Итак, мы с вами добрались до наиболее серьезного узкого места - это проблема доступа и хранения данных приложения. И опять же для разрешения этой проблемы прибегнем к помощи распределенного кеша. Распределенный кеш используется для кеширования подмножества данных, которые в данный момент необходимы сервису в течении определенного промежутка времени. Кроме того масштабируемость самих сервисов может повышаться косвенно путем повышения масштабируемости распределеного кеша (за счет добавления дополнительных аппаратных ресурсов в кластер). Если вы будете использовать распределенный кеш как прослойку между сервисным уровнем и базой данных, то резко повысите мастабируемость и производительность.
Простейшая логика: перед там как идти в бд за очередной порцией данных, проверьте их наличие в кеше. Если вы получили промах кеша, необходимо взять данные из базы, положить в кеш и отдать их клиенту.
Политика устаревания данных в кеше.
Политика устаревания определяет как долго данные должны оставаться в кеше прежде чем они будут удалены оттуда. Вы можете применить один из двух методов: абсолютное устаревание и скользящее.
Так как ваши данные, предварительно сохраненные в кеше, могут быть изменены в базе данных другим пользователем, необходимо каким-то образом синхронизировать данные в кеше с данными в базе. Если у вас есть возможность приблизительно определить как долго ваши данные будут оставаться актуальными, то можно задать для них абсолютное устаревания. Например, Вы можете задать правило: "удалить этот элемент из кеша через 10 минут, начиная с текущего момента". В случае же скользящего устаревания данные остаются актуальными пока их кто-то использует. Например, вы можете задать правило: "удалить этот элемент из кеша если к нему никто не обращался в течении 10 минут".
Enterprise Service Bus как средство повышения масштабируемости SOA.
Enterprise Service Bus (ESB) это инфраструктура для Web сервисов, которая опосредует коммуникацию между компонентами. ESB это удобный и мощный способ для асинхронного разделения данных между несколькими приложениями. Однако, ESB не предназначена для использования между организациями. Обычно SOA еще на уровне проектирования разбивается на несколько составных частей, при чем эти части должны разделять данные между собой, в таком случае ESB идеальный кандидат для внедрения :).
Существует множество вариантов построения ESB. На рисунке ниже представлен вариант с использованием распределенного кеша. Множество слабо связанных приложений или сервисных компонентов могут использовать ее для расшаривания данных со своими соседями по шине.
Распределенный кеш по своему устройству базируется на компьютерном кластере. Это повышает его масштабируемость. В дополнение хороший распределенный кеш реплицирует данные для повышения надежности. Кроме того хороший распределенный кеш предлагает интеллектуальный механизм по распространению событий.
Существует 2 вида событий, которые должен поддерживать распределенный кеш, чтобы быть пригодным для ESB. В первую очередь любое клиентское приложение должно иметь возможность закреплять свой интерес к какому либо элементу таким образом, что изменение или удаление этого элемента повлечет за собой немедленное оповещение подключенного приложения. Во вторых, кеш должен позволять приложениям генерировать в ESB кастомные события таким образом, что все подключенные к шине и заинтересованные в этом событии приложения были немедленно оповещены о нем, в независимости где они находятся (речь идет о области действия интранет сети).
При помощи ESB, большинство операций по обмену данными могут быть значительно улучшены. Кроме того задача реализации асинхронного разделения данных на базе обычного WCF сервиса является нетривиальной задачей. Но ESB делает этот процесс значительно более простым. Вы имеете возможность создать даже такие ситуации, когда ESB сама отправляет данные клиентами, которые предварительно проявили интерес к ним.
Масштабируемость распределеного кеша и высокая доступность.
Топология кеша - термин, используемый для определения того как данные хранятся в распределенном кеше. Существует несколько таких топологий, я раскрою 3 основных: секционированный кеш, секционированно-реплицированный кеш и реплицированный кеш.
Первые 2 топологии играют большую роль в сценариях масштабируемости. В обоих случаях кеш разбивается на несколько секций, после чего каждая секция сохраняется на отдельном сервере из кластера. Секционированно-реплицированный кеш дополнительно имеет реплику каждой секции на другом сервере из кластера. Эти 2 топологии наиболее подходят для транзакционных данных (где частота записи данных практически совпадает с частотой их чтения) так как путем добавления дополнительных серверов в кластер вы не только повышаете количество вмещаемых транзакций, вы также увеличиваете дисковое пространство кеша, так как все секции вместе взятые формируют единое представление кеша.
Согласно 3-й топологии каждый кеш дублируется на каждом сервере кластера. Это значит такая топология предлагает высокую доступность данных и очень хороша для очень интенсивных операций чтения. Она практически не подходит для систем с интенсивным обновлением данных, потому что обновления выполняются синхронно и не так быстро по сравнению с другими топологиями.
Как показано на рисунке ниже секционно-реплицированный кеш идеальный вариант для масштабируемости и высокой доступности.
Высокая доступность может быть улучшена за счет так называемого динамической кластеризации, что означает возможность добавления или удаления дополнительных серверов в кластер в рантайме без остановки кеша или клиентских приложений.
Заключение.
Как видите, крайне тяжело эффективно увеличивать производительность SOA приложение когда данные находятся в хранилище недостаточно масштабируемом. Это тот случай когда очень помогает распределенное кеширование. Надеюсь техники, описанные в этой статье, помогут вывести Ваши SOA приложения на новый уровень масштабируемости.
3 комментария:
Ты автор статьи или это перевод?
Перевод, оригинал здесь: http://goo.gl/UIII
Отправить комментарий