LINUX.ORG.RU

Как реализовать барьеры записи?

 , , , ,


0

1

Мне нужно что-то типа барьеров ФС, но для файла. Причём непосредственная запись в файл прямо сейчас не обязательна, даже наоборот, лучше чтоб её не было.

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

Картинка для пояснения:

1 2 3 4 | 5 6 7 | 8 9 10 | 11 12 13 14 15 16 17 | 18 19 20
Здесь числа — блоки данных, пайпы — моменты вызова barrier()
Что мне нужно — это чтобы при сбрасывании кеша не было такого, что 9 записалось до 7, например. Последовательность записи внутри группы не имеет значения, пусть записывает как хочет.

Сейчас использую fsync, но он блокируется, пока не запишет данные, а это жуть как медленно. Есть sync_file_range, но как я понял, фактически он тоже ждёт.

★★★★★

По сути вы просите защитить вас от write reordering. Этот reordering может произойти на разных уровнях:

- ядро попытается упорядочить записи через block queue (близкие друг к другу пойдут первыми)
- кэш контроллера непредсказуем, может быть очень умный — оставлять часто записываемые сектора у себя;
- контроллер попытается упорядочить записи через своё queue (стратегия та же, чтобы лишний раз головку ЖД не дёргать)

То есть, видно, что мы спустились до физического устройства. Поэтому у вас два выхода, или дёргать fsync()/fdatasync(), или отключать все очереди (/sys/block/.../queue/) софта и очереди+кэши у железа, и, по сути, вы придёте к тому, что сделаете полностью синхронное IO.

То есть, вы просите странного. Хотя я ни разу не специалист в этом, так что, может я и не прав. :-)

hexdump01010101
()

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

Сделай отдельную нить + очередь записываемых блоков.

tailgunner ★★★★★
()
Ответ на: комментарий от hexdump01010101

По сути вы просите защитить вас от write reordering.

Примерно так, да. Мне не надо чтобы прям всё подряд, достаточно чтобы группы друг в друга не проникали.

кэш контроллера непредсказуем

Мне бы с софтовой частью разобраться. Хотя я уже чувствую, что в этом направлении всё плохо.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

Сделай отдельную нить

Основное время тратится на запись/чтение. Собственно, я в файле тасую данные, туда-сюда. Вроде в этом случае смысла нет выносить.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Основное время тратится на запись/чтение. Собственно, я в файле тасую данные, туда-сюда.

С отдельной нитью записи ты сможешь запараллелить чтение и запись.

Вроде в этом случае смысла нет выносить.

Если нет смысла выносить, то я не понимаю жалобы «жуть как медленно».

P.S. и используй fdatasync вместо fsync.

tailgunner ★★★★★
()

fsync() + понционально свои очереди как раз и есть что вам нужно.

но он блокируется, пока не запишет данные, а это жуть как медленно.

Внезапно, запись с сохранением очереди мелкими кусками сама по себе медленная, оставляете меньше шансов ОС/железу выбрать оптимальный вариант. Нужно делать либо очередь и/или увеличивать кол-во сбрасываемых блоков между барьерами.

mashina ★★★★★
()
Ответ на: комментарий от mashina

увеличивать кол-во сбрасываемых блоков между барьерами

Да, похоже это поможет.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от tailgunner

aio_fsync

спасибо, попробую и его

i-rinat ★★★★★
() автор топика

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

hibou ★★★★★
()

Есть sync_file_range, но как я понял, фактически он тоже ждёт.

С некоторыми флагами не ждёт, но в любом варианте в качестве барьера не сгодится. Помнится, когда-то была дискуссия среди ядерщиков на тему добавления сисвызова с логикой барьера. Судя по всему, до дела не дошло, хотя, быть может, какой-нибудь патч где-нибудь и завалялся.

const86 ★★★★★
()
Ответ на: комментарий от const86

С некоторыми флагами не ждёт

насколько я понял, ему можно только сказать «чтоб сбросил страницы до следующей записи». Но первая запись заставляет его начать сброс немедленно. А у меня запись будет практически сразу, так что экономии не будет. Отладочная версия без оптимизаций за час работы ест всего минуту времени процессора, с оптимизациями будет и того меньше, так что от фоновости процесса толку мало.

но в любом варианте в качестве барьера не сгодится

Да, я осознал ошибочность идеи. Буду использовать fdatasync и «склеивать» транзакции.

i-rinat ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.