SAN с двумя контроллерами: multipath, ALUA и тест выдёргиванием питания
На Fibre Channel SAN с двумя контроллерами настроили multipath I/O с политикой round-robin. При эмуляции отказа пути базы данных не прерывались. Вошло в регламент приёмки.
Стандарт ALUA (Asymmetric Logical Unit Access) входит в практику SAN-подключений как механизм, описывающий приоритет путей к LUN на двухконтроллерных хранилищах
С iSCSI мы уже разобрались, что один путь - это недопустимо, и отработали MPIO на Windows. Но там хранилище было с одним контроллером: потеря пути означала потерю коммутатора или кабеля, не самого железа хранилища. Сейчас другой случай: клиент поставил Fibre Channel SAN с двумя контроллерами. Два контроллера - это уже другая история, и задача stать чуть сложнее.
Почему два контроллера меняют картину
На однoконтроллерном хранилище LUN принадлежит единственному контроллеру, и все пути в итоге приходят к нему. При выходе из строя контроллера - хранилище просто недоступно, мультипатинг тут не поможет.
Двухконтроллерное устройство другое: каждый LUN в каждый момент имеет «родной» контроллер (owner) и второй, который тоже умеет обслуживать доступ к этому LUN, но с более высокой латентностью. Это и есть суть ALUA - Asymmetric Logical Unit Access. Стандарт описывает, как хранилище сообщает хосту: «путь A к этому LUN - оптимальный, путь B - нет, но при необходимости работает».
Если multipath-драйвер не понимает ALUA, он может гнать трафик через «неоптимальный» путь постоянно - и тогда каждый I/O идёт через не-родной контроллер, внутри хранилища передаётся на нужный, и только потом обрабатывается. Вроде работает, но производительность заметно ниже, а внутренняя шина хранилища загружена без нужды.
Что за стенд
Клиент взял SAN с двумя контроллерами, четыре FC-порта на хранилище (по два на контроллер), два HBA на сервере, два FC-коммутатора. Схема классическая для серьёзной инсталляции: полная физическая избыточность, никаких общих точек отказа между хостом и дисками.
Хосты - Linux с ядром 2.6, на котором device-mapper-multipath входит в штатный состав дистрибутива. Раньше мы бы ставили сторонний multipath-драйвер от вендора хранилища; сейчас dm-multipath достаточно зрелый, чтобы работать с ALUA через встроенный failover.
Настройка dm-multipath с ALUA
Ключевой момент - выбор политики в /etc/multipath.conf. По умолчанию dm-multipath не знает про ALUA и использует round-robin или failover, не опираясь на информацию о приоритете путей от хранилища.
Для хранилища с ALUA правильная политика - multibus или специфичный для вендора prio_callout, который опрашивает устройство через SCSI-команды и получает приоритет пути. Результат: dm-multipath сам знает, какой путь оптимальный, и направляет туда основной трафик. Резервный путь висит наготове, но не используется без нужды.
Фрагмент конфига, который у нас получился:
defaults {
path_grouping_policy group_by_prio
prio_callout "/sbin/mpath_prio_alua /dev/%n"
failback immediate
rr_weight priorities
no_path_retry fail
}
prio_callout запрашивает у каждого пути его ALUA-приоритет. Пути с одинаковым приоритетом группируются, между ними работает round-robin. При переходе на резервный контроллер - failback immediate, то есть как только оптимальный путь восстановился, трафик возвращается сам, без ручного вмешательства.
Тест на отказ
Проверяли два сценария.
Первый - потеря FC-кабеля. При активной нагрузке на базу данных отсоединили кабель от одного HBA. dm-multipath зафиксировал потерю двух путей (оба порта первого HBA), перераспределил трафик на второй HBA. SQL-сессии не прервались - небольшая пауза в запросах, но транзакции не откатились, приложение не упало.
Второй - принудительное отключение контроллера. Это страшнее: на хранилище через сервисный интерфейс вывели из работы один контроллер. ALUA-приоритеты путей изменились, LUN'ы перешли на второй контроллер как на owner. dm-multipath пересчитал приоритеты через prio_callout и перестроил группы путей. Базы данных - без прерывания, прикладной уровень не заметил ничего.
Время переключения в обоих случаях - несколько секунд. Не мгновенно, но для большинства прикладных задач вполне приемлемо.
Что не работало сразу
Первая попытка с дефолтным конфигом (failover без ALUA) дала неожиданный результат: при одновременной нагрузке с двух хостов на один и тот же LUN производительность была ощутимо ниже расчётной. Причина - трафик шёл через оба контроллера по round-robin, но LUN принадлежит одному. Второй контроллер обрабатывал запросы транзитно через внутреннюю шину хранилища - это и давало просадку.
После переключения на ALUA-политику трафик сосредоточился на оптимальных путях, и картина выровнялась. Вывод простой: round-robin без учёта ALUA на двухконтроллерном хранилище - это не оптимизация, а деградация.
Что вошло в регламент
По итогам - зафиксировали обязательный шаг приёмки для любого хранилища с двумя и более контроллерами:
- Проверка ALUA.
sg_rtpg /dev/sdXпоказывает группы путей и их приоритеты. Если хранилище поддерживает ALUA - в конфиге должен быть prio_callout, а не просто round-robin. - Тест потери пути. Физически отключить кабель при нагрузке, убедиться что dm-multipath переключился и приложение не потеряло сессию.
- Тест потери контроллера. Если архитектура позволяет - вывести контроллер через сервисный интерфейс. Это дороже, но именно это проверяет реальную отказоустойчивость, а не просто переключение между портами.
- Проверка failback. Вернуть оборудование в строй и убедиться, что multipath восстановил оптимальные пути автоматически, без ручного вмешательства.
До этого проекта у нас в чеклисте приёмки хранилища был пункт «проверить доступность LUN». Теперь там четыре пункта выше. Разница существенная - первый пункт закрывался за пять минут, четыре новых требуют полноценного окна обслуживания. Зато клиент, которого мы ведём в рамках сопровождения серверной инфраструктуры, получает хранилище с проверенной отказоустойчивостью, а не просто с красивой схемой на бумаге.
- iSCSI и MPIO: добавляем второй путь и тестируем выдёргиванием кабеля · 21 ноября 2006
- iSCSI и Jumbo Frames: почему MTU 9000 решил половину проблемы с throughput · 22 февраля 2007