Предыстория


Существует красивое решение для создания надёжного недорогого кластера основанное на DRBD + Proxmox VE. Страница в Wiki проекта Proxmox появилась 11 сентября 2009-го года и создана она была CEO компании Martin-ом Maurer-ом.



С тех самых пор это решение стало очень популярным, и никто не подозревал, что у этого решения есть скрытый подводный камень. В документации про это не пишут, а те, кто сталкивался с последствиями этой проблемы (например, зависание машины при онлайн миграции с одного хоста на другой), списывали всё на «случай». Кто-то грешил на железо, кто-то на Proxmox, а кто-то на драйверы внутри виртуальной машины. Конечно, хотелось бы, чтобы DRBD сам сообщал о своих проблемах, и, как-то подсознательно веришь в то, что он так и делает. Проверяешь /proc/drbd, видишь строку «cs:Connected ro:Primary/Primary ds:UpToDate/UpToDate» и продолжаешь верить что DRBD не причём.

Однажды, внимательно читая документацию к DRBD, я нашёл рекомендацию делать регулярную проверку DRBD на целостность, т.е. на идентичность двух нод между собой. Ну, а почему бы и нет, подумал я, проверка лишней не будет. И тут началась история длиной в целый год.

Оказалось, что каждую неделю в DRBD появлялись новые блоки out-of-sync. Т.е. данные на двух серверах отличались. Но почему?!

Замена железа, обновление версии DRBD, отключение offload и bonding-а к положительному результату не приводили, а новые блоки всё появлялись и появлялись. Анализ того, какие именно блоки оказывались out-of-sync, привёл к следующим результатам:
— часто — swap раздел виртуальной машины с Linux
— редко — Windows с разделом NTFS на виртуальной машине
— никогда — ext4 на виртуальной машине с Linux

Это было «интересно», но ответа на вопрос «почему и как это может быть» не давало. Обо всех своих изысканиях я рассказывал в списке рассылки «DRBD Users» (http://www.gossamer-threads.com/lists/drbd/users/25227) и однажды я получил ответ, которого так долго ждал. Lars Ellenberg, один из основных разработчиков DRBD, рассказал, что именно происходит, и как это проверить.

Как происходит запись в DRBD


Общий случай:
1) DRBD получает запрос от ОС за запись данных из буфера;
2) DRBD записывает данные на локальное блочное устройство;
3) DRBD отправляет данные второй ноде по сети;
4) DRBD получает подтверждение окончания записи от локального блочного устройства;
5) DRBD получает подтверждение окончания записи от второй ноды;
6) DRBD отправляет ОС подтверждение окончания записи.

А теперь представим себе, что данные в буфере неожиданно изменились и мы получим:
1) DRBD получает запрос от ОС за запись данных из буфера;
2) DRBD записывает данные на локальное блочное устройство;
2.5) данные буфера изменились;
3) DRBD отправляет данные второй ноде по сети;
4) DRBD получает подтверждение окончания записи от локального блочного устройства;
5) DRBD получает подтверждение окончания записи от второй ноды;
6) DRBD отправляет ОС подтверждение окончания записи.
И мы тут же получаем out-of-sync.

Как же такое получается? Очень просто. Буфер может использоваться приложением для кэширования на запись (приложение, у нас, это процесс виртуальной машины). В этом случае приложение может обновлять данные в буфере, не дожидаясь подтверждения записи этих данных на физическое устройство или контроллер, а в случае с DRBD это неприемлемо.

Самое неприятное во всем этом то, что для возможности потерять данные не нужно даже отключения питания. Достаточно лишь включить кэш на запись.

Как проверить? Нужно включить в настройках DRBD data-integrity-alg и ждать. Если вы получите что-то вроде «buffer modified by upper layers during write», то это оно и есть. Будьте осторожны, если DRBD работает в режиме dual-primary, то при включенном «data-integrity-alg» вы тут же получите split brain (об этом не написано в документации).

Кэширование записи в QEMU/KVM


По-умолчанию виртуальные машины в Proxmox VE используют для виртуальных дисков режим cache=none. Несмотря на то, что «none» как бы говорит нам «ничего не кэшируем», на самом деле это не совсем так. None, в данном случае, означает не использовать «host cache», но кэш на запись в блочное устройство по-прежнему используется. А отсюда мы получаем проблему с рассинхронизацией блоков в DRBD.



Всего два режима можно считать надёжными при использовании с DRBD: directsync и writethrough. Первый не использует кэширование вообще, т.е. читает всегда напрямую с блочного устройства (это может быть RAID контроллер) и пишет в блочное устройства (это может быть RAID контроллер) обязательно дожидаясь подтверждения записи. Второй режим использует «host cache» для чтения.

Таким образом, система виртуализации может стать катастрофически медленной, если вы не используе��е физический RAID с кэшированием за запись и BBU. А если вы используете RAID с BBU, то виртуальная машина получит подтверждение о записи сразу же после помещения данных в кэш контроллера.

Почему же нет out-of-sync на ext4


Использование режимов cache=directsync и cache=writethrough являются самыми надёжными, т.к., в этом случае, нам не нужно беспокоиться о том, что происходит внутри виртуальной машины. Но это не единственный способ. Это нужно учитывать в тех случаях, когда нам недостаточно производительности RAID или же у нас нет RAID вообще.

Убедиться в том, что данные уже записаны можно не только на уровне процесса виртуальной машины, но и внутри VM. Здесь мы знакомимся с понятием barrier, которое предполагает, что файловая система сама знает, когда её нужно сбросить данные из кэша на физическое устройство и дождаться завершения этой операции. А man mount говорит нам, что «The ext4 filesystem enables write barriers by default». Именно поэтому мы и не увидим никогда out-of-sync на тех областях, где расположена файловая система использующая barriers.

Полезные ссылки:
— Proxmox и DRBD: pve.proxmox.com/wiki/DRBD
— Out of sync: www.gossamer-threads.com/lists/drbd/users/25227
— Ещё про out of sync: forum.proxmox.com/threads/18259-KVM-on-top-of-DRBD-and-out-of-sync-long-term-investigation-results
— Описание параметра cache для kvm/qemu: www.suse.com/documentation/sles11/book_kvm/data/sect1_1_chapter_book_kvm.html
— Ещё про кэш: www.ilsistemista.net/index.php/virtualization/23-kvm-storage-performance-and-cache-settings-on-red-hat-enterprise-linux-62.html?start=2