Jak przechowywać pliki na serwerze

18 lut
{lang: 'pl'}

Przykładowy problem. Posiadamy serwis internetowy, w którym jest bardzo duża liczba użytkowników. Zdjęcia każdego użytkownika trzymamy w osobnym folderze w katalogu /uploads. Niestety przy dużej liczbie zdjęć spada szybkość odczytu, a przy naprawde dużej system nie chce utwarzać kolejnych plików . Czy istnieje lepszy sposób przechowywania plików na serwerze?

Owszem, istnieje, ale przyjrzyjmy się przykładowi powyżej. Trzymanie ogromnej ilości katalogów w jednej lokalizacji nie jest dobrym pomysłem, a to co najmniej w dwóch powodów

  1. Listing w kórym jest kilkadziesiąt tysięcy pozycji zabije każdego klienta ftp, ssh i inne
  2. Praktycznie każda maszyna serwerowa ( mówie o linuxie ) ma nałożone ograniczenia maksymalnej liczby katalogów w jednej lokalizacji. Osobiście testowałem trzy maszyny: Centos, Debian i Slackware i  na każdej to ograniczenia wynosiło 32 000 plików ( katalog to też plik )
  3. Jest jeszcze trzeci powód, a mianowicie odczyt przez serwer w takim gąszczu jest mniej wydajny

Co zatem moglibyśmy zrobić?

Zadajmy sobie pytanie ile katalogów w jednej lokalizacji stanowiło by dla nas optymalną liczbę? 100 ? Ale jak moglibyśmy to zrobić kiedy użytkowników mamy ponad 30 000. Istnieje bardzo proste wyjcie.

Każdy użytkownik posiada swój rekord w bazie danych. Każdy rekord posiada swój unikalny klucz Primary Key. W 99% przypadkach składający się z liczby typu INTEGER. Spójrzmy na przykładowe identyfikatory:

  • 12
  • 758
  • 47255

Każdy z tych identyfikatorów przedstawiamy „płasko” w systemie plików. Zróbmy zatem tak. Załóżmy że nasz identfikator musi mieć stałą liczbę cyfr- niech to będzie 10. Przeliczmy liczbę cyfr w każdym ID i dopełnijmy go zerami żeby się zgadzało.

  • 0000000012
  • 0000000758
  • 0000047255

Założyliśmy że chcemy przechowywać maksymalnie po 100 katalogów. Czyli nasza liczba musi mieć dwa znaki ( wliczając 0-99 ). Patrząc na powyższą listę od razu nasuwa się rozwiązanie:

Weźmy każdego ID i podzielmy go wedlug jego dwóch znaków np.

  • 00/00/00/00/12
  • 00/00/00/07/58
  • 00/00/04/72/55

Jak widzimy każda pozycja jest ścieżką względem naszego katalogu /uploads.

Spełniliśmy nasze założenie w pełni. Ograniczyliśmy liczbę katalogów w jednej lokalizacji a dodatkowo stworzyliśmy przyjazny dla serwera i siebie system plików, w którym wyszukiwanie plików nie powinno sprawiać problemów.

Żeby ostatecznie dopełnić ten post przygotowałem poniżej umieszczam oskryptowanie w php, które zajmuje się budowaniem ścieżek. Pierwotnie był tu dośc opasły skrypt składający się z dwóch funkcji, ale dzięki komentarzowi Trexora, widać jak można to samo przedstawić dużo prościej

function get_path($id, $maxlength = 10, $counterLimit = 2) {
  $id = str_pad( $id, $maxlength, "0", STR_PAD_LEFT );
  return implode( DIRECTORY_SEPARATOR , str_split( $id, $counterLimit ) );
}

użycie:

echo get_path( 12 );
//wynik 00/00/00/00/12
Print Friendly

Wyszukiwane frazy:

  • debian maksymalna ilość podkatalogów w katalogu (10)
  • gdzie przechowywac pliki (7)
  • serwery do przechowywania plików (4)
  • gdzie przechować pliki (4)
  • serwer do przechowywania plików (3)
  • jak przechowywać pliki na serwerze (3)
  • jak trzymać pliki na serwerze (2)
  • jak trzymać zdjęcia na własnym serwerze (2)
  • przechowywanie zdjęć na serwerze adres url (2)
  • ograniczenie ilości katalogów (2)

Inne posty:

  1. Synchronizacja katalogów via FTP
  2. Jak zamazać dane na dysku
  3. Wymiary obrazka w milimetrach w php

Tagi: , , , ,

« »
  • Trexor

    Da się to zrealizować trochę prościej ;)

    function getPath($id, $maxlength = 10, $counterLimit = 2)
    {
    $id = str_pad($id, $maxlength, ’0′, STR_PAD_LEFT);
    return implode(‘/’, str_split($id, $counterLimit));
    }

    • http://kopiec.net Damian Kopiec

      Super. Prosto i elegancko, widzę teraz, że mój przykład jest zrobiony nieco na około.

      Dzięki za wskazówkę ;)

  • Pingback: Blog Krzysztofa Bieleckiego » Blog Archive » Problem ilości plików w jednym katalogu

[B]log programistyczny

IP 38.107.179.240 (38.107.179.240)