Решение проблемы: ограничение на кол-во каталогов (32000) в каталоге в *nix

bigton
На сайте с 17.08.2009
Offline
43
602

Всем привет!

Я являюсь программистом на одном игровом проекте и так сложилось, что небольшая часть пользовательских данных у нас по прежнему храниться в файлах. То есть, условно есть каталог /users, в котором при регистрации нового пользователя создается каталог с его именем (/users/bigton). Проект существует уже почти 4 года и раз в год мы сталкивались с одной и той же проблемой: при создании каталога пользователя возникала ошибка too many links, то есть количество каталогов в каталоге /users достигало 32000 и новые каталоги не создавались. Обычно проблема решалась путем удаления каталогов неактивных пользователей и "свободного места" хватало еще на год, но не на этот раз...

На этот раз проблема требовала другого решения, поиск подсказывал, что самым рациональным решением являлась бы реорганизация структуры каталогов в папке /users: /users/bigton → /users/bi/bigton. Но, к сожалению, такое такое решение потребовало бы внесения значительных изменений в программный код, а так как в ближайшем будущем мы планируем вообще отказаться от файлов (работа в этом направление ведется уже полгода) тратить время на решение этой задачи не хочется совсем.

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

Было


<?php

/**
*
* Условная функция регистрации пользователя
*
* Пример
* Функция создает каталог /users/bigtonnew
*
*/
function registration($username)
{
return mkdir($_SERVER['DOCUMENT_ROOT'].'/users/'.$username, 0777);
}

?>

Стало


<?php

/**
*
* Условная функция регистрации пользователя
*
* Пример
* Функция создает каталог /users2/bi/bigtonnew и символическую ссылку /users/bigtonnew на созданный каталог
*
*/
function registration($username)
{
$sub_folder = $_SERVER['DOCUMENT_ROOT'].'/users2/'.strtolower(substr($username, 0, 2));

if ( ! file_exists($sub_folder))
{
if ( ! mkdir($sub_folder, 0777))
{
return false;
}
}

$user_folder = $sub_folder.'/'.$username;

if ( ! mkdir($user_folder, 0777))
{
return false;
}

return symlink($user_folder, $_SERVER['DOCUMENT_ROOT'].'/users/'.$username);
}

?>

В итоге:

- рациональная структура каталогов для новых пользователей (/users2/bi/bigtonnew);

- никаких значительных изменений в программный код (скрипты по прежнему читаю, пишут, проверяют на существование файлы в каталоге /users/bigtonnew/*);

- ограничение на 32000 каталогов в каталоге /users не актуально (задача решена).

Недостатки решения:

- использование символических ссылок незначительно замедляет процесс работы с файлами, так как "системе нужно проанализировать содержимое ссылки и установить связь с настоящим файлом";

- ограничение на максимальное количество ссылок в каталоге /users по прежнему остается, только это значение на порядки больше 32000 и зависит от используемой файловой системы.

bbon
На сайте с 01.04.2006
Offline
168
#1

а почему было нельзя /users смонтировать просто на ext4, где вроде нет такого ограничения? 😕

Mik Foxi
На сайте с 02.03.2011
Offline
1216
#2

ext4 + 64 битная ось и никаких ограничений.

Антибот, антиспам, веб фаервол, защита от накрутки поведенческих: https://antibot.cloud/ (Зеркало: https://антибот.рф/ ) Форум на замену серчу: https://foxi.biz/

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий