Pull to refresh

Хранение очень большого количества файлов на web-сервер

Недавно встала задача хранить большое количество файлов на сервере.
Сайт — доска объявлений, к каждому объявлению можно загружать от 0 до 10 фото. Для каждой фото, создается уменьшенная копия. В среднем на одно объявление 5 фото.
При проектировании, все файлы хранились в одной папке, это было удобно. Но, количество объявлений превысило 20 000(и стремительно растет), получилось около 100 тыс файлов в одной папке.
Сайт находится на VPS, и пока что все хорошо, если обратится напрямую к файлу. При попытке открыть эту папку, все зависает и жрут много ресурсов. Так же при создание бэкапа для переноса на другой сервер, появилась необходимость разделять архив(около 6 ГБ) на несколько частей, что не получилось и пришлось локально скачать архив, обрабатывать и потом загружать обратно.

Для решения проблемы использовал следующий алгоритм:
1. Файлы от каждой 1000 объявлений храню в отдельной папке(получается до 10000 файлов в одной папке)
2. Делал 2 уровня папок, на первом уровне папки от 0 до 99(сотни тысяч), и на втором уровне(в каждой из 100 папок первого уровня) создал еще по 100 папок(от 0 до 99). Для создания иерархии папок использовал следующий скрипт:

set_time_limit(0);
for($i = 0; $i<100; $i++){
	mkdir($i, 0777);//создаем папки первого уровня
	for($j = 0; $j<100; $j++){
		mkdir($i."/".$j, 0777);//создаем папки второго уровня
	}
}


3. Для определения папки в котором нужно записать(из которой нужно читать файл) используется следующая функция:

function folderDefine($id){
	$d100m = floor($id/100000);//определяем папку для сотен тысяч 
	$d1m = floor($id%100000/1000);//определяем папку для тысяч
	return $d100m."/".$d1m."/";
}


Несколько примеров:
ID=120, путь получается 0/0/ — 0 сонет тысяч и 0 тысяч
ID=1 320, путь получается 0/1/ — 0 сотен тысяч и 1 тысяча
ID=20 300, путь получается 0/20/ — 0 сотен тысяч и 20 тысяч
ID=100 000, путь получается 1/0/ — 1 сотня тысяч и 0 тысяч
ID=200 000, путь получается 2/0/ — 2 сотни тысяч и 0 тысяч
ID=201 000, путь получается 2/1/ — 2 сотни 1 тысяча и 0 тысяч

Таким образом, можно хранить файлы для 100*100*1000 = 10 миллионов записей(объявлений), если файловая система и ресурсы сервера позволяют это делать.

Преимущества:
— увеличивается скорость листинга папки
— легче делать перенос, или даже можно разделить файлы по нескольким серверам
— быстрое нахождение нужного файла
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.