Di Linux, eksekusi perintah yang selesai seperti cp
atau dd
tidak berarti bahwa data telah ditulis ke perangkat. Seseorang harus, misalnya, memanggil sync
, atau menjalankan fungsi "Safely Remove" atau "Eject" pada drive.
Apa filosofi di balik pendekatan semacam itu? Mengapa data tidak ditulis sekaligus? Apakah tidak ada bahaya bahwa penulisan akan gagal karena kesalahan I / O?
kernel
drivers
io
unix-philosophy
marmistrz
sumber
sumber
Jawaban:
Efisiensi (penggunaan karakteristik disk yang lebih baik) dan kinerja (memungkinkan aplikasi untuk melanjutkan segera setelah menulis).
Keuntungan utama adalah OS bebas untuk menyusun ulang dan menggabungkan operasi tulis yang berdekatan untuk meningkatkan penggunaan bandwidth mereka (lebih sedikit operasi dan lebih sedikit mencari). Hard disk berkinerja lebih baik ketika sejumlah kecil operasi besar diminta sementara aplikasi cenderung membutuhkan sejumlah besar operasi kecil sebagai gantinya. Optimalisasi lain yang jelas adalah OS juga dapat menghapus semua kecuali penulisan terakhir ketika blok yang sama ditulis beberapa kali dalam waktu singkat, atau bahkan menghapus beberapa penulisan bersama-sama jika file yang terpengaruh telah dihapus sementara itu.
Ini menulis asynchronous dilakukan setelah para
write
system call telah kembali. Ini adalah keuntungan kedua dan paling terlihat pengguna. Asynchronous menulis mempercepat aplikasi karena mereka bebas untuk melanjutkan pekerjaan mereka tanpa menunggu data untuk benar-benar ada di disk. Jenis buffering / caching yang sama juga diterapkan untuk operasi baca di mana baru-baru ini atau sering membaca blok disimpan dalam memori alih-alih dibaca lagi dari disk.Belum tentu. Itu tergantung pada sistem file yang digunakan dan redundansi di tempat. Kesalahan I / O mungkin tidak berbahaya jika data dapat disimpan di tempat lain. Sistem file modern seperti ZFS melakukan sendiri menyembuhkan blok disk yang buruk. Perhatikan juga bahwa kesalahan I / O tidak crash OS modern. Jika mereka terjadi selama akses data, mereka hanya dilaporkan ke aplikasi yang terkena dampak. Jika itu terjadi selama akses metadata struktural dan membahayakan sistem file, itu mungkin dibuat ulang hanya-baca atau dibuat tidak dapat diakses.
Ada juga sedikit risiko kehilangan data jika terjadi kerusakan OS, pemadaman listrik, atau kegagalan perangkat keras. Ini adalah alasan mengapa aplikasi yang harus 100% yakin data ada di disk (mis. Basis data / aplikasi keuangan) melakukan penulisan sinkron yang kurang efisien tetapi lebih aman. Untuk mengurangi dampak kinerja, banyak aplikasi masih menggunakan penulisan asinkron tetapi akhirnya menyinkronkannya ketika pengguna menyimpan secara eksplisit file (misalnya vim, pengolah kata.)
Di sisi lain, sebagian besar pengguna dan aplikasi tidak perlu atau tidak peduli dengan keamanan yang disediakan oleh penulisan sinkron. Jika ada gangguan atau pemadaman listrik, satu-satunya risiko adalah sering kehilangan paling buruk 30 detik terakhir data. Kecuali jika ada transaksi keuangan yang terlibat atau sesuatu yang serupa yang akan menyiratkan biaya yang jauh lebih besar dari 30 detik waktu mereka, keuntungan besar dalam kinerja (yang bukan ilusi tetapi sangat nyata) asinkron menulis memungkinkan sebagian besar mengungguli risiko.
Akhirnya, penulisan sinkron tidak cukup untuk melindungi data yang ditulis. Jika aplikasi Anda benar-benar harus memastikan data mereka tidak dapat hilang apa pun yang terjadi, replikasi data pada banyak disk dan pada beberapa lokasi geografis perlu dilakukan untuk mencegah bencana seperti kebakaran, banjir, dll.
sumber
Ini hanya memberikan ilusi kecepatan ke program yang tidak benar-benar harus menunggu sampai tulisan selesai. Pasang sistem file Anda dalam mode sinkronisasi (yang memberi Anda tulisan instan) dan lihat seberapa lambat semuanya.
Terkadang file hanya ada untuk sementara ... sebuah program melakukan sedikit pekerjaan dan menghapus file tepat setelah pekerjaan selesai. Jika Anda menunda penulisan itu, Anda mungkin tidak pernah menulisnya sejak awal.
Oh, tentu saja. Dalam kasus seperti itu, biasanya seluruh sistem file masuk ke mode read-only, dan semuanya mengerikan. Namun itu jarang terjadi, tidak ada gunanya merugi pada keunggulan kinerja secara umum.
sumber
Asynchronous, buffered I / O digunakan sebelum Linux dan bahkan sebelum Unix. Unix memilikinya, dan demikian pula semua cabang.
Inilah yang ditulis Ritchie dan Thompson dalam makalah CACM mereka The UNIX Time-Sharing System :
Dalam pertanyaan Anda, Anda juga menulis:
Ya, penulisan dapat gagal dan program mungkin tidak pernah mengetahuinya. Meskipun tidak pernah merupakan hal yang baik, efek dari ini dapat diminimalkan dalam kasus di mana kesalahan I / O menghasilkan kepanikan sistem (pada beberapa OS ini dapat dikonfigurasi - alih-alih panik, sistem dapat terus berjalan tetapi sistem file yang terpengaruh adalah dilepas atau dipasang hanya baca). Pengguna kemudian dapat diberi tahu bahwa data pada sistem file itu dicurigai. Dan disk drive dapat dipantau secara proaktif untuk melihat apakah daftar cacat yang tumbuh dengan cepat meningkat, yang merupakan indikasi bahwa drive gagal.
BSD menambahkan
fsync
panggilan sistem sehingga sebuah program dapat memastikan bahwa data file-nya telah sepenuhnya ditulis ke disk sebelum melanjutkan, dan sistem Unix berikutnya telah menyediakan opsi untuk melakukan penulisan sinkron. GNU dd memiliki opsiconv=fsync
untuk memastikan bahwa semua data telah ditulis sebelum perintah keluar. Sangat berguna saat menulis untuk memperlambat flash drive yang dapat dilepas, di mana data yang disangga dapat mengambil beberapa menit untuk menulis.Sumber lain dari file korupsi adalah sistem shutdown mendadak, misalnya dari kehilangan daya. Hampir semua sistem saat ini mendukung flag bersih / kotor di sistem file mereka. Bendera diatur untuk dibersihkan ketika tidak ada lagi data yang akan ditulis dan sistem file akan di-unmount, biasanya selama sistem mati atau dengan menelepon secara manual
umount
. Sistem biasanya akan berjalanfsck
saat reboot jika mereka mendeteksi bahwa sistem file tidak dimatikan dengan bersih.sumber
Banyak jawaban yang bagus, tetapi izinkan saya menambahkan satu hal lain ... Ingatlah bahwa Unix adalah sistem multi-proses dan multi-pengguna, sehingga berpotensi banyak pengguna akan mencoba melakukan operasi file (terutama menulis) di (hampir) waktu yang sama. Dengan hard-disk lama yang lambat - mungkin dipasang di jaringan - ini tidak hanya akan memakan waktu (yang pada dasarnya program-program akan terkunci dan pengguna harus menunggu), tetapi menyebabkan banyak perpindahan read / write-head dari disk bolak-balik.
Jadi alih-alih, file yang menunggu untuk ditulis disimpan dalam memori untuk sementara waktu, dan disortir setelah di mana mereka akan berakhir pada disk ... dan ketika buffer penuh - atau daemon disk-sinkronisasi telah menunggu diperlukan jumlah detik (saya pikir biasanya sekitar 30 detik) - seluruh buffer dituliskan ke disk "dalam urutan", dengan kepala-tulis hanya harus melakukan satu gerakan menyapu berkelanjutan, menulis file ke disk sebagai ia pergi ... bukannya melompat ke mana-mana.
Dengan cepat menggunakan cakram cepat saat ini - belum lagi perangkat solid-state - keuntungannya jauh lebih sedikit ... terutama pada sistem linux rumah, di mana hanya ada satu pengguna yang bekerja pada satu waktu, dan hanya dengan beberapa program.
Pokoknya, kombinasi antisipasi membaca dengan membaca (ke cache / buffer) lebih dari yang diminta - dan mengurutkan data menunggu untuk ditulis, sehingga dapat ditulis dalam "satu gerakan" - sebenarnya ide yang sangat bagus di waktu, terutama pada sistem dengan banyak membaca dan menulis oleh banyak pengguna.
sumber
Ini tidak spesifik untuk Linux, dan itu disebut cache halaman (yang Linux lakukan dengan cukup baik). Lihat juga http://linuxatemyram.com/ ; jadi jika file ditulis, maka baca lagi beberapa detik kemudian, sangat sering tidak diperlukan I / O disk.
Keuntungan utama adalah bahwa pada banyak sistem, ada banyak RAM, dan beberapa di antaranya dapat digunakan sebagai cache oleh kernel. Jadi beberapa operasi file dapat mengambil keuntungan dari caching ini. Juga, waktu disk I / O jauh lebih lambat (biasanya ribuan kali untuk SDD, dan hampir satu juta kali lebih lambat untuk hard disk mekanis) daripada RAM.
Kode aplikasi dapat memberikan petunjuk tentang caching ini: lihat misalnya posix_fadvise (2) & madvise (2)
sumber
Spinning platters lebih lambat dari RAM. Kami menggunakan caching membaca / menulis untuk 'menyembunyikan' fakta ini.
Hal yang berguna tentang menulis IO adalah bahwa ia tidak memerlukan disk IO untuk segera terjadi - tidak seperti pembacaan, di mana Anda tidak dapat mengembalikan data ke pengguna hingga pembacaan selesai pada disk.
Karenanya menulis beroperasi di bawah batasan waktu lunak - selama throughput berkelanjutan kami tidak melebihi disk kami, kami dapat menyembunyikan banyak hukuman kinerja dalam cache tulis.
Dan kita perlu menulis cache - disk berputar sangat lambat. Tetapi untuk melakukan jenis RAID modern memiliki penalti yang signifikan untuk operasi.
A RAID 6 misalnya, untuk menyelesaikan satu penulisan IO harus:
Jadi setiap penulisan sebenarnya 6 operasi IO - dan terutama ketika Anda memiliki disk lambat seperti drive SATA besar, ini menjadi sangat mahal.
Tapi ada solusi mudah yang bagus - menulis penggabungan. Jika Anda bisa membuat tulisan 'full stripe' di buffer, Anda tidak perlu membaca paritas dari disk Anda - Anda dapat menghitungnya berdasarkan apa yang ada di memori.
Sangat diinginkan untuk melakukan ini, karena Anda tidak perlu menulis amplifikasi lagi. Memang, Anda bisa berakhir dengan penalti tulis lebih rendah dari RAID 1 + 0.
Mempertimbangkan:
RAID 6, 8 + 2 - 10 spindle.
8 blok data berturut-turut untuk ditulis - hitung paritas dalam cache, dan tulis satu blok untuk setiap disk. 10 menulis per 8, berarti penalti tulis 1,25. 10 disk RAID 1 + 0 masih memiliki penalti tulis 2 (karena Anda harus menulis untuk setiap submirror). Jadi dalam skenario ini, Anda benar-benar dapat membuat RAID 6 berkinerja lebih baik daripada RAID1 + 0. Dalam penggunaan di dunia nyata, Anda mendapatkan sedikit lebih banyak profil IO campuran.
Jadi caching tulis membuat perbedaan besar terhadap persepsi kinerja set RAID - Anda bisa menulis dengan kecepatan RAM dan memiliki penalti tulis yang rendah - meningkatkan throughput berkelanjutan Anda jika melakukannya.
Dan jika tidak, Anda menderita kinerja SATA yang lambat, tetapi kalikan dengan 6 dan tambahkan beberapa pertengkaran di sana. SATA RAID-6 10-way tanpa cache tulis akan sedikit lebih cepat daripada drive tunggal tanpa RAID ... tetapi tidak terlalu banyak.
Anda mengambil risiko meskipun - seperti yang Anda perhatikan - kehilangan daya berarti kehilangan data. Anda dapat mengurangi ini dengan siklus flushing cache, baterai mendukung cache Anda, atau menggunakan SSD atau cache non-volatile lainnya.
sumber
Tidak ada jawaban lain yang menyebutkan alokasi tertunda . XFS, ext4, BTRFS, dan ZFS semuanya menggunakannya. XFS telah menggunakannya sejak sebelum ext4 ada, jadi saya akan menggunakannya sebagai contoh:
XFS bahkan tidak memutuskan di mana harus menyimpan data sampai penulisan. Alokasi yang tertunda memberikan pengalokasi jauh lebih banyak informasi untuk mendasarkan keputusannya. Ketika sebuah file pertama kali ditulis, tidak ada cara untuk mengetahui apakah itu akan menjadi file 4k atau file 1G-dan-masih-tumbuh. Jika ada 10G ruang kosong yang berdekatan di suatu tempat, meletakkan file 4k di awal tidak ada gunanya. Menempatkan file besar di awal ruang kosong besar mengurangi fragmentasi.
sumber
Semua jawaban lain di sini paling tidak sebagian besar benar untuk kasus normal, dan saya akan merekomendasikan membaca salah satu dari mereka sebelum saya, tetapi Anda sebutkan dd dan dd memiliki kasus penggunaan umum yang mungkin tidak melibatkan caching tulis. Caching tulis terutama diterapkan pada tingkat filesystem. Perangkat mentah biasanya tidak melakukan caching tulis (beberapa driver perangkat seperti raid atau lvm adalah bola lilin lainnya). Karena dd sering digunakan dengan perangkat raw block, ia memberikan opsi-opsi bs dan yang terkait untuk memungkinkan penulisan besar untuk kinerja yang lebih baik pada perangkat mentah. Ini tidak berguna ketika kedua titik akhir adalah file biasa (meskipun penulisan besar menggunakan lebih sedikit panggilan sistem dalam kasus ini). Tempat umum lain di mana ini sangat terlihat adalah dengan paket mtools yang merupakan implementasi sistem file lemak userspace. menggunakan mtools dengan floppy drive selalu terasa sangat lamban karena alatnya sepenuhnya sinkron dan floppy drive sangat lambat. Memasang floppy dan menggunakan sistem file kernel lemak jauh lebih responsif kecuali untuk umount yang sinkron (dan sangat penting untuk mencegah kehilangan data, terutama untuk perangkat yang dapat dilepas seperti disket). Hanya ada beberapa program lain yang saya ketahui secara teratur digunakan dengan perangkat mentah seperti basis data yang dikonfigurasikan secara khusus (yang mengimplementasikan caching penulisan mereka sendiri), tar, dan perangkat khusus dan alat sistem file seperti chdsk, mkfs dan mt. Memasang floppy dan menggunakan sistem file kernel lemak jauh lebih responsif kecuali untuk umount yang sinkron (dan sangat penting untuk mencegah kehilangan data, terutama untuk perangkat yang dapat dilepas seperti disket). Hanya ada beberapa program lain yang saya ketahui secara teratur digunakan dengan perangkat mentah seperti basis data yang dikonfigurasikan secara khusus (yang mengimplementasikan caching penulisan mereka sendiri), tar, dan perangkat khusus dan alat sistem file seperti chdsk, mkfs dan mt. Memasang floppy dan menggunakan sistem file kernel lemak jauh lebih responsif kecuali untuk umount yang sinkron (dan sangat penting untuk mencegah kehilangan data, terutama untuk perangkat yang dapat dilepas seperti disket). Hanya ada beberapa program lain yang saya ketahui secara teratur digunakan dengan perangkat mentah seperti basis data yang dikonfigurasikan secara khusus (yang mengimplementasikan caching penulisan mereka sendiri), tar, dan perangkat khusus dan alat sistem file seperti chdsk, mkfs dan mt.
sumber
O_DIRECT
jika Anda ingin memotong cache.dd oflag=direct
. IIRC, beberapa kesatuan standar untuk mengarahkan I / O pada perangkat blok. (Dan memerlukan pembacaan / penulisan blok yang disejajarkan, yang Linux tidak lakukan karena hanya menulis pagecache.)Filosofi ini tidak aman secara default.
Ada dua strategi yang masuk akal dan jelas yang mungkin: menulis flush ke disk segera atau menunda penulisan. UNIX secara historis memilih yang terakhir. Jadi dapatkan keamanan, Anda perlu menelepon
fsync
setelah itu.Namun, Anda dapat menentukan keamanan dimuka dengan memasang perangkat dengan opsi
sync
, atau per file dengan membukanyaO_SYNC
.Ingatlah bahwa UNIX dirancang untuk para pakar komputer. "Aman secara default" bukan merupakan pertimbangan. Keamanan berarti I / O lebih lambat, dan sistem-sistem awal itu benar-benar memperlambat I / O sehingga membuat tingkat harga menjadi tinggi. Sayangnya, baik UNIX maupun Linux tidak beralih ke safe-be-default, meskipun ini adalah perubahan yang tidak melanggar.
sumber
Ini memperdagangkan sejumlah kecil keandalan untuk peningkatan besar dalam throughput.
Misalkan, misalnya, program kompresi video. Dengan keterlambatan menulis ("tulis kembali"):
Melawan
Versi kedua muncul dua kali lebih cepat karena dapat menggunakan CPU dan disk pada saat yang sama, sedangkan versi pertama selalu menunggu satu atau yang lain.
Secara umum Anda ingin menulis kembali untuk operasi streaming dan operasi file massal, dan write-through untuk database dan aplikasi seperti database.
sumber
Dalam banyak aplikasi, perangkat penyimpanan akan sesekali sibuk membaca data. Jika suatu sistem selalu dapat menunda penulisan hingga waktu ketika perangkat penyimpanan tidak sibuk membaca data, maka dari sudut pandang aplikasi menulis tidak akan membutuhkan waktu untuk menyelesaikan. Satu-satunya situasi di mana menulis tidak akan instan adalah ketika:
Isi buffer menulis hingga tidak ada lagi permintaan penulisan yang ditangguhkan yang dapat diterima sampai penulisan benar-benar selesai.
Hal ini diperlukan untuk mematikan atau menghapus perangkat yang sedang menunggu penulisan.
Aplikasi secara khusus meminta konfirmasi bahwa penulisan sebenarnya telah selesai.
Memang, itu hanya karena persyaratan di atas yang menulis harus benar-benar terjadi sama sekali. Di sisi lain, umumnya tidak ada alasan untuk tidak melakukan penulisan yang tertunda pada saat-saat ketika suatu perangkat akan menganggur, sehingga banyak sistem yang melakukannya.
sumber
Ada juga ini:
Tulis "Hai, Joe Moe"
lebih cepat dari:
Tulis "Hai,"
Tulis "Joe"
Tulis "Moe"
Dan juga:
Tulis "Hai, apa kabar?"
lebih cepat dari:
Tulis "Hai, ada apa?"
Hapus
Tulis itu "Howdy, apa kabar?"
Hapus yang
Tulis "Hai, apa kabar?"
Lebih baik modifikasi dan agregasi terjadi pada RAM daripada pada disk. Disk Batching menulis membebaskan pengembang aplikasi dari masalah seperti itu.
sumber