Artikel ini terutamanya membincangkan sistem fail maya. Seni bina sistem fail Linux termasuk lapisan abstraksi antara sistem fail tertentu (seperti Ext2, Ext3, XFS, dll.) dan aplikasi, iaitu Sistem Fail Maya (VFS). VFS membenarkan aplikasi berkomunikasi dengan pelbagai jenis sistem fail tanpa mengetahui butiran sistem fail asas. Dengan VFS, pelaksanaan sistem fail boleh diasingkan dan dipisahkan daripada aplikasi, dengan itu meningkatkan fleksibiliti dan kebolehselenggaraan sistem. VFS juga membenarkan kernel Linux menyokong pelbagai jenis sistem fail dan menyediakan antara muka bersatu untuk aplikasi mengakses sistem fail. Di bawah rangka kerja VFS, sistem fail yang berbeza boleh berkomunikasi dengan kernel dengan melaksanakan antara muka operasi sistem fail standard
Gambar
Rajah di atas menunjukkan bahawa pusat seni bina ini ialah sistem fail maya VFS. VFS menyediakan rangka kerja sistem fail, dan sistem fail tempatan boleh dilaksanakan berdasarkan VFS. Ia terutamanya menyelesaikan tugas-tugas berikut:
1) Sebagai lapisan abstraksi, VFS menyediakan antara muka bersatu (baca, tulis, chmod, dll.) untuk lapisan aplikasi.
2) Beberapa fungsi awam dilaksanakan dalam VFS, seperti cache inode dan cache halaman.
3) Menyeragamkan antara muka yang harus dilaksanakan oleh sistem fail tertentu.
Berdasarkan tetapan di atas, sistem fail khusus lain hanya perlu mengikut konvensyen VFS, melaksanakan antara muka dan logik dalaman yang sepadan, dan mendaftarkannya dalam sistem. Selepas pengguna memformat dan memasang sistem fail, dia boleh menggunakan sumber cakera keras untuk melaksanakan operasi berdasarkan sistem fail.
Dalam sistem pengendalian Linux, selepas memformat cakera, anda perlu menggunakan arahan pelekap untuk melekapkannya ke direktori dalam pepohon direktori sistem Direktori ini dipanggil titik pelekap. Selepas pemasangan selesai, kita boleh menggunakan ruang cakera keras yang diformatkan berdasarkan sistem fail ini. Dalam sistem pengendalian Linux, titik lekap boleh menjadi hampir mana-mana direktori, tetapi untuk penyeragaman, titik lekap biasanya merupakan subdirektori di bawah direktori mnt.
Berikut menunjukkan struktur direktori yang agak kompleks. Dalam struktur direktori ini, direktori akar terletak pada cakera keras sda, dan terdapat tiga subdirektori di bawah direktori mnt, iaitu ext4, xfs dan nfs, yang masing-masing memasang sistem fail Ext4 (dibina pada cakera keras sdb) dan Sistem fail XFS (dibina pada pemacu keras sdc) dan sistem fail NFS (dipasang melalui rangkaian).
Gambar
Hubungan antara berbilang sistem fail dalam pepohon direktori diwakili oleh beberapa struktur data dalam kernel. Apabila memasang sistem fail, hubungan antara sistem fail akan diwujudkan dan API sistem fail tertentu akan didaftarkan. Apabila mod pengguna memanggil API untuk membuka fail, ia akan mencari API sistem fail yang sepadan dan mengaitkannya dengan struktur berkaitan fail (seperti fail dan inod, dsb.).
Perihalan di atas agak skema, dan anda mungkin masih berasa keliru. Tetapi jangan risau, kami akan memperkenalkan VFS dan cara menyokong berbilang sistem fail dengan lebih terperinci seterusnya berdasarkan kod.
VFS dalam Linux tidak wujud dari awal Versi Linux yang paling awal dikeluarkan tidak mempunyai VFS. Selain itu, VFS tidak dicipta dalam Linux Ia pertama kali dibangunkan oleh Sun pada tahun 1985 dalam SunOS2.0nya. Tujuan utama membangunkan VFS adalah untuk menyesuaikan sistem fail tempatan dan sistem fail NFS.
VFS melaksanakan abstraksi sistem fail tertentu melalui satu set API awam dan struktur data. Apabila pengguna memanggil API sistem fail yang disediakan oleh sistem pengendalian, fungsi yang dilaksanakan oleh kernel VFS dipanggil melalui gangguan lembut. Jadual berikut menunjukkan surat-menyurat antara beberapa API fail dan fungsi kernel VFS.
API Mod Pengguna |
Fungsi kernel |
Arahan |
terbuka |
do_sys_open |
Buka fail |
tutup |
ksys_close |
Tutup fail |
baca |
ksys_read/vfs_read |
Baca data |
tulis |
ksys_write/vfs_write |
Tulis data |
lekapkan |
do_mount |
Lekapkan sistem fail |
Ia boleh dilihat daripada jadual di atas bahawa setiap API mod pengguna mempunyai fungsi mod kernel yang sepadan. Apabila aplikasi memanggil API sistem fail, fungsi yang sepadan dalam keadaan kernel akan dicetuskan. Apa yang disenaraikan di sini hanyalah subset yang agak kecil bagi API sistem fail, dan tujuannya adalah untuk menggambarkan hubungan antara API dan VFS. Jika anda ingin mengetahui tentang API lain, sila baca sendiri kod sumber kernel dan saya tidak akan menerangkan butiran dalam artikel ini.
Untuk memberikan pemahaman persepsi kepada semua orang tentang hubungan antara VFS dan sistem fail tertentu, bahagian ini mengambil API penulisan Ext2 sebagai contoh untuk menunjukkan hubungan panggilan daripada API kepada fungsi VFS dan kemudian kepada fungsi sistem fail Ext2. Seperti yang ditunjukkan dalam rajah di bawah, penulisan fungsi API mencetuskan fungsi ksys_write kernel melalui gangguan lembut Selepas beberapa proses, fungsi ini akhirnya akan memanggil fungsi ext2_file_write_iter sistem fail Ext2 melalui penuding fungsi (file->f_op. ->wirte_iter).
Gambar
Dalam rajah di atas, pintu masuk ke proses kernel ialah fungsi ksys_write Seperti yang dapat dilihat dari kod pelaksanaan, tujuan utama di sini adalah untuk mendapatkan fd, dan kemudian memanggil vfs_write dengan fail ahli dalam fd sebagai parameter. . Antaranya, fd ialah struktur, dan formatnya adalah seperti yang ditunjukkan dalam rajah di bawah Ahli fail adalah struktur data yang agak teras. Seperti yang dapat dilihat dari rajah di atas, ia adalah melalui kandungan ahli ini bahawa fungsi sistem fail Ext2 dipindahkan.
Gambar
Nampak sangat mudah, VFS hanya perlu memanggil penunjuk fungsi yang didaftarkan oleh sistem fail tertentu. Tetapi terdapat masalah yang tidak dapat diselesaikan di sini Bilakah penunjuk fungsi dalam VFS didaftarkan?
Penunjuk fungsi Ext2 dimulakan apabila fail dibuka (untuk butiran, sila rujuk Bahagian 3.1.2.2 "Orang Dalam Teknologi Sistem Fail"). Seperti yang kita semua tahu, program mod pengguna mengembalikan deskriptor fail apabila ia membuka fail, tetapi fail struktur yang mewakili fail dalam kernel sepadan dengannya. Ahli yang lebih penting dalam struktur ini termasuk f_inode, f_ops dan f_mapping, seperti yang ditunjukkan dalam rajah di bawah.
Gambar
Dalam rajah di atas, f_inode ialah nod inod yang sepadan dengan fail. f_ops ialah koleksi penunjuk fungsi untuk operasi fail dalam sistem fail tertentu (seperti Ext2 Ia dimulakan apabila fail dibuka). Melalui koleksi petunjuk fungsi inilah VFS melaksanakan akses kepada sistem fail tertentu.
Di atas melibatkan satu lagi konsep VFS iaitu inode. Dalam Linux, inode ialah singkatan nod indeks, yang mewakili objek tertentu (seperti fail atau direktori) dalam sistem fail. Terdapat struktur data bernama inode dalam VFS, yang merupakan abstraksi inode sistem fail tertentu. Sebagai contoh, dalam sistem fail Ext2, ia ditakrifkan secara khusus sebagai ext2_inode_info, tetapi dalam XFS, ia diwakili oleh struktur data xfs_inode. Selain itu, struktur data inode sistem fail tertentu secara intrinsik berkaitan dengan inode VFS Anda boleh membaca kod itu sendiri.
Dalam rajah seni bina, kita melihat bahawa terdapat beberapa pelaksanaan cache dalam VFS, termasuk cache halaman, cache inode, cache gigi, dll. Cache inode dan cache gigi dilaksanakan dengan cara yang sama dan agak mudah. Oleh itu, artikel ini mula-mula memperkenalkan kedua-dua cache ini.
Malah, kedua-dua cache ini dilaksanakan melalui jadual cincang Semua orang tahu konsep jadual cincang, jadi saya tidak akan menerangkan secara terperinci dalam artikel ini. Ambil cache inode sebagai contoh Rajah berikut menunjukkan proses pemulaannya Melalui parameter ihash_entry, anda boleh melihat bahawa saiznya adalah dinamik (saiznya berkaitan dengan memori sistem. Semakin besar cache inode apabila memori sistem berada. baca).
Gambar
Memandangkan inod dan dentri kerap diakses semasa mengakses fail, caching fail boleh mengelakkan kehilangan prestasi yang disebabkan oleh membaca data daripada cakera keras.
Cache halaman VFS (Cache) digunakan terutamanya untuk meningkatkan prestasi sistem fail. Teknologi caching merujuk kepada teknologi yang menyimpan sebahagian daripada data dan metadata sistem fail dalam ingatan untuk meningkatkan prestasi sistem fail. Memandangkan kependaman akses memori ialah seratus ribu daripada kependaman capaian cakera keras mekanikal (seperti yang ditunjukkan dalam rajah di bawah, dengan daftar sebagai unit asas 1s), penggunaan teknologi caching boleh meningkatkan prestasi fail dengan ketara. sistem.
Gambar
Cache meningkatkan prestasi sistem fail melalui tiga aspek pengoptimuman IO, iaitu data panas, pra-bacaan dan penggabungan IO. Banyak aplikasi akan mempunyai data panas Contohnya, apabila pengarang mengedit dokumen, blok data semasa dan blok data berdekatan adalah data panas. Atau apabila artikel popular muncul, kandungan artikel ini adalah data panas. Prestasi peranti storan asas selalunya lebih baik untuk membaca dan menulis blok besar Baca ke hadapan bermaksud membaca blok besar data daripada peranti pendasar terlebih dahulu dan menyimpannya dalam cache, supaya permintaan aplikasi boleh dijawab melalui cache. Penggabungan IO adalah untuk permintaan tulis Permintaan tulis tidak diteruskan ke peranti bahagian belakang serta-merta, tetapi dicache dan dibahagikan kepada sebahagian besar IO sebelum menulis.
Memandangkan kapasiti memori jauh lebih kecil daripada kapasiti cakera keras, cache halaman tidak boleh cache semua data cakera keras. Dengan cara ini, hanya subset data sistem fail boleh disimpan dalam cache. Apabila pengguna terus menulis data, mereka akan menghadapi situasi di mana cache penuh Pada masa ini, ia melibatkan masalah bagaimana untuk mengepam data cache ke cakera dan kemudian menyimpan data baru.
Proses mengepam cache ke cakera dan menyimpan data baharu dipanggil penggantian cache. Terdapat banyak algoritma untuk penggantian cache, setiap satu digunakan untuk menyelesaikan masalah yang berbeza. Seterusnya kami memperkenalkan beberapa algoritma penggantian cache biasa.
Algoritma LRU, nama penuh LRU ialah Least Recently Used, yang bermaksud paling kurang digunakan baru-baru ini. Algoritma ini berdasarkan prinsip lokaliti temporal, iaitu, jika sekeping data telah digunakan baru-baru ini, terdapat kebarangkalian tinggi bahawa ia akan digunakan semula pada masa hadapan. Oleh itu, algoritma akan mengeluarkan cache yang tidak digunakan baru-baru ini.
Algoritma LRU biasanya dilaksanakan menggunakan senarai terpaut Cache yang baru digunakan akan dimasukkan ke dalam kepala jadual, manakala data yang tidak kerap digunakan akan dihimpit perlahan-lahan ke hujung senarai terpaut. Untuk memahami prinsip LRU dengan lebih jelas, kami akan menggambarkannya dengan rajah berikut.
Gambar
Dalam contoh ini, kami mengambil hits penuh sebagai contoh. Andaikan bahawa terdapat 6 blok data dalam cache, seperti yang ditunjukkan dalam baris pertama angka tersebut. Anggapkan bahawa akses pertama (boleh dibaca atau ditulis) ialah blok data No. 3. Oleh kerana ia telah diakses, ia dipindahkan ke kepala senarai terpaut.
Akses kedua ialah blok data No. 4. Mengikut prinsip yang sama, blok data ini juga dialihkan ke kepala senarai terpaut. Butiran ditunjukkan dalam baris 2 rajah di atas.
Secara analogi, selepas 4 pusingan capaian, data yang diakses telah dialihkan ke hadapan, manakala blok data yang tidak diakses (seperti 1 dan 2) perlahan-lahan dipicit ke belakang senarai terpaut. Ini menunjukkan pada tahap tertentu kemungkinan kedua-dua blok data ini diakses kemudian adalah agak kecil.
Jika terdapat hit penuh, tiada penggantian cache. Situasi sebenar ialah cache selalunya tidak mencukupi, dan data di dalamnya perlu dikeluarkan (bergantung pada keadaan, sama ada ia perlu disiram ke cakera) untuk menyimpan data baharu. Pada masa ini, algoritma LRU sangat berguna Algoritma ini menggunakan blok data ekor untuk menyimpan data baharu dan kemudian meletakkannya di kepala senarai terpaut, seperti yang ditunjukkan dalam rajah di bawah. Jika terdapat data kotor dalam blok data ini, ia perlu dibuang ke cakera, jika tidak, ia boleh dikeluarkan terus.
Gambar
Prinsip dan pelaksanaan algoritma LRU agak mudah, tetapi ia mempunyai pelbagai kegunaan. Walau bagaimanapun, algoritma LRU mempunyai kekurangan, iaitu, apabila sejumlah besar data berterusan secara tiba-tiba, semua blok cache akan diganti, menyebabkan semua statistik penggunaan cache sebelumnya menjadi tidak sah Fenomena ini dipanggil pencemaran cache. Untuk menyelesaikan masalah pencemaran cache, terdapat banyak algoritma LRU yang dipertingkatkan, antaranya yang lebih biasa ialah LRU-K, 2Q dan LIRS.
Algoritma LFU, nama penuh LFU ialah Least Frequently Used, bermakna ia paling kurang kerap digunakan baru-baru ini. Algoritma ini memutuskan blok cache yang akan dikeluarkan berdasarkan kekerapan akses data. Blok cache dengan kekerapan akses paling rendah akan dikeluarkan terlebih dahulu.
Seperti yang ditunjukkan di bawah ialah gambarajah skematik algoritma LFU. Baris 1 ialah keadaan asal, dan nombor dalam kotak mewakili bilangan kali blok cache telah diakses. Penambahan data baharu dan penghapusan blok cache dilakukan dari ekor. Andaikan bahawa sekeping data tertentu (kotak putus-putus) telah diakses 4 kali, dan bilangan akses telah berubah daripada 12 kepada 16, jadi ia perlu dialihkan ke lokasi baharu, iaitu rupa baris 2 dalam rajah. .
Gambar
Buku ini menggunakan senarai terpaut sebagai contoh untuk menggambarkan prinsip LFU untuk memudahkan pemahaman, tetapi ia tidak akan pernah dilaksanakan menggunakan senarai terpaut semasa pelaksanaan projek. Oleh kerana lokasi baharu perlu dicari apabila bilangan akses kepada blok data berubah, operasi carian senarai terpaut sangat memakan masa. Untuk mencapai carian pantas, pokok carian biasanya digunakan.
LFU juga mempunyai kelemahannya Jika blok data telah diakses dengan kerap dalam tempoh masa tertentu lama dahulu dan tidak lagi diakses pada masa hadapan, data akan kekal dalam cache. Walau bagaimanapun, oleh kerana data tidak akan diakses lagi, kapasiti berkesan cache dikurangkan. Dalam erti kata lain, algoritma LFU tidak mengambil kira situasi terkini.
Artikel ini terutamanya memperkenalkan dua algoritma penggantian yang sangat asas, LRU dan LFU. Sebagai tambahan kepada algoritma di atas, terdapat banyak algoritma penggantian, kebanyakannya berdasarkan teori LRU dan LFU, seperti 2Q, MQ, LRFU, TinyLFU dan ARC, dll. Disebabkan oleh keterbatasan ruang, buku ini tidak akan menerangkan secara terperinci Anda boleh membaca sendiri kertas yang berkaitan.
Prabacaan data juga mempunyai algoritma tertentu Algoritma prabacaan membaca data dari cakera ke cache terlebih dahulu dengan mengenal pasti corak IO. Dengan cara ini, apabila aplikasi membaca data, ia boleh membaca data terus dari cache, dengan itu meningkatkan prestasi membaca data dengan ketara.
Perkara yang paling penting dalam algoritma prabacaan ialah keadaan pencetus, iaitu, dalam keadaan apa operasi prabacaan dimulakan. Biasanya terdapat dua situasi yang mencetuskan baca ke hadapan: satu ialah apabila terdapat permintaan baca berturut-turut daripada berbilang alamat, yang mencetuskan operasi baca ke hadapan; yang lain ialah apabila aplikasi mengakses cache dengan tanda baca ke hadapan. Di sini, cache tanda prabaca ialah tanda yang dibuat pada halaman cache apabila operasi prabaca selesai Apabila aplikasi membaca cache dengan tanda ini, prabaca seterusnya akan dicetuskan, dengan itu mengetepikan pengenalan. daripada mod IO.
Gambar
Untuk menerangkan logik prabacaan dengan lebih jelas, kami memperkenalkan keseluruhan proses melalui gambar di atas. Apabila sistem fail menyedari bahawa mod IO memerlukan pra-bacaan, ia akan membaca bahagian tambahan kandungan (dipanggil pra-bacaan segerak), seperti yang ditunjukkan dalam masa 1 (baris pertama). Pada masa yang sama, untuk data baca ke hadapan segerak, sistem fail akan menandakan salah satu blok. Tujuan tanda ini adalah untuk mencetuskan prabaca seterusnya seawal mungkin sebelum akhir cache.
Pada titik kedua dalam masa, apabila aplikasi terus membaca data, kerana blok cache yang ditanda dibaca, prabaca seterusnya dicetuskan pada masa yang sama. Pada masa ini, data akan dibaca dari cakera dalam satu langkah, dan anda boleh melihat dari angka bahawa cache meningkat.
Pada titik 3 dan 4 seterusnya, aplikasi boleh membaca data terus dari cache. Memandangkan tiada blok cache yang ditanda telah dibaca, bacaan hadapan seterusnya tidak akan dicetuskan. Pada titik masa 5, kerana terdapat tanda prabaca, proses prabaca akan dicetuskan semula.
Dapat dilihat daripada analisis di atas bahawa disebabkan ciri prabacaan, data dibaca ke dalam cache terlebih dahulu. Aplikasi boleh membaca data terus dari cache tanpa mengakses cakera, jadi prestasi capaian keseluruhan akan bertambah baik.
Atas ialah kandungan terperinci Analisis ringkas tentang seni bina sistem fail Linux (Sistem Fail).. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!