Mysql
 sql >> Database >  >> RDS >> Mysql

Memorizzazione efficiente delle immagini caricate dall'utente sul file system

Abbiamo un tale sistema in forte produzione con oltre 30.000 file e oltre 20 GB fino ad oggi...

   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")

I file vengono semplicemente archiviati in una singola directory con l'intero File_ID come nome del file. Siamo oltre 30.000 senza problemi. Ho testato più in alto senza problemi.

Questo sta usando RHEL 5 x86_64 con ext3 come file system.

Lo farei di nuovo in questo modo? No. Consentitemi di condividere un paio di pensieri su una riprogettazione.

  1. Il database è ancora la "fonte principale" delle informazioni sui file.

  2. Ogni file viene sottoposto a hash sha1() e archiviato in una gerarchia di filesystem basata su quell'hash:/FileData/ab/cd/abcd4548293827394723984723432987.jpg

  3. il database è un po' più intelligente per quanto riguarda la memorizzazione di meta-informazioni su ciascun file. Sarebbe un sistema a tre tabelle:

    File :memorizza informazioni come nome, data, IP, proprietario e un puntatore a un BLOB (sha1)
    File_Meta :memorizza le coppie chiave/valore sul file, a seconda del tipo di file. Questo può includere informazioni come Image_Width, ecc...
    Blob :memorizza un riferimento allo sha1 insieme alla sua dimensione.

Questo sistema deduplica il contenuto del file memorizzando i dati a cui fa riferimento un hash (più file potrebbero fare riferimento agli stessi dati del file). Sarebbe molto facile eseguire il backup della sincronizzazione del database di file utilizzando rsync.

Inoltre, verrebbero eliminate le limitazioni di una determinata directory contenente molti file.

L'estensione del file verrebbe archiviata come parte dell'hash del file univoco. Ad esempio, se l'hash di un file vuoto fosse abcd8765 ... Un .txt vuoto file e vuoto .php file si riferirebbe allo stesso hash. Piuttosto, dovrebbero fare riferimento a abcd8765.php e abcd8765.txt . Perché?

Apache, ecc. possono essere configurati per scegliere automaticamente il tipo di contenuto e le regole di memorizzazione nella cache in base all'estensione del file. È importante memorizzare i file con un nome valido e l'estensione che rifletta il contenuto del file.

Vedete, questo sistema potrebbe davvero aumentare le prestazioni delegando la consegna dei file tramite nginx. Vedi http://wiki.nginx.org/XSendfile .

Spero che questo aiuti in qualche modo. Abbi cura di te.