Проблема блокировок в памяти в облачных сервисах

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

Листинг 4.1. Типовой подход Java, реализующий последовательность действий по бронированию номера в отеле, но не подходящий для использования в облачной среде

public void book(Customer customer, Room room, Date[] days) throws BookingException {

synchronized( room ) { // синхронизация блокировок объекта room if( !room.isAvailable(days) ) {

throw new BookingException("Room unavailable.");

}

room.book(customer, days);

}

}

Поскольку код, приведенный в листинге 4.1, использует ключевое слово блокировок Java synchronized, никакие другие потоки (threads) в текущем процессе не могут вносить изменения в объект    1. Если у вас — односерверная среда, то такой код будет без проблем работать под любой нагрузкой, которую может выдер-

1 Я прошу программистов на Java простить мне это чрезмерное упрощение и технологически не совсем корректное описание ключевого слова synchronized. Это объяснение приводится здесь просто для того, чтобы помочь читателям понять в общих чертах все, что происходит в данном контексте, а не для того, чтобы подробно рассказывать им о тонкостях многопоточного программирования на Java.

живать данный сервер. К сожалению, в многосерверном контексте этот код работать не будет.

Проблема с этим примером заключается в блокировке в памяти, которую захватывает приложение. Если у вас два клиента, одновременно пытающихся сделать запрос на бронирование номера к одному и тому же серверу, то Java позволит выполнить синхронизирующую блокировку только одному из них, потому что в каждый конкретный момент времени может быть установлена только одна такая блокировка. За счет этого удается избежать таких ситуаций, когда один и тот же номер может оказаться забронирован сразу двумя клиентами.

С другой стороны, если ваши клиенты делают запросы на бронирование номера через разные серверы приложений (или даже через разные процессы на одном и том же сервере), то синхронизирующие блокировки на каждом из серверов могут быть выполнены параллельно. В результате этого первый клиент, который сделал вызов room.book(), потеряет свою бронь, потому что она будет перезаписана вторым клиентом. Проблему двойного бронирования иллюстрирует рис. 4.2.

Рис. 4.2. Бронь первого клиента, сделавшего запрос на бронирование номера, будет перезаписана вторым клиентом (проблема двойного бронирования)

Если не применять при объяснении проблемы двойного бронирования подхода Java, то суть проблемы заключается в том, что если ваша логика реализации тран-

закций использует блокировку памяти для защиты целостности транзакций, то в многосерверной среде транзакция завершится неудачно. Из-за этого ваше приложение не сможет воспользоваться преимуществами облачной среды для динамического масштабирования приложения.

Одним из способов обойти эту проблему является использование кластерных технологий или системы, позволяющих серверам совместно использовать память. Второй подход к проблеме заключается в том, чтобы рассматривать базу данных как арбитра, управляющего статусом вашей системы.

ЧТО ДЕЛАТЬ,

ЕСЛИ МОЕ ПРИЛОЖЕНИЕ ИСПОЛЬЗУЕТ БЛОКИРОВКИ ПАМЯТИ?

Я уже могу представить себе, что сейчас многие из вас начнут обо мне говорить (особенно те, чьи приложения в широком масштабе используют многопоточность). Но не спешите возмущаться. Если вы тоже оказались в такой ситуации, когда ваши приложения используют блокировки в памяти, и переработка такого приложения не представляется возможной, вы все равно можете мигрировать в облачную инфраструктуру. Правда, вы не сможете масштабировать ваше приложение, распределив его по множеству серверов.

Выход из этого положения заключается в том, чтобы блокировать абсолютно все с помощью разделяемого механизма блокировки — как правило, это движок вашей базы данных (database engine). Еще один вариант состоит в самостоятельном написании распределенной системы управления транзакциями. Правда, зачем это делать, если в вашей базе данных такая система уже имеется?

Источник: Риз Дж., Облачные вычисления: Пер. с англ. — СПб.: БХВ-Петербург, 2011. — 288 с.: ил.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете промотать до конца и оставить ответ. Pinging в настоящее время не допускается.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100