LINUX.ORG.RU

Асинхронная работа с диском, libaio


1

2

Добрый день.

Пишу высокопроизводительный сервер, в данный момент дисковый ввод вывод. Для асинхронного ввода и вывода на диск использую libaio. Проблема в том, что интерфейс для работы с асинхронным вводом выводом (io_submit и io_getevents) не унифицированы с интерфейсом асинхронного доступа к сокетам. То есть - события асинхронного дискового интерфейса нельзя принимать через epoll. Это ведет к тому, что мне приходится чередовать системные вызовы epoll и io_getevents, что усложняет код. Вопрос - нельзя ли как нибудь унифицировать эти системы? Второй вопрос - есть ли аналог асинхронного ввода вывода в солярисе и фряхе? Именно аналога libaio. librt (aio_read, aio_write) не подходит, поскольку нет поллинга, и обычно реализуется через треды.


Ответ на: комментарий от Sorcerer

флаг NONBLOCK игнорируется при работе с диском. то есть, любая операция чтения или записи в файл является блокирующей.

b3qkc
() автор топика

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

Я пользуюсь Java NIO, оно внутри использует самую эффективную реализацию поллинга на целевой системе. В Linix - epoll, в FreeBSD - kqueue, в солярке - /dev/poll или как-то так. В винде соответствующее WinAPI. В итоге мне вообще пофиг что внизу. Обработку делаю в ExecutionService. Это thread pool с динамической подстройкой количества потоков, автоматическим созданием очередей, причем реализацию очереди можно задать и с разными стратегиями поведения, когда все ресурсы пула заняты: подождать, отказать, выбросить самый старый запрос и т.д.

Тебе советую тоже взять что-то посерьезнее. От пионерщины только настрадаешься

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

Ну и конечно сокеты и файлы унифицированны

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

Это не следствие бага 12309 случайно? :)

Вообще если библиотека не имеет poll'ящихся дескрипторов, то лучше использовать её собственные функции в отдельном потоке или процессе, чем чередовать poll и спецфункцию библиотеки. Тем более, что, по-моему, Вы не сможете эффективно реализовать такое чередование.

А aio_suspend() - чем не аналог поллинга? По крайней мере это стандарт, если уж Вас заботит перенос на другие ОС.

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

в том, что на операциях чтения/записи программа зависать не должна. пока она посылает данные на запись, или запрашивает данные - время идет впустую. По мере увеличения числа запросов время может еще больше возрастать. я написал тестовую программу, которая читает данные через read и через libaio. после io_submit и перед io_getevents я гонял пустой цикл. Результаты таковы - 80% времени, которое обычная программа тратит на read, освобождается для других операций

b3qkc
() автор топика
Ответ на: комментарий от vertexua

Другого я не знаю, вот в чем проблема. Как я уже сказал - всё дисковое ио блокирующее, а потому epoll здесь ну никак не поможет.

Советуешь мне взять что то посерьезнее - назови что.

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

Ну да, я говорил о polling. Но вообще я посмотрел, то AIO нормального и кроссплатформенного таки нет. В том числе и под Java. Это просто никому особо не нужно, иначе бы уже запилили в первую очередь.

Кстати, я так и не понял. Это

http://www.ibm.com/developerworks/linux/library/l-async/

libaio или что-то еще?

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

эффективно не эффективно, а альтернатив пока нет.

aio_suspend - это часть librt. реализована эта библиотека в линуксе через треды (то есть, просто запускаются дополнительные треды с блокирующими операциями чтения записи). Через что она реализована в других системах - не знаю, но сколько ни читал - нормальной реализации не нашел.

Поллинг там и правда есть, я ошибся.

На переносимость приложения мне абсолютно наплевать.

b3qkc
() автор топика
Ответ на: комментарий от vertexua

Нет. это librt данный момент уже часть glibc.

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

>реализована эта библиотека в линуксе через треды вот именно, не волшебным же образом. может самому что-то подобное через треды и сделать?

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

по уму (в libaio) это делается следующим образом - запросы к диску копируются в очердь запросов ядра, и системный вызов немедленно возвращается. Как только диск завершает предыдущую операцию - он генерирует прерывание, и ядро передает контроллеру новую группу запросов. После их выполнения контроллер снова оповещает ядро, и оно заносит результаты выполнения в структуры асинхронной подсистемы, чтобы при вызове io_getevents вернуть пользователю список выполненных запросов.

Где тут магия, и почему нельзя было сделать так везде - я не знаю.

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

> Где тут магия, и почему нельзя было сделать так везде - я не знаю.

Это вообще позор, ибо асинхронный ввод/вывод на файловых операциях был в винде ещё на NT кажись (в 2000 совершенно точно был), а в linux нифига.

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

к сожалению, не представлятеся возможным проверить, насколько виндовое ио действительно асинхронное, ибо код закрыт.

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

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

> не представлятеся возможным проверить, насколько виндовое

ио действительно асинхронное


Реально асинхронное, как бы проверенно на практике. Что бы это понять смотреть исходный код совершенно не обязательно.

обсуждаемые здесь линуксовые решения (либаио и либрт) появились как

раз где то в начале века.



Необходимая поддержка в ядре появилась в 2.6, а без поддержки на уровне ядра ничего не получится.

И очень жаль, что нет интеграции с epoll, тот же порт завершения ввода/вывод кажись (может вру, давно винду в глаза не видел, подзабыл) может работать как с файлами, так и с сокетами.

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

Насколько я знаю в винде есть пул потоков для вызова колбеков асинхронного ввода-вывода.

Вроде даже неоднократно возникали споры нужно ли это в ядре линукса/libc и сходились на том, что кому надо - сами сделают.

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

>запросы к диску копируются в очердь запросов ядра

каким образом?
через внутренние системные вызовы ядра? у этого libaio модуль ядра есть?
или через публичные вызовы ядра? если через публичные то что мешает сделать то-же самое без libaio через треды?

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

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

Из последующего сообщения видно, что именно второй вариант.

b3qkc
() автор топика
Ответ на: комментарий от quest

либаио - это интерфейс к асинхроннй подсистеме ядра. функции либаио являются обертками к соответствующим системным вызовам

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

>> асинхронно работают эти вызовы для пользователя или нет, а о том - реальная там асинхронность - или блокирующие вызовы припрятаны в пул тредов

Я думаю это и есть «настоящая» асинхронность, т.к. из обработчика прерывания вызвать userspace callback напрямую очень проблематично.

sergej ★★★★★
()

Если использовать aio_*, то можно получать уведомление о завершении сигналом, а сигнал можно ловить в epoll_pwait (в мане про pselect разжёвано, как именно) или через signalfd. И какая разница, что оно через потоки реализовано? Главное, что работает асинхронно и интерфейс стандартный посиксный. Можно использовать линуксовое aio, но емнип, оно требует режима direct io со всеми вытекающими, да и нестандартное.

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

Разница, очевидно, в следующем:

когда идет дохера ио к диску - операции могут зависать надолго. Я пишу сервер рассчитанный под несколько тысяч одновременных операций.

Варинта два -

1) заводится несоклько тысяч тредов

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

Оба варианта хреновые.

Вариант с сигналами реализован все равно через треды.

b3qkc
() автор топика
Ответ на: комментарий от b3qkc

>к сожалению, не представлятеся возможным проверить, насколько виндовое ио действительно асинхронное, ибо код закрыт.

ЕМНИП, код управления io есть в исходниках ведра винсервер 2003, которые качаются с сайта ms (win research kernel).

cnupm
()
Ответ на: комментарий от b3qkc

> когда идет дохера ио к диску - операции могут зависать надолго

Никакой суперасинхронный механизм не сделает твой винчестер быстрее и при большой нагрузке всё равно придётся ждать долго, причём скорее всего непредсказуемо долго. Если хочешь выжать оптимум(?), реализуй работу с диском сам с нуля.

Вариант с сигналами реализован все равно через треды.

Меньше знаешь - крепче спишь. Оно работает и даже сигналы реально доходят. И не надо думать о том, как оно реализовано.

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

> Никакой суперасинхронный механизм не сделает твой винчестер быстрее и при большой нагрузке всё равно придётся ждать долго

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

От дискового ио я получил то, что нужно - максимальную возможную утилизацию. Большего получить и не надеюсь. Проблема состоит в том, что код кривой. И не надо мне либрт советовать (вы сговорились что ли?) в нем ТА ЖЕ САМАЯ проблема - и при работе через треды (ибо интерфейс с еполлом тоже не синхронизирован), и при работе через сигналы, которые мало того, что реалиованы через треды, еще и с лишним оверхедом от сигналов, И ТОЖЕ БЕЗ УНИФИКАЦИИ ИНТЕРФЕЙСА. Ибо работа с epoll_pwait НИЧЕМ не отличается от постоянного переключения между двумя поллящими вызовами. Короче - либрт - не имеет никаких плюсов кроме переносимости (на которую мне пох) перед либаио, зато имеет кучу минусов.

Если хочешь выжать оптимум(?), реализуй работу с диском сам с нуля.

база работает напрямую с диском, так что это уже реализовано.

Меньше знаешь - крепче спишь. Оно работает и даже сигналы реально доходят. И не надо думать о том, как оно реализовано.

Это ведь толстый троллинг, правда?

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