Управление блокировками распределенной системы с использованием хранилища Azure

Распределенные системы существуют уже достаточно давно, и при их проектировании уже установлены хорошо известные шаблоны. Сегодня мы обсудим один из популярных шаблонов: “блокировки.”

Проще говоря, блокировки — это способ, с помощью которого процессы получают эксклюзивный доступ к ресурсу для выполнения определенного действия. Например, представьте, что в учетной записи хранения есть множество Blob-ов, и вам нужно, чтобы один экземпляр вашего сервиса обрабатывал каждый blob, чтобы избежать дублирующей обработки. Способ сделать это — захватить блокировку на blob, завершить обработку и освободить ее. Однако возникает потенциальная проблема, если процесс завершает работу до освобождения блокировки, либо потому, что процесс завершился, либо из-за сетевого разрыва, оставляя ресурс заблокированным на неопределенный срок. Это может привести к взаимным блокировкам и конкуренции за ресурсы.

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

Таймаут блокировки

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

Блокировка аренды

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

Плюсы и минусы блокировок на основе таймаута и аренды

Pros Cons
Блокировка на основе таймаута Просто реализовать Требует тщательного выбора таймаута
Предотвращает постоянные блокировки Если обработка не завершена, то нет способа продлить аренду
Блокировка на основе аренды Снижает риск преждевременного
истечения блокировки
Требует механизма для продления аренды

Процесс может продолжать запрашивать аренду, пока работа не завершена.

Обе вышеуказанные стратегии являются способом быстрого восстановления после сбоев процессов или сетевых разделений в распределенных системах.

Стратегия блокировки аренды с Azure Storage

Давайте посмотрим, как использовать стратегию блокировки аренды с Azure Storage. Это также охватывает стратегию блокировки по таймауту.

Шаг 1: Импортировать Nuget хранилища блоков

“12.23.0” – последняя версия на момент написания этой статьи. Последние версии можно найти на хранилище блоков Azure.

XML

 

Шаг 2: Получение аренды

Ниже приведен код для получения аренды.

C#

 

  1. Сначала мы создаем клиент контейнера блобов и получаем клиент блоба для конкретного блоба, на котором мы хотим получить аренду.
  2. Во-вторых, метод “Acquire Async” пытается получить аренду на определенный срок. Если получение прошло успешно, возвращается идентификатор аренды, в противном случае выбрасывается 409 (код состояния для конфликта).
  3. Метод “Acquire Async” является ключевым здесь. Остальной код можно настроить/изменить в соответствии с вашими потребностями.

Шаг 3: Обновить аренду

  • “Renew Async” – метод в SDK хранилища .NET, используемый для обновления аренды.
  • Если обновление не удалось, выбрасывается исключение вместе с причиной сбоя.
C#

 

Шаг 4: Организовать методы получения и обновления аренды

  • Изначально мы вызываем “Try Acquire Lease Async” для получения идентификатора аренды из Шага 2. Как только это происходит успешно, запускается фоновая задача, которая вызывает “Renew Lease Async” из Шага 3 каждые X секунд. Просто убедитесь, что между временем ожидания и вызовом метода обновления аренды достаточно времени.
C#

 

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

Шаг 5: Отмена обновления аренды

  • Когда вызывается метод “Cancel Async”, “IsCancellationRequested” в Шаге 4 становится true, из-за чего мы больше не входим в цикл while и не запрашиваем обновление аренды.
C#

 

Шаг 6: Освобождение аренды

Наконец, чтобы освободить аренду, просто вызовите метод “Release Async”.

C#

 

Заключение

Блокировки являются одними из основных шаблонов в распределенных системах для получения эксклюзивного доступа к ресурсам. Необходимо помнить о возможных проблемах при работе с ними для беспроблемного выполнения операций. Используя Azure Storage, мы можем реализовать эффективные механизмы блокировки, которые могут предотвратить бесконечное блокирование и, в то же время, обеспечить упругость в том, как управляются блокировки.

Source:
https://dzone.com/articles/locks-in-distributed-systems-timeout-lease-based