Имаме такава система в тежко производство с 30 000+ файла и 20+ GB към днешна дата...
Column | Type | Modifiers
-------------+-----------------------------+----------------------------------------------------------
File_ID | integer | not null default nextval('"ACRM"."File_pseq"'::regclass)
CreateDate | timestamp(6) with time zone | not null default now()
FileName | character varying(255) | not null default NULL::character varying
ContentType | character varying(128) | not null default NULL::character varying
Size | integer | not null
Hash | character varying(40) | not null
Indexes:
"File_pkey" PRIMARY KEY, btree ("File_ID")
Файловете просто се съхраняват в една директория с цялото число File_ID като име на файла. Ние сме над 30 000 без проблеми. Тествах по-високо без проблеми.
Това използва RHEL 5 x86_64 с ext3 като файлова система.
Бих ли го направил отново по този начин? Не. Позволете ми да споделя няколко мисли за редизайна
-
Базата данни все още е "главният източник" на информация за файловете.
-
Всеки файл е sha1() хеширан и се съхранява в йерархия на файловата система въз основа на този хеш:
/FileData/ab/cd/abcd4548293827394723984723432987.jpg
-
базата данни е малко по-интелигентна относно съхраняването на мета-информация за всеки файл. Това ще бъде система с три таблици:
File
:съхранява информация като име, дата, IP, собственик и указател към Blob (sha1)File_Meta
:съхранява двойки ключ/стойност във файла, в зависимост от типа файл. Това може да включва информация като Image_Width и др...Blob
:съхранява препратка към sha1 заедно с неговия размер.
Тази система ще премахне дублирането на съдържанието на файла, като съхрани данните, препоръчани от хеш (няколко файла могат да се позовават на едни и същи файлови данни). Би било много лесно да архивирате синхронизирането на файловата база данни с помощта на rsync.
Също така, ограниченията на дадена директория, съдържаща много файлове, ще бъдат премахнати.
Разширението на файла ще се съхранява като част от уникалния файлов хеш. Например, ако хешът за празен файл е abcd8765
... Празен .txt
файл и празен .php
файл ще се отнася към същия хеш. По-скоро те трябва да се отнасят към abcd8765.php
и abcd8765.txt
. Защо?
Apache и др. могат да бъдат конфигурирани да избират автоматично типа съдържание и правилата за кеширане въз основа на разширението на файла. Важно е да съхранявате файловете с валидно име и разширение, което отразява съдържанието на файла.
Виждате ли, тази система наистина може да повиши производителността, като делегира доставката на файлове чрез nginx. Вижте http://wiki.nginx.org/XSendfile .
Надявам се това да помогне по някакъв начин. Пазете се.