Pull to refresh

Comments 46

В линуксе давным-давно идёт срач на тему персистентных страниц при записи. Другими словами, «можно ли писать в грязные страницы». Срач типовой для подобной ситуации — одних ужасает, что данные могут меняться в середине записи (и записываться непонятно как), других ужасает то, как дорого и медленно выглядит решение проблемы.

[Решение: полный отказ от кешей на запись любого уровня и переход на ssd].
Я бы предпочёл, чтобы в DRBD был параметр «copy before write», который включен по-умолчанию и можно было бы его выключить «если знаешь, что делаешь». Кстати, Lars упонянул, что подобная ситуцаия может встериться и с програмным RAID. Интересно копирует ли mdraid буфер перед записью?
Именно вокруг этого параметра в LKML срач и стоит.

Нет, никто не копирует, потому что это очень дорого. Производительность проседает кратно. А дальше — см написанное выше — два лагеря, одни ужасаются при виде коррапченных данных, другие при виде провисших графиков производительности.

Насколько я знаю, в линуксах этот параметр уже можно менять (и он будет глобальным для всех блочных устройств и файловых систем). Ща попробую погуглить.

UPD: Называется stable pages,
lwn.net/Articles/442355/
Да, про stable pages как раз Lars и говорил, только про параметр я ничего не нашёл.
Ага, я посмотрел, оно так и не смержено.

Вот тредик с вялым отбрыкиванием от патча:
thread.gmane.org/gmane.comp.file-systems.ext4/25009

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

Ну, записали мы локально. Собираемся отправить на пира. Обнаружили изменения. Наши действия? Записать локально и послать на пира? За это время оно опять поменяется. И опять, и опять. Условно говоря, сетевая latency 100µs, а клиент делает 20kIOPS.
Так и наплевать на латенси, клиенту приедет подтверждение записи сразу после попадения в кеш.
Ну и сколько у вас таких страниц, которые успевают перезаписываться? Я думаю что не очень много.
Подтверждение сразу после попадания в кеш == write back. Достаточно одной странно записанной страницы, чтобы развалить LVM огромного размера. Или удалённую файловую систему с iscsi.
Так сколько будет таких страниц? Если у вас будет ждать полной записи на все ноды 1% запросов, то на общую производительность это скажется совсем не сильно.
Вообще мне казалось что блокировочки тут должен делать элеватор. Но подозреваю что таки нет.
Если от этого 1% зависят остальные (что бывает при обновлении метаданных), то этот 1% будет тормозить всё остальное. Причём банальное cp будет идти с той же скоростью, а вот OLDP (то есть осмысленная структурированная нагрузка) будет простаивать в дедлоках.

Собственно, если в DRBD и нижележащих штуках полностью выключить всё и сделать stable pages, то мы получим кровоточащую производительность — потому что само drbd тоже активно пишет метаданные и мы получим такую простую математику (C-mode):
операция записи:
latency до drbd + латенси локального drbd + латенси нижележащего устройства с метаданными (IO1) + латенси нижележащего устройства с данными (IO2) + латенси сети, плюс латенси удалённого drbd плюс латенси метаданных удалённого drbd (IO3) + латенси данных удалённого drbd плюс латенси ответа.

Самыми большими обычно являются latency сети и IO, то есть мы получаем IO_latency*4 + network_latency. Если у нас 0.1ms сеть, 0.1ms SSD, то мы получим минимум 0.5ms на запись. Что означает при одном потоке на запись максимум 2к IOPS. При том, что в параллельном IO на тех же SSD мы имеем 50к IOPS.
Так у вас выбор или все писать до конца, или только то что менялось. Второе всяко быстрее.
А кто хочет надежно за иопсами не гонится.
Таки да — для больших iops более надёжной получается асинхронная репликация.
А для неё этой проблемы просто нет.
Кто-нибудь обладает информацией о поддержке barriers на NTFS в Windows? Кэш на запись можно включить/отключить в настройках диска, а вот про barriers я ничего не нашёл.
Барьеры — это абстракция линукса. В виндах её нет, и даже если бы она была, это была бы абстрация виндов. То есть на уровне устройства никаких барьеров нет, а есть writeall, etc — зависит от конкретной шины. Некоторые устройства (консьюмерские ssd) могут вообще не поддерживать синхронную запись.
Как бы оно не называлось, но что-то подобное должно существовать, иначе нельзя было бы гарантировать целостность при использовании кэша на запись.
При чём тут вообще кеш на запись? Кеш на запись на уровне хоста означает, что при потере питания или краше ядра данные превращаются в тыкву.

stable pages, точнее, их отсутствие, говорит про ситуацию, когда в страницу пишется несколько комплектов данных не дожидаясь, что сосед закончит. Частным случаем этого является write-back, т.е. drbd говорит «угу», не закончив операцию, и огребает следующую запись в тот же блок. Другим случаем является write-through при конкурентной записи.

Проблема именно в том, что страница, отправленная на запись в блочное устройство, может меняться. Не важно чем, важно, что это чистой воды race condition. При этом патч предполагает блокировку всех, кто пытается конкурентно писать — а это может сильно уронить производительность. Потому патч не принят — ведь файловых систем это не касается.
Я сейчас вообще не про DRBD. Без barriers мы можем, столкнуться с ситуацией, когда в результате reordering (так может делать железка или планировщик) и отключения питания мы получим не просто потерю коммита, а порушенную файловую систему.
Насколько я понимаю, все файловые системы в курсе про reordering. Вообще, сам reordering никаким образом sync-записи не мешает, потому что если мы отправили запрос на запись, следующей записи не будет, пока не будет успеха от этой.
Вот тут об этом хорошо написано: lwn.net/Articles/283161/
Как с этим обстоят дела в Windows найти не могу.
А почему DRBD не может получить уведомление о событии записи (п. 2.5)?
Как я понимаю, механизма нет )

Судя по lwn.net/Articles/442355/ ситуация такая:
1) Используется кэш на запись (как у автора)
2) Приложение посылает запрос на запись
3) Данные пишутся в страницу кэша
4) Страница помечается как грязная
5) В очередь планировщика IO ставится запрос на сброс грязной страницы на диск
НО несмотря на то, что страница помечена как грязная, писать в нее все еще можно. С этого момента начинается русская рулетка. Худший сценарий выглядит так:
6) Очередь планировщика IO доходит до первого запроса и начинается его исполнение. Это ОЧЕНЬ медленная операция по сравнению со всем остальным. При этом данные уходят на уровень DRBD в виде указателя на страницу кэша. Грязная страница в этот момент не блокируется на запись (патч как раз это и должен делать).
7) DRBD пишет данные на первый том
8) Приложение посылает второй запрос на запись в то же место (как пример, менеджер виртуальной памяти пишет в своп)
9) Этот запрос попадает в кеш, в ту же страницу, что и первый, и перезаписывает данные. При этом в очередь планировщика IO уходит второй запрос на сброс страницы.
10) DRBD начинает писать данные на второй том, у него указатель на уже измененные данные. На второй том именно они и уходят.
11) Получаем рассинхронизацию

Я, правда, не совсем понимаю вот что: второй запрос на IO, который появился при изменении данных в кэше, должен исправить ситуацию — DRBD перезапишет парные блоки еще раз и все будет ок? Интересно, почему этого не происходит?
К тому же, в lwn.net/Articles/442355/ проблему обсуждают не в контексте DRBD, а в том, что некоторые контроллеры вычисляют на этапе 6 контрольную сумму, потом пишут данные на диск на этапе 10, вычисляют сумму повторно и ругаются на «checksum error».

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

QEMU — тоже молодец: параметр cache=none отключает не только кеш на уровне VM, но и контроль за операциями IO вообще, так что запрос просто уходит в память гипервизора, VM сообщается, что запрос выполнен, а успел ли гипервизор его записать — не проверяется. При этом, правда, VM сообщается, что устройство, на которое она пишет, работает в режиме writeback, так что если VM успевает вовремя слать sync (как это делает Linux с ext4), то все хорошо )
К тому же, в lwn.net/Articles/442355/ проблему обсуждают не в контексте DRBD, а в том, что некоторые контроллеры вычисляют на этапе 6 контрольную сумму, потом пишут данные на диск на этапе 10, вычисляют сумму повторно и ругаются на «checksum error».

DRBD делает точно так же при включенном data-integrity-alg. Причём, если режим работы primary/secondary, то secondary автоматически переподключается (disconnect -> connect), а в случае с dual primary тут же получаем split brain.

QEMU — тоже молодец: параметр cache=none отключает не только кеш на уровне VM, но и контроль за операциями IO вообще, так что запрос просто уходит в память гипервизора

Только не гипервизора, а блочного устройства. Кэш хоста, в этом случае, как раз не используется.
К тому же, в lwn.net/Articles/442355/ проблему обсуждают не в контексте DRBD, а в том, что некоторые контроллеры вычисляют на этапе 6 контрольную сумму, потом пишут данные на диск на этапе 10, вычисляют сумму повторно и ругаются на «checksum error».

Я это к тому, что на lwm.net проблемы с DRBD не признают и считают дефект косметическим — ну, поругался контроллер на checksum, ну, записал данные еще раз — все же ок?
Как-то так все печально, что даже не верится.
Интересно как все это устроено в виндах.
Как-то так все печально, что даже не верится.
Интересно как все это устроено в виндах.

Так же, просто в виндах нет механизмов аналогичных DRBD и, поэтому, нет проблем.
Хотя может в случае софтрейда в винде что-то проявляется.

Я, например, много лет юзаю md-raid в линуксе и таких проблем не вижу — проверки рейд проходит регулярно.
Тут даже кеш не важен — если у нас есть что-то типа iscsi поверх lvm, поверх drbd, то второй запрос записи в ту же область мы можем словить параллельно первому. То есть первый запрос мы не выполнили, а уже пришёл второй.

Особенно актуально на всяких недокластерных файловых системах.
вставлю свои 5 копеек…
аппаратные RAID контроллеры (точнее их драйвера) достаточно честно относятся к barrier, и если оно включено, то драйвер контролера при получении запроса на запись с barrier, скомандует контроллеру честно положить данные на диск, минуя write cache контроллера. Таким образом, мы имеем: 1) быстрый, но битый DRBD с выключенным barrier или 2) целый DRBD, неиспользуемый write-cache контроллера + низкую производительность на запись с включенным barrier

короче говоря, или мы вообще без кеша на запись живем или drbd ломается(((
Я чуть выше описал сценарий, при котором даже при отключенном кеше конкурентная запись побъёт данные.
Друзья, наткнулся на статью, и испугался…

Подскажите, чем опасна связка:

/dev/sd[a,b] (SSD) -> md -> lvm -> drbd0 -> drbd10 -> ext4 -> qcow2 -> KVM

Хочу иметь не дорогое решение для виртуализации c синхронизацией на три узла. Если будет использован режим: writethrough (в KVM), и drbd только в режиме: master/slave.

Можно спать спокойно?

Можно-ли linux хосты держать в других резимах? — Если побьётся swap, то это же не страшно. Всё одно, на другом хосте оно поднимится через reboot.
Очень сложно. Если ошибка произойдёт на любом из уровней, восстанавливать будет сложно.
Согласен. Не буду так сильно рисковать. Сделаю чуть попроще. Но всё же, очень хочу drbd. Вы от него не отказались в итоге?
Нет, не отказался. Сейчас полёт нормальный. Работает на 4х кластерах с различной конфигурацией, т.е. на 8ми хостах в целом.
Если я Вам опишу свою планируемую схему, не сочтёте за труд, вникнуть, и подсказать мне, где я могу быть не правым?
Пишите, попробуем.
Написано несколько официальным текстом, чтобы можно было технически обосновать, ну и понять, чего же я вообще хочу. — Без этого никуда. Это некий драфт ТЗ. Посмотрите пожалуйста, и прокомментируйте текст (там прям можно комментировать): docs.google.com/document/d/1SXHOvFkQExFErPuQEVPrGHFsoUfEgcV0LV7KnA0VzKY/edit?usp=sharing
Напишите мне в гугл чат. Обсудим.
Написал вроде… Я в goole не особо понимаю чего они там натворили, но вроде как в hangouts теперь только можно.
Простите, что вмешиваюсь, но мне кажется, что использовать DRBD для бэкапов — это плохая идея. Например, есть у нас СУБД, у нее кэш на 10G в RAM и она использует его по своему усмотрению. В момент репликации кэш, естественно, не сбрасывается, и в результате на slave получается тыква вместо бэкапа. Вообще, в Windows VSS writers не зря придумали, как и в Linux перед созданием LVM-снэпшота для бэкапа MySQL команду FLUSH TABLES WITH READ LOCK посылают не зря. Если вам нужны целостные бекапы — применяйте инструментарий именно для бэкапов.
Для гарантированно целостных бекапов: vm выключаются, и с них снимается qcow2 снепшот (т.е. состояние в случае чего должно быть консистентным). В случае поднятия на втором узле машин при резком сбое основного узла — это будет как power cut для вирт. машин (если файлы образов не побьются при этом конечно). — Так или иначе, все БД рассчитаны на такой случай (наверно). Машины, где используется БД — можно использовать в режиме cache writeback.

Я сам в общем не могу сказать, что я уверен, в том, чего сейчас несу. Но как-то так я это себе предстваляю.

В противном случае, выходит, что drbd вообще не нужен как и любая сетевая распределённая файловая система…
Использую lvm поверх него drbd, libvirt cache=writethrough. Виртуалки на raw drbd. Все равно ошибки проскакивают(!!!), несмотря на то, что обновлял весь софт (gentoo). спасает конечно проверка checksum, но приятного от этого мало. Где было возможно ушел на Ceph, чего и Вам желаю.
Подскажите несколько вопросов:
1. Как долго в среднем делается checksum?
2. Можно ли checksum ставить на паузу?
3. Как там с приоритетом io при проверке checksum?

Ceph — на две машины мне кажется это слишком…
Паузу, на соклько я помню, сделать нельзя. Длительность процесса verify зависит от размера DRBD ресурса.
Посмотрите вот это раздел pve.proxmox.com/wiki/DRBD#Integrity_checking
Sign up to leave a comment.

Articles