Saya memiliki situs web yang akan menyimpan gambar profil pengguna. Setiap gambar disimpan dalam direktori (Linux) khusus untuk pengguna. Saat ini saya memiliki basis pelanggan 30+, yang berarti saya akan memiliki 30+ folder. Tetapi kotak Linux saya saat ini (ext2 / ext3) tidak mendukung pembuatan lebih dari 32000 direktori. Bagaimana saya bisa melewati ini? Bahkan orang-orang YouTube punya masalah yang sama, dengan thumbnail video. Tetapi mereka menyelesaikannya dengan pindah ke ReiserFS. Tidak bisakah kita memiliki solusi yang lebih baik?
Pembaruan: Ketika ditanya di IRC, orang-orang bertanya tentang memutakhirkannya ke ext4, yang memiliki batas 64 ribu dan tentu saja Anda bahkan bisa melewatinya juga . Atau peretasan kernel untuk mengubah batas.
Pembaruan: Bagaimana membagi basis pengguna ke dalam folder berdasarkan rentang userid. Berarti 1-1000 dalam satu folder, 1000-2000 di yang lain seperti itu. Ini tampaknya sederhana. Bagaimana menurutmu, kawan?
Terus terang, tidak ada cara lain?
sumber
Jawaban:
Batas itu adalah per-direktori, bukan untuk keseluruhan sistem file, sehingga Anda bisa mengatasinya dengan melakukan sub-pembagian lebih lanjut. Misalnya, alih-alih memiliki semua subdirektori pengguna dalam direktori yang sama, pisahkan per dua karakter pertama dari nama tersebut sehingga Anda memiliki sesuatu seperti:
Bahkan yang lebih baik adalah membuat beberapa bentuk hash dari nama-nama dan menggunakannya untuk divisi. Dengan cara ini Anda akan mendapatkan penyebaran yang lebih baik di antara direktori daripada, dengan contoh huruf awal, "da" menjadi sangat penuh dan "zz" benar-benar kosong. Misalnya jika Anda mengambil nama CRC atau MD5 dan menggunakan 8 bit pertama Anda akan mendapatkan sesuatu seperti:
Ini dapat diperluas ke kedalaman lebih lanjut sesuai kebutuhan, misalnya seperti jika menggunakan nama pengguna bukan nilai hash:
Metode ini digunakan di banyak tempat seperti cache squid, untuk menyalin contoh Ludwig, dan cache lokal browser web.
Satu hal penting yang perlu diperhatikan adalah bahwa dengan ext2 / 3 Anda akan mulai mengenai masalah kinerja sebelum Anda mendekati batas 32.000, karena direktori dicari secara linear. Pindah ke sistem file lain (ext4 atau reiser misalnya) akan menghapus inefisiensi ini (reiser mencari direktori dengan algoritma binary-split sehingga direktori lama ditangani jauh lebih efisien, ext4 mungkin juga melakukannya) serta batas tetap per direktori.
sumber
Jika Anda terikat ke ext2 / ext3 satu-satunya kemungkinan yang saya lihat adalah mempartisi data Anda. Temukan kriteria yang membagi data Anda menjadi potongan-potongan yang dapat dikelola dengan ukuran yang sama.
Jika hanya tentang gambar profil yang akan saya lakukan:
Sebagai contoh, cache SQUID melakukannya dengan cara ini:
f / 4b / 353ac7303854033
Direktori level atas adalah hex-digit pertama, level kedua adalah dua hex-digit berikutnya, dan nama file adalah hex-digit yang tersisa.
sumber
Anda memang memiliki solusi yang lebih baik - gunakan sistem file yang berbeda, ada banyak yang tersedia, banyak di antaranya dioptimalkan untuk tugas yang berbeda. Seperti yang Anda tunjukkan, ReiserFS dioptimalkan untuk menangani banyak file dalam direktori.
Lihat di sini untuk perbandingan sistem file.
Hanya senang Anda tidak terjebak dengan NTFS yang benar-benar buruk untuk banyak file di direktori. Saya akan merekomendasikan JFS sebagai pengganti jika Anda tidak suka menggunakan ext4 FS yang relatif baru (tetapi tampaknya stabil).
sumber
Apakah gambar profil kecil? Bagaimana dengan memasukkannya ke dalam basis data dengan data profil lainnya? Ini mungkin bukan pilihan terbaik untuk Anda, tetapi patut dipertimbangkan ...
Berikut adalah whitepaper Microsoft (yang lebih lama) tentang topik: Untuk BLOB atau bukan BLOB .
sumber
Saya telah meretas galeri web kecil, di mana saya berakhir dengan variasi masalah ini; Saya "hanya" memiliki ~ 30.000 gambar di direktori cache, yang ternyata sangat lambat (ext2 menggunakan daftar yang ditautkan untuk indeks direktori, seperti yang saya ingat).
Saya akhirnya melakukan sesuatu seperti ini:
Ini akan mempartisi data dalam 256 direktori, yang memberikan pencarian direktori cepat untuk masing-masing dari tiga level.
sumber
Bukan jawaban langsung untuk masalah Anda, tetapi sesuatu yang harus diperhatikan untuk referensi di masa mendatang adalah proyek terkait OpenBSD yang disebut 'Epitome'
Epitome adalah mesin yang menyediakan layanan Penyimpanan Instans Tunggal, Penyimpanan Beralamat Konten, dan Deduplikasi.
Semua data Anda disimpan di penyimpanan data sebagai blok hash, menghapus blok non-unik untuk mengurangi penggunaan ruang, dan memungkinkan Anda untuk melupakan mekanisme penyimpanan karena Anda hanya dapat meminta konten dari penyimpanan data oleh UUID.
Epitome saat ini bersifat eksperimental, tetapi sesuatu yang harus diperhatikan untuk masa depan.
sumber
Secara umum Anda ingin menghindari memiliki direktori dengan banyak file / direktori di dalamnya. Alasan utama adalah bahwa ekspansi wildcard pada baris perintah, akan menghasilkan kesalahan "Terlalu banyak argumen" yang mengakibatkan banyak rasa sakit ketika mencoba untuk bekerja dengan direktori ini.
Carilah solusi yang membuat pohon lebih dalam tetapi lebih sempit, misalnya dengan membuat subfolder seperti yang telah dijelaskan orang lain.
sumber
Kami memiliki masalah serupa, solusinya - seperti yang disebutkan sebelumnya - adalah membuat hierarki direktori.
Tentu saja jika Anda memiliki aplikasi kompleks yang bergantung pada struktur direktori datar, Anda mungkin perlu banyak perbaikan. Jadi, baik untuk mengetahui bahwa ada solusi, gunakan symlink yang tidak memiliki batas 32k yang disebutkan. Maka Anda punya banyak waktu untuk memperbaiki aplikasi ...
sumber
Mengapa tidak menggunakan pendekatan timestamp, dan kemudian memiliki opsi overflow.
Sebagai contoh
Jadi katakanlah cap waktu Anda adalah: 1366587600
Abaikan 2 digit terakhir (atau hanya sedikit konyol). Pisahkan cap ke dalam kumpulan 4 (jumlah direktori tidak boleh lebih dari 9999 - jika Anda mau, Anda bisa memisahkannya secara berbeda).
Ini seharusnya memberi Anda sesuatu seperti ini:
Kemudian juga periksa jumlah dalam dir sebelum mengunggah, jika mendapatkan jumlah besar unggahan (yaitu 32000 + per 100 detik), kemudian iterasikan direktori dengan huruf kedua atau huruf, misalnya:
atau
Kemudian catat stempel waktu + huruf atau kode jalur lengkap ke db bersama dengan pengguna dan Anda harus mengaturnya.
pathstamp: 1366587600 atau 13665876a (jika Anda menggunakan huruf).
Ini memang berakhir dengan sejumlah besar direktori, tetapi bisa sangat berguna untuk menangani revisi file. Misalnya, jika pengguna ingin menggunakan gambar profil baru, Anda masih memiliki versi timestamped lama dari yang lebih tua jika mereka ingin membatalkan perubahan (tidak hanya tertulis berlebihan).
sumber
Saya sarankan memutuskan berapa banyak subdirektori maksimum yang Anda inginkan (atau dapat) miliki di folder induk.
Maka Anda perlu mengonversi id pengguna Anda sehingga mereka mulai dari 1.
Maka Anda dapat melakukan:
modulo = currentId % numberOfSubdirectories
modulo
sekarang akan berisi nomor subdirektori Anda yang tidak akan pernah lebih besar dari yangnumberOfSubdirectories
Anda pilih.Lakukan apa pun yang Anda inginkan dengan modulo, hash, misalnya.
Juga subdirektori cara ini akan diisi secara linear.
sumber