Привет!
Есть проблема с выбором архитектуры демона.
Вкраце опишу задачу:
Демон при старте считывает из БД Oracle информацию и строит
по ней дерево поиска (цифровое деверо).
Критичным ресурсом является именно время поиска информации, а
в случае дерева всё что нужно - просто пройти по нему в глубину.
После построения дерева в памяти демон переходит в бесконечный цикл
обработки запросов клиентов (т.е. блокируется в accept, принимает
соединение, создает дочерний процесс на обработку запроса и снова
блокируется в accept).
Т.о. имеем тривиальную process per connection архитектуру.
Теперь опишу проблему:
Дерево в памяти занимает около 100Mb, т.е. очень много.
Известно, что при создании процесса через fork используется
оптимизация copy-on-write.
Казалось бы, при read-only доступе к дереву в дочерних процессах
никакого копирования быть не должно и все дочерние процессы должны
разделять дерево.
Однако, во-первых, COW опцимизация в Linux постраничная (per page).
Во-вторых, демон написан на Perl'е, который может творить "за кулисами"
всё что угодно.
И последнее, я не уверен на 100%, но скорее всего это так - при
своппинге разделяемых страниц памяти на диск они перестают разделяться
между процессами и система уходит в глубочайший своп (это то, что
я вижу после какого-то времени работы демона при большом количестве
подключений, но не таком большом чтобы была fork-бомба).
Соответсвенно, при такой простой архитектуре и большом объеме дерева
демон не работает корректно.
Сразу на ум приходят 2 решения:
1) Потоки вместо процессов (явное разделение адресного пространства).
К сожалению, использование потоков невозможно (по ряду причин, которые
от меня не зависят).
2) Разделяемая память.
Я пробовал модуль Shareable, но он валится при заполнении дерева.
Может кто предложить грамотный способ решения задачи?
Может есть другие подходы?
Спасибо!