Как организовать файловое хранилище пользователей (виртуальная фс или нативная)?
А тут все зависит от количества и размера файлов, от количества пользователей и от распределения файлов по пользователям. Поясняю, если пользовтелей много (миллионы) а файлов у них мало (десятки) то у Вас будет много папок, а в них мало файлов, это не экономный расход файловой системы, будет много уходить на оглавление, и будет папка с медленным доступом (в которой лежат папки пользователей). Если пользователей мало, а файлов много, то так же, будут папки с очень большим оглавлением. Тут можно или выбрать файловую систему, которая решает эти проблемы или самому сбалансировать дерево папок, чтобы поиск был оптимальным. Как добиться оптимального поиска, сделать сбалансированную структуру папок, чтобы в каждой было не много и не мало файлов с очень различающимися названиями. Например, можно сделать 2х или 3х уровневую систему папок, в которой лежат файл переименованные в HEX, например /EA8D253F/2145AE32/F259C201 Нам нужно генерировать случайные имена папок и файлов, а потом в базу данных писать этот путь. это будет оптимально для любой файловой системы и любого кол-ва файлов, просто увеличте длину имен, алфавит и вложенность папок (в завистмости от особенности файловой системы и своих нужд, это нужно изучать). Кроме всего, это решает кучу проблем - файлы с одинаковыми именами и файлы со странными символами в именах (в том числе арабские, китайские и прочие UTF8 имена), исполняемые файлы и вообще вопрос безопасности, относительную деперсонализацию данных, и прочее... Про FTP лучше забудьте, ни какие пользователи по FTP ходить не должны, это архаичный протокол позднего проволочного века, применяемый сейчас только мной и прочими извращенцами. А если Вы еще будете вычислять для файлов хеши, несколько разных хешей на всякий случай, и хранить их вместе с именами и всеми метаданными, в базе, то можно избавиться от дублирования на диске (есть случаи, когда у разных пользователей большой процент одинаковых файлов). Вот тут кое-какие наброски: /lib/impress.files.js#L111-L174 даже файлы на винте сжимаются двумя ZIP и GZIP в зависмсти от размера. Берите, дарю методу...
Тут уже упомянули хеши, советую вам основательно над ними подумать. Сейчас хэши считаются довольно быстро на современном железе, так что подумайте о content-adressable файловой системе. На классическую ФС мапается элементарно: хэш бьется на нужное количество кусков и по ним формируется вложенная структура, что-то вроде f5/c3/ab/1414.... . Иерархию папок хранить в БД, не знаю правда что для этого лучше использовать, по идее реальная ФС как раз-таки лучше подходит для хранения вложенной структуры, чем например, реляционная БД. Так что нужно будет основательно поисследовать в этом месте - какую БД взять для метаданных о файлах. Ну и собственно помимо остальной метаинфы писать хэш контента, и находить реальное содержимое по хэшу. Шардиться такое решение должно очень хорошо, плюс, как отметил Тимур Шемсединов, будет выигрыш от недублирования файлов (если реализовать более умную систему, которая будет считать ссылки на конкретный хэш). Вероятность совпадения хэша очень очень низкая, для надежности еще можно проверку на размер поставить, хотя врядли за время использования вы с таким случаем столкнетесь.