Menyimpan jutaan gambar dalam sistem file

79

Saya memiliki proyek yang akan menghasilkan sejumlah besar gambar. Sekitar 1.000.000 untuk memulai. Itu bukan gambar besar jadi saya akan menyimpan semuanya di satu mesin di awal.

Bagaimana Anda disarankan untuk menyimpan gambar-gambar ini secara efisien? (Sistem file NTFS saat ini)

Saya sedang mempertimbangkan skema penamaan ... untuk memulai semua gambar akan memiliki nama tambahan dari 1 ke atas. Saya harap ini akan membantu saya mengurutkannya nanti jika perlu, dan melemparkannya ke folder yang berbeda.

apa yang akan menjadi skema penamaan yang lebih baik:

a / b / c / 0 ... z / z / z / 999

atau

a / b / c / 000 ... z / z / z / 999

ada ide tentang ini?

s.mihai
sumber
1
Apakah mereka terkait dengan pengguna tertentu atau hanya generik? Apakah mereka dikelompokkan dalam mode apa pun?
hanya generik. banyak gambar yang dihasilkan oleh beberapa peralatan teknis. Saya menamai mereka bertahap dari 1 hanya untuk memiliki ide waktu refence.
s.mihai
bagaimana mereka akan digunakan / diakses? melalui aplikasi yang dipesan lebih dahulu atau apa?
dove
16
Apakah ini Anda? i46.tinypic.com/1z55k7q.jpg
1
:)) ya ... 1 mil. gambar porno :))
s.mihai

Jawaban:

73

Saya akan merekomendasikan menggunakan sistem file biasa daripada database. Menggunakan sistem file lebih mudah daripada database, Anda dapat menggunakan alat biasa untuk mengakses file, sistem file dirancang untuk penggunaan seperti ini dll. NTFS seharusnya berfungsi dengan baik sebagai sistem penyimpanan.

Jangan menyimpan jalur aktual ke basis data. Lebih baik menyimpan nomor urut gambar ke database dan memiliki fungsi yang dapat menghasilkan jalur dari nomor urut. misalnya:

 File path = generatePathFromSequenceNumber(sequenceNumber);

Lebih mudah ditangani jika Anda perlu mengubah struktur direktori. Mungkin Anda perlu memindahkan gambar ke lokasi yang berbeda, mungkin Anda kehabisan ruang dan Anda mulai menyimpan beberapa gambar pada disk A dan beberapa di disk B dll. Lebih mudah untuk mengubah satu fungsi daripada mengubah jalur dalam database .

Saya akan menggunakan algoritma semacam ini untuk menghasilkan struktur direktori:

  1. Pertama pad nomor urut Anda dengan nol terkemuka sampai Anda memiliki setidaknya 12 digit string. Ini adalah nama untuk file Anda. Anda mungkin ingin menambahkan akhiran:
    • 12345 -> 000000012345.jpg
  2. Kemudian pisahkan string menjadi 2 atau 3 blok karakter di mana setiap blok menunjukkan level direktori. Memiliki jumlah level direktori yang tetap (misalnya 3):
    • 000000012345 -> 000/000/012
  3. Simpan file ke dalam direktori yang dihasilkan:
    • Dengan demikian path lengkap dan nama file untuk file dengan urutan id 123adalah 000/000/012/00000000012345.jpg
    • Untuk file dengan urutan id 12345678901234jalannya akan123/456/789/12345678901234.jpg

Beberapa hal yang perlu dipertimbangkan tentang struktur direktori dan penyimpanan file:

  • Algoritma di atas memberi Anda sebuah sistem di mana setiap direktori daun memiliki maksimum 1000 file (jika Anda memiliki kurang dari 1 000 000 000 000 file)
  • Mungkin ada batasan berapa banyak file dan subdirektori yang dapat berisi direktori, misalnya sistem file ext3 di Linux memiliki batas 31.998 sub-direktori per satu direktori.
  • Alat normal (WinZip, Windows Explorer, baris perintah, bash shell, dll.) Mungkin tidak berfungsi dengan baik jika Anda memiliki banyak file per direktori (> 1000)
  • Struktur direktori itu sendiri akan memakan ruang disk, jadi Anda tidak perlu terlalu banyak direktori.
  • Dengan struktur di atas Anda selalu dapat menemukan jalur yang benar untuk file gambar dengan hanya melihat nama file, jika Anda mengacaukan struktur direktori Anda.
  • Jika Anda perlu mengakses file dari beberapa mesin, pertimbangkan berbagi file melalui sistem file jaringan.
  • Struktur direktori di atas tidak akan berfungsi jika Anda menghapus banyak file. Ini meninggalkan "lubang" dalam struktur direktori. Tetapi karena Anda tidak menghapus file apa pun, itu tidak masalah.
Juha Syrjälä
sumber
1
sangat menarik! memisahkan nama file ... saya tidak memikirkan itu. Saya menganggap ini adalah cara yang elegan untuk melakukannya: -?
s.mihai
37
Menggunakan hash (seperti MD5) sebagai nama file, serta distribusi direktori, akan berfungsi. Integritas file tidak hanya akan bermanfaat bagi skema penamaan (mudah diperiksa), tetapi Anda juga akan memiliki distribusi yang merata di seluruh hierarki direktori. Jadi jika Anda memiliki file bernama "f6a5b1236dbba1647257cc4646308326.jpg" Anda akan menyimpannya di "/ f / 6" (atau sedalam yang Anda butuhkan). Kedalaman 2 level memberikan 256 direktori, atau hanya di bawah 4000 file per direktori untuk file 1m awal. Ini juga akan sangat mudah untuk mengotomatiskan redistribusi ke skema yang lebih dalam.
+1 Saya baru memperhatikan jawaban ini mirip dengan yang baru saya posting.
3dinfluence
1
Saya pasti setuju untuk menggunakan sistem file dan membuat pengenal artfisial untuk "mengiris" menjadi nama folder. Tetapi Anda juga harus mencoba untuk mendapatkan distribusi pengidentifikasi acak, yaitu jangan menggunakan nomor urut. Itu akan memungkinkan Anda memiliki pohon folder yang lebih seimbang. Selain itu, dengan distribusi acak Anda dapat lebih mudah mempartisi pohon di beberapa sistem file. Saya juga menggunakan SAN berbasis ZFS dengan dedup dihidupkan dan volume jarang untuk setiap filesystem. Anda masih bisa menggunakan NTFS dengan menggunakan iSCSI untuk mengakses SAN.
Michael Dillon
Jika Anda pergi dari kanan ke kiri dalam langkah 2 file-file tersebut didistribusikan secara merata. Anda juga tidak perlu khawatir bahwa Anda tidak mengisi dengan angka nol yang cukup karena jumlah file yang tidak terbatas
ropo
31

Saya akan menaruh 2 sen saya pada saran negatif: Jangan pergi dengan database.

Saya telah bekerja dengan database penyimpanan gambar selama bertahun-tahun: file besar (1 meg-> 1 manggung), sering diubah, beberapa versi file, diakses cukup sering. Masalah basis data yang Anda temui dengan file besar yang sedang disimpan sangat membosankan untuk ditangani, masalah penulisan dan transaksi sangat rumit dan Anda mengalami masalah penguncian yang dapat menyebabkan kecelakaan kereta api besar. Saya memiliki lebih banyak latihan dalam menulis skrip dbcc, dan mengembalikan tabel dari cadangan daripada yang dimiliki orang normal mana pun .

Sebagian besar sistem baru yang pernah saya gunakan telah mendorong penyimpanan file ke sistem file, dan mengandalkan database hanya untuk pengindeksan. Sistem file dirancang untuk mengambil penyalahgunaan semacam itu, mereka jauh lebih mudah untuk diperluas, dan Anda jarang kehilangan seluruh sistem file jika satu entri rusak.

Satanicpuppy
sumber
Iya. catatan diambil!
s.mihai
5
Sudahkah Anda melihat tipe data FILESTREAM SQL 2008? Ini adalah persilangan antara basis data dan penyimpanan sistem file.
NotMe
Memberi +1 untuk tetap menggunakan server file daripada database karena Anda melakukan operasi IO yang cepat dan jarang.
Bagaimana jika Anda hanya menyimpan beberapa ratus dokumen atau foto per basis data - apa kerugian menggunakan basis data untuk penyimpanan?
Bip bip
1
+1 ... sistem file adalah semacam "basis data" (ntfs pastinya), jadi mengapa membuatnya terlalu rumit.
akira
12

Saya pikir sebagian besar situs yang harus berurusan dengan ini menggunakan semacam hash untuk memastikan bahwa file didistribusikan secara merata di folder.

Jadi, katakan Anda memiliki hash file yang kira-kira seperti ini. 515d7eab9c29349e0cde90381ee8f810
Anda bisa menyimpannya di lokasi berikut dan Anda dapat menggunakan berapa banyak level yang Anda butuhkan untuk menjaga agar jumlah file di setiap folder tetap rendah.
\51\5d\7e\ab\9c\29\349e0cde90381ee8f810.jpg

Saya telah melihat pendekatan ini dilakukan berkali-kali. Anda masih membutuhkan database untuk memetakan hash file ini ke nama yang dapat dibaca manusia dan apa pun metadata lain yang perlu Anda simpan. Tetapi pendekatan ini menskala dengan cukup baik b / c Anda dapat mulai mendistribusikan ruang alamat hash antara beberapa komputer dan atau kumpulan penyimpanan, dll.

Pengaruh 3d
sumber
2
Git menggunakan pendekatan yang sama: git-scm.com/book/en/v2/Git-Internals-Git-Objects (untuk mendukung jawaban ini)
aexl
11

Idealnya, Anda harus menjalankan beberapa tes pada waktu akses acak untuk berbagai struktur, seperti pengaturan hard drive khusus Anda, caching, memori yang tersedia, dll. Dapat mengubah hasil ini.

Dengan asumsi Anda memiliki kendali atas nama file, saya akan mempartisi mereka pada level 1000-an per direktori. Semakin banyak level direktori yang Anda tambahkan, semakin banyak inode yang Anda bakar, sehingga ada tarikan-dorong di sini.

Misalnya,

/ root / [0-99] / [0-99] / namafile

Catatan, http://technet.microsoft.com/en-us/library/cc781134(WS.10).aspx memiliki detail lebih lanjut tentang pengaturan NTFS. Secara khusus, "Jika Anda menggunakan banyak file dalam folder NTFS (300.000 atau lebih), nonaktifkan pembuatan nama file pendek untuk kinerja yang lebih baik, dan terutama jika enam karakter pertama dari nama file yang panjang itu serupa."

Anda juga harus melihat ke dalam menonaktifkan fitur sistem file yang tidak Anda butuhkan (misalnya, waktu akses terakhir). http://www.pctools.com/guides/registry/detail/50/

Jason Yanowitz
sumber
3
+1 untuk menonaktifkan generasi nama file 8.3 dan waktu akses terakhir; itulah hal pertama yang terlintas dalam pikiran ketika saya membaca "sejumlah besar [file]" dan "NTFS" (Windows).
merampok
tautan turun ........................
Pacerier
7

Apa pun yang Anda lakukan, jangan menyimpan semuanya dalam satu direktori.

Bergantung pada distribusi nama-nama gambar ini, Anda dapat membuat struktur direktori di mana Anda memiliki folder tingkat atas satu huruf di mana Anda akan memiliki satu set subfolder untuk huruf ke-2 gambar dll.

Begitu:

Folder img\a\b\c\d\e\f\g\akan berisi gambar-gambar yang dimulai dengan 'abcdefg' dan seterusnya.

Anda bisa memperkenalkan kedalaman Anda sendiri yang diperlukan.

Hal yang hebat tentang solusi ini adalah bahwa struktur direktori secara efektif bertindak seperti hashtable / kamus. Diberi nama file gambar, Anda akan tahu direktori dan diberi direktori, Anda akan tahu bagian dari gambar yang ada di sana.

Wim Hollebrandse
sumber
\ a \ b \ c \ d \ e \ f \ yang saya lakukan sekarang, saya berpikir ada cara yang bijaksana untuk melakukan ini.
s.mihai
1
Itu solusi yang diterima secara umum tentang cara menyimpannya secara fisik. Jelas menghasilkan URL gambar adalah sesuatu yang dapat dengan mudah dilakukan secara dinamis berdasarkan nama file gambar. Selain itu, untuk menyajikannya, Anda bahkan dapat memperkenalkan img-a, img-b subdomain di server gambar jika Anda mau, untuk mempercepat waktu pemuatan.
2
Dan +1 untuk "jangan menyimpan semuanya dalam satu direktori". Saya mendukung sistem warisan yang telah menempatkan lebih dari 47000 file di server dalam satu folder, dan dibutuhkan sekitar satu menit bagi Explorer hanya untuk membuka folder.
Mark Ransom
5
Melakukan \ b \ c \ d \ e \ f \ g membuat struktur direktori sangat dalam dan setiap direktori hanya berisi beberapa file. Lebih baik menggunakan lebih dari satu huruf per tingkat direktori misalnya ab \ cd \ ef \ atau abc \ def \. Direktori juga mengambil ruang dari disk sehingga Anda tidak ingin terlalu banyak.
Juha Syrjälä
2
Saya harus mendukung aplikasi yang memiliki 4 + juta file semua dalam satu direktori; itu bekerja dengan sangat baik, tetapi Anda TIDAK PERNAH mendapatkan penjelajah untuk membuka folder, itu akan terus menyortir penambahan baru. +1 untuk NTFS dapat menanganinya tanpa sekarat.
SqlACID
5

Saya akan menyimpan ini di sistem file tetapi tergantung pada seberapa cepat jumlah file akan tumbuh. Apakah file ini di-host di web? Berapa banyak pengguna yang akan mengakses file ini? Ini adalah pertanyaan yang perlu dijawab sebelum saya bisa memberi Anda rekomendasi yang lebih baik. Saya juga akan melihat Haystack dari Facebook, mereka memiliki solusi yang sangat baik untuk menyimpan dan menyajikan gambar.

Juga jika Anda memilih sistem file, Anda perlu mempartisi file-file ini dengan direktori. Saya telah melihat masalah ini dan mengusulkan solusi tetapi tidak sempurna dengan cara apa pun. Saya mempartisi berdasarkan tabel hash dan pengguna Anda dapat membaca lebih banyak di blog saya .

Lukasz
sumber
gambar tidak dimaksudkan untuk sering diakses. jadi tidak ada masalah dengan ini. jumlah mereka akan tumbuh cukup cepat. saya berasumsi akan ada 1mil. tandai dalam 1 bulan.
s.mihai
Saya tertarik pada tampilan programmer sehingga saya tidak terlalu banyak berpikir terlalu banyak
s.mihai
Jadi jika Anda tidak memerlukan akses cepat, tumpukan jerami mungkin bukan untuk Anda. Menggunakan Direktori untuk Partisi adalah solusi paling sederhana dalam pandangan saya.
Lukasz
5

Kami memiliki sistem toko foto dengan 4 juta gambar. Kami menggunakan basis data hanya untuk data meta dan semua gambar disimpan di sistem file menggunakan sistem penamaan terbalik, di mana nama folder dihasilkan dari digit terakhir file, last-1, dan sebagainya. misalnya: 000001234.jpg disimpan dalam struktur direktori seperti 4 \ 3 \ 2 \ 1 \ 000001234.jpg.

Skema ini bekerja sangat baik dengan indeks identitas dalam database, karena ini mengisi struktur direktori secara merata.


sumber
4

Titik cepat, Anda tidak perlu menyimpan path file di DB Anda. Anda bisa menyimpan nilai numerik, jika file Anda dinamai sesuai cara Anda menggambarkan. Kemudian menggunakan salah satu skema penyimpanan terdefinisi dengan baik yang sudah dibahas, Anda bisa mendapatkan indeks sebagai nomor dan sangat cepat menemukan file dengan melintasi struktur direktori.

Pak Boy
sumber
: -? titik cepat yang bagus. Hanya saja sekarang saya tidak memiliki algoritma untuk menghasilkan path.
s.mihai
4

Apakah gambar Anda harus dinamai secara unik? Bisakah proses yang menghasilkan gambar-gambar ini menghasilkan nama file yang sama lebih dari sekali? Sulit dikatakan tanpa mengetahui perangkat apa yang membuat nama file tetapi mengatakan perangkat itu 'reset' dan setelah restart itu mulai memberi nama gambar seperti yang dilakukan terakhir kali itu 'reset' - jika itu menjadi perhatian ..

Juga, Anda mengatakan bahwa Anda akan menekan 1 juta gambar dalam waktu satu bulan. Bagaimana setelah itu? Seberapa cepat gambar-gambar ini akan terus mengisi sistem file? Akankah mereka mencapai puncak pada titik dan level di sekitar 1 juta gambar TOTAL atau akan terus tumbuh dan tumbuh, bulan demi bulan?

Saya bertanya karena Anda dapat mulai mendesain sistem file Anda berdasarkan bulan, kemudian oleh gambar. Saya mungkin cenderung menyarankan agar Anda menyimpan gambar dalam struktur direktori seperti itu:

imgs\yyyy\mm\filename.ext

where: yyyy = 4 digit year
         mm = 2 digit month

example:  D:\imgs\2009\12\aaa0001.jpg
          D:\imgs\2009\12\aaa0002.jpg
          D:\imgs\2009\12\aaa0003.jpg
          D:\imgs\2009\12\aaa0004.jpg
                   |
          D:\imgs\2009\12\zzz9982.jpg
          D:\imgs\2010\01\aaa0001.jpg (this is why I ask about uniqueness)
          D:\imgs\2010\01\aab0001.jpg

Bulan, tahun, bahkan hari baik untuk gambar jenis keamanan. Tidak yakin apakah ini yang Anda lakukan, tetapi saya melakukannya dengan kamera keamanan rumah yang mengambil foto setiap 10 detik ... Dengan cara ini aplikasi Anda dapat menelusuri waktu tertentu atau bahkan rentang di mana Anda mungkin berpikir bahwa gambar itu dihasilkan . Atau, alih-alih tahun, bulan - apakah ada "makna" lain yang dapat diturunkan dari file gambar itu sendiri? Beberapa deskriptor lain, selain contoh tanggal yang saya berikan?

Saya tidak akan menyimpan data biner di DB. Tidak pernah memiliki kinerja yang baik / keberuntungan dengan hal semacam itu. Tidak bisa membayangkan itu bekerja dengan baik dengan 1 juta gambar. Saya akan menyimpan nama file dan hanya itu. Jika mereka semua akan menjadi JPG maka jangan menyimpan ekstensi. Saya akan membuat tabel kontrol yang menyimpan pointer ke server file, drive, path, dll. Dengan cara ini Anda dapat memindahkan gambar-gambar ke kotak lain dan masih menemukannya. Apakah Anda perlu menandai kata kunci gambar Anda? Jika demikian maka Anda ingin membangun tabel yang sesuai yang memungkinkan pemberian tag semacam itu.

Anda / orang lain mungkin telah membahas ide-ide ini ketika saya menjawab .. Semoga ini bisa membantu ..

Taptronic
sumber
1. semua file akan dinamai secara unik 2. sistem akan tumbuh dan tumbuh pada awalnya akan keluar di sekitar 1 juta gambar dan kemudian tumbuh pada tingkat beberapa puluh ribu per bulan. 3. akan ada semacam penandaan file di beberapa titik di masa depan, itu sebabnya saya ingin menyimpan semacam data identifikasi di db.
s.mihai
3

Saya terlibat dalam proyek yang menyimpan 8,4 juta gambar selama setahun untuk mendokumentasikan status berbagai perangkat. Gambar yang lebih baru diakses lebih sering, dan gambar yang lebih tua jarang dicari kecuali suatu kondisi ditemukan yang mendorong seseorang untuk menggali arsip.

Solusi saya, berdasarkan penggunaan ini, adalah secara bertahap meng-zip gambar menjadi file terkompresi. Gambar adalah JPG, masing-masing sekitar 20kB dan tidak banyak kompres, sehingga skema kompresi ZIP tidak ada. Hal ini dilakukan hanya untuk menggabungkan mereka menjadi satu entri sistem file yang sangat membantu NTFS dalam hal kecepatan ketika harus memindahkan mereka dari drive ke drive, atau melihat melalui daftar file.

Gambar yang lebih tua dari satu hari digabungkan menjadi zip "harian"; ritsleting lebih tua dari sebulan digabungkan ke dalam zip "bulanan" masing-masing; dan akhirnya apapun yang lebih dari setahun tidak lagi diperlukan dan akibatnya dihapus.

Sistem ini berfungsi dengan baik karena pengguna dapat menelusuri file (baik melalui sistem operasi atau sejumlah aplikasi klien) dan semuanya dinamai berdasarkan nama perangkat dan cap waktu. Umumnya pengguna mengetahui dua informasi ini dan dapat dengan cepat menemukan salah satu dari jutaan gambar.

Saya mengerti ini mungkin tidak terkait dengan detail khusus Anda, tetapi saya pikir saya akan membagikannya.

JYelton
sumber
2

Mungkin skema penamaan berdasarkan tanggal pembuatan - baik termasuk semua info dalam nama file atau (lebih baik untuk browsing nanti) membaginya dalam direktori. Saya dapat memikirkan hal-hal berikut, tergantung pada seberapa sering Anda menghasilkan gambar:

  • Beberapa gambar dihasilkan setiap hari: Year/Month/Day/Hour_Minute_Second.png
  • Pasangan sebulan: Year/Month/Day_Hour_Minute_Second.png

dll. Anda mengerti maksud saya ... =)

Tomas Aschan
sumber
mereka tidak terus menerus dihasilkan dari waktu ke waktu, sehingga beberapa folder akan menjadi gemuk dan lain-lain tinggal ... ramping :))
s.mihai
Ya, Anda jelas tidak harus membuat setiap folder, hanya karena Anda mengikuti skema ini. Anda bahkan dapat memiliki Year/Month/Day/Hour/Minute- memutuskan berapa tingkat folder yang Anda butuhkan tergantung pada seberapa sering gambar dihasilkan ketika tingkat tertinggi - dan kemudian jangan membuat folder yang akan dibiarkan kosong.
Tomas Aschan
2

Saya akan cenderung membuat struktur folder berbasis tanggal, misalnya \ year \ month \ day, dan menggunakan cap waktu untuk nama file. Jika perlu, cap waktu dapat memiliki komponen penghitung tambahan jika gambar harus dibuat begitu cepat sehingga mungkin ada lebih dari satu dalam milidetik. Dengan menggunakan urutan paling signifikan hingga paling tidak signifikan untuk penyortiran penamaan, pencarian dan pemeliharaan sangatlah mudah. mis. hhmmssmm [seq] .jpg

John Gardeniers
sumber
2

Apakah Anda mempertimbangkan pemulihan bencana?

Beberapa solusi yang diusulkan di sini akhirnya mengacaukan nama file (sehingga jika file fisik dipindahkan Anda akan kehilangan jejak file apa itu sebenarnya). Saya sarankan mempertahankan nama file fisik yang unik sehingga jika daftar utama lokasi file Anda rusak, Anda dapat membuat ulang dengan shell kecil, eh, powershell, skrip;)

Dari apa yang saya baca di sini sepertinya semua file ini akan disimpan pada satu sistem file. Pertimbangkan menyimpannya di banyak sistem file di banyak mesin. Jika Anda memiliki sumber daya, tentukan sistem penyimpanan setiap file pada dua mesin yang berbeda jika Anda kehilangan catu daya dan penggantiannya habis 2 hari.

Pertimbangkan jenis prosedur apa yang perlu Anda buat untuk memigrasi file antara mesin atau sistem file. Kemampuan untuk melakukan ini dengan sistem Anda adalah langsung dan online dapat menghemat banyak sakit kepala di jalan.

Anda dapat mempertimbangkan menggunakan GUID sebagai nama file fisik alih-alih nomor tambahan jika penghitung nomor tambahan Anda (kolom identitas basis data?) Menjadi kacau.

Jika sesuai, pertimbangkan untuk menggunakan CDN seperti Amazon S3.

Donald Byrd
sumber
2

Meskipun saya belum menyajikan gambar pada skala itu, saya sebelumnya telah menulis aplikasi galeri kecil untuk melayani ~ 25k gambar pada mesin 400MHz w. RAM 512 MB atau lebih. Beberapa pengalaman;

  • Hindari database relasional di semua biaya; sementara database, tidak diragukan lagi, pintar dalam menangani data, mereka tidak dirancang untuk penggunaan seperti itu (kami mendapat basis data kunci-nilai hierarki khusus untuk yang disebut sistem file ). Sementara saya tidak lebih dari firasat, saya berani bertaruh bahwa cache DB keluar dari jendela, jika Anda melemparkan gumpalan yang sangat besar padanya. Sementara perangkat keras saya yang tersedia berada di ujung kecil, tidak menyentuh DB sama sekali pada pencarian gambar memberi perintah kecepatan yang lebih baik.

  • Teliti bagaimana sistem file berperilaku; pada ext3 (atau apakah ext2 pada saat itu - tidak ingat), batas untuk dapat mencari sub-direktori dan file secara efisien adalah sekitar tanda 256; jadi hanya memiliki banyak file dan folder dalam folder yang diberikan. Sekali lagi, speedup yang terlihat. Meskipun saya tidak tahu tentang NTFS, hal-hal seperti XFS (yang menggunakan B-tree, sejauh yang saya ingat) sangat cepat, hanya karena mereka dapat melakukan pencarian dengan sangat cepat.

  • Mendistribusikan data secara merata; ketika saya bereksperimen dengan hal di atas, saya mencoba mendistribusikan data secara merata ke semua direktori (saya melakukan MD5 dari URL dan menggunakannya untuk direktori; /1a/2b/1a2b...f.jpg). Dengan begitu dibutuhkan waktu lebih lama untuk mencapai batas kinerja apa pun yang ada (dan cache sistem file tidak berlaku pada set data besar seperti itu). (Sebaliknya, Anda mungkin ingin melihat di mana batasnya lebih awal; kemudian Anda ingin membuang semuanya di direktori pertama yang tersedia.

Morten Siebuhr
sumber
2

Mungkin terlambat untuk pertandingan ini. Tetapi satu solusi (jika sesuai dengan kasus penggunaan Anda) bisa berupa hashing nama file. Ini adalah cara untuk membuat jalur file yang mudah direproduksi menggunakan nama file sambil juga membuat struktur direktori yang terdistribusi dengan baik. Misalnya, Anda dapat menggunakan byte dari kode nama file sebagai path:

String fileName = "cat.gif";
int hash = fileName.hashCode();
int mask = 255;
int firstDir = hash & mask;
int secondDir = (hash >> 8) & mask;

Ini akan menghasilkan jalan yang:

/172/029/cat.gif

Anda kemudian dapat menemukan cat.gifdalam struktur direktori dengan mereproduksi algoritma.

Menggunakan HEX sebagai nama direktori akan semudah mengonversi intnilai:

String path = new StringBuilder(File.separator)
        .append(String.format("%02x", firstDir))
        .append(File.separator)
        .append(String.format("%02x", secondDir)
        .toString();

Yang menghasilkan:

/AC/1D/cat.gif

Saya menulis artikel tentang ini beberapa tahun yang lalu dan baru-baru ini memindahkannya ke Medium. Ini memiliki beberapa rincian lebih lanjut dan beberapa kode sampel: Nama File Hashing: Membuat Struktur Direktori Hashed . Semoga ini membantu!

Michael Andrews
sumber
Kami menyimpan 1,8 miliar item menggunakan sesuatu yang serupa. Itu bekerja dengan baik. Gunakan hash yang cepat dan memiliki tingkat tabrakan yang rendah dan Anda siap.
CVVS
1

Jika mereka SEMUA tidak diperlukan segera dan Anda dapat membuatnya secara langsung dan ini adalah gambar kecil, mengapa tidak menerapkan memori LRU - atau disk-cache di atas generator gambar Anda?

Ini bisa menyelamatkan Anda dari penyimpanan dan menjaga gambar-gambar panas untuk dilayani dari mem?

Jé Queue
sumber
1

Saya baru saja menjalankan tes pada zfs karena saya suka zfs, dan saya memiliki partisi 500gig yang telah saya kompresi. Saya menulis sebuah skrip yang menghasilkan 50-100k file dan menempatkannya di direktori bersarang 1/2/3/4/5/6/7/8 (kedalaman 5-8 level) dan membiarkannya berjalan selama saya pikir 1 minggu. (Itu bukan skrip yang hebat.) Itu mengisi disk dan akhirnya memiliki sekitar 25 juta file. Akses ke salah satu file dengan jalur yang dikenal adalah instan. Mendaftarkan direktori apa pun dengan jalur yang dikenal adalah instan.

Namun, mendapatkan hitungan daftar file (melalui find) membutuhkan waktu 68 jam.

Saya juga menjalankan tes dengan meletakkan banyak file dalam satu direktori. Saya mendapatkan sekitar 3,7 juta file dalam satu direktori sebelum saya berhenti. Daftar direktori untuk mendapatkan hitungan butuh sekitar 5 menit. Menghapus semua file dalam direktori itu membutuhkan waktu 20 jam. Tetapi pencarian dan akses ke file apa pun instan.

Stu
sumber
1

Saya melihat orang lain menyebutkan database, tetapi tidak melihat hal itu di posting Anda. Bagaimanapun, pendapat saya tentang titik khusus ini adalah: tetap berpegang pada database atau sistem file. Jika Anda harus mencampur keduanya, berhati-hatilah. Segalanya menjadi lebih rumit. Tetapi Anda mungkin harus melakukannya. Menyimpan sejuta foto dalam database tidak terdengar ide terbaik.

Anda mungkin tertarik dengan spesifikasi berikut, kebanyakan kamera digital mengikutinya untuk mengelola penyimpanan file: https://en.wikipedia.org/wiki/Camera_Image_File_Format

Pada dasarnya, folder dibuat, seperti 000OLYMPUSdan foto ditambahkan ke folder itu (misalnya DSC0000.RAW). Ketika penghitung nama file mencapai DSC9999.RAWfolder baru dibuat ( 001OLYMPUS) dan gambar ditambahkan lagi, mengatur ulang penghitung, mungkin dengan awalan yang berbeda (mis P_0000.RAW. :) .

Atau Anda juga bisa membuat folder berdasarkan bagian nama file (sudah disebutkan beberapa kali). Misalnya, jika foto Anda dinamai IMG_A83743.JPG, simpan di IMG_\A8\3\IMG_A83743.JPG. Lebih rumit untuk diterapkan tetapi akan membuat file Anda lebih mudah ditemukan.

Bergantung pada sistem file (ini akan memerlukan beberapa riset), Anda mungkin bisa membuang semua gambar dalam satu folder, tetapi, menurut pengalaman saya, ini biasanya akan menyebabkan masalah kinerja.

Rolf
sumber
0

Anda mungkin ingin melihat Salam ZFS (sistem file, manajer volume dari Sun)


sumber
0

Cara bersih untuk menghasilkan path dari sejumlah besar adalah dengan mudah mengubahnya menjadi hex lalu membaginya!

misalnya 1099496034834> 0xFFFF1212>FF/FF/12/12

public string GeneratePath(long val)
{  
    string hex = val.ToString("X");
    hex=hex.PadLeft(10, '0');
    string path="";
    for(int i=0; i<hex.Length; i+=2 )
    {
        path += hex.Substring(i,2);
        if(i+2<hex.Length)
            path+="/";
    }
    return path;
}

Simpan dan muat:

public long Store(Stream doc)
{
   var newId = getNewId();
   var fullpath = GeneratePath(newId)
   // store into fullpath 
   return newId;
}

public Stream Load(long id)
{
   var fullpath = GeneratePath(newId)
   var stream = ... 
   return stream;
}

Kode sumber lengkap: https://github.com/acrobit/AcroFS

Ghominejad
sumber
-1

Sayangnya filesystem sangat buruk (kinerja dengan banyak file per direktori atau pohon direktori yang dalam, memeriksa waktu restart, keandalan) dalam mengelola banyak file kecil, sehingga solusi di atas yang melibatkan file ZIP adalah yang terbaik jika Anda ingin menggunakan filesystem.

Menggunakan manajer basis data sejauh ini merupakan pilihan terbaik; contoh sederhana seperti BDB atau GDBM misalnya; bahkan DBMS relatrional seperti MySQL akan lebih baik. Hanya orang-orang malas yang tidak memahami sistem file dan basis data (misalnya mereka yang menolak transaksi) cenderung menggunakan sistem file sebagai basis data (atau agak lebih jarang, sebaliknya).


sumber
-2

Bagaimana dengan database dengan tabel yang berisi ID dan BLOB untuk menyimpan gambar? Kemudian Anda dapat menambahkan tabel baru kapan pun Anda ingin mengaitkan lebih banyak elemen data dengan foto.

Jika Anda mengharapkan skala, mengapa tidak skala sekarang? Anda akan menghemat waktu baik IMO sekarang dan nanti. Terapkan layer database sekali, yang cukup mudah untuk memulai. Atau terapkan sesuatu dengan folder dan nama file dan bla bla bla, dan kemudian beralih ke hal lain saat Anda mulai meledakkan MAX_PATH.

jdmichal
sumber
5
Pernah ke sana, melakukan itu, memiliki bekas luka untuk membuktikannya. Basis data yang menyimpan gambar dalam jumlah besar hampir tidak dapat dipercaya, dan membutuhkan pemeliharaan yang sangat banyak. Jauh lebih baik untuk menyimpan mereka dalam sistem file kecuali Anda memiliki kebutuhan khusus yang hanya bisa dijawab oleh database (kita adalah pelacakan versi.)
Satanicpuppy
1
Dan ada banyak utilitas untuk menangani file dan sistem file, sedikit atau tidak ada yang berurusan dengan file dalam database.
Mark Ransom
2
Ya Tuhan. Tolong jangan gunakan database sebagai penyimpanan BLOB besar.
Neil N
Eek. Tidak tahu bahwa basis data (masih?) Memiliki banyak masalah dengan Gumpalan.
Bagaimana solusi buruk yang memiliki begitu banyak komentar masih memiliki +1? jangan tersinggung OP (saya melihatnya berasal dari SO) tetapi tombol downvote ada di sini karena suatu alasan!
Mark Henderson