Искусство удержания файлового дескриптора
В своем решении RabbitMQ использует центральный диспетчер, который отслеживает, какие файлы и когда были открыты и закрыты. Единственное но — диспетчер не используется для открытия файлов, а процессы сами сообщают диспетчеры, когда файлы открываются и закрываются. Это позволяет избежать узких мест при открытии файлов.
Диспетчер держит список наиболее часто используемых дескрипторов (MRU). Если количество дескрипторов приближается к системному ограничению на количество открытых файлов, он отсылает в соответствующие процессы сообщения с предложением закрыть самые неиспользуемые из них.
В случае, если все же ограничение превышено, центральный диспетчер закрывает неиспользуемые файлы, сохраняя состояние, в котором они находились до закрытия. В случае, если процесс, который работал с этим файлом, захочет продолжить с ним работу, диспетчер прозрачно для процесса заново откроет тот файл в том состоянии, в котором он был.
Вся эта функциональность реализована в модуле file_handle_cache.erl. Этот модуль содержит и многие другие оптимизации, значительно ускоряющие работу с файлами, в частности для того, чтобы свести системные вызовы к минимуму. Подробнее — в блоге LShift.
