Buat Linux menulis ke sistem file jaringan bersamaan dengan pembacaan disk lokal

17

Ringkasan

Bagaimana Anda dapat mengkonfigurasi Linux untuk membaca dari disk / sistem file lokal dan menulis ke jaringan berbagi pada saat yang sama, yang bertentangan dengan membaca saat tidak ada data yang melewati jaringan, kemudian mengirimkan data melalui jaringan saat disk lokal diam?

Jauh lebih cepat untuk membaca dan menulis pada saat yang sama daripada hanya melakukan satu operasi dan kemudian yang lainnya secara bergantian.

Detail

Saya memindahkan sejumlah besar data dari disk lokal di mesin Linux ke perangkat NAS.

Saya menggunakan rsyncpada dasarnya menyalin /srv/datake /mnt/nas, yang merupakan CIFS gunung.

Itu dimulai dengan baik, membaca pada 100MB / detik dan menulis ke NAS pada 100MB / detik (batas jaringan gigabit), dengan membaca dan menulis terjadi secara bersamaan.

Namun sekarang, beberapa jam kemudian, saya menemukan bahwa itu membaca dari disk lokal, lalu menghentikan pembacaan saat ia menulis ke NAS, kemudian ketika tidak ada lagi data untuk ditulis ke NAS, itu kembali membaca dari disk. lagi. Jaringan idle saat disk sedang dibaca, dan disk idle saat jaringan sedang digunakan.

Tidak perlu dikatakan, membaca 200MB kemudian menulis 200MB membutuhkan waktu lebih lama daripada membaca dan menulis 200MB pada saat yang sama.

Bagaimana saya bisa mengkonfigurasi kernel sehingga tetap pada perilaku membaca dan menulis sebelumnya pada waktu yang sama, daripada bergantian antara membaca dan menulis, hanya melakukan satu operasi pada satu waktu?

Beberapa pengamatan: Ketika disk lokal membaca pada 100 + MB / detik semuanya tampaknya terjadi secara paralel dengan baik-baik saja, tetapi begitu disk melambat (tampaknya hanya 20MB / detik sekarang karena beberapa alasan) saat itulah baca / tulis ini Peralihan tampaknya terjadi.

Saya juga dapat menjalankan syncsecara manual setiap beberapa detik untuk membuat penulisan terjadi secara paralel dengan membaca (meskipun jelas pada kecepatan berkurang) namun menempatkan syncdalam satu whileputaran sehingga berjalan setiap lima detik sepertinya bukan solusi yang tepat ...

Kernel tampaknya men-cache sekitar 1GB data dan kemudian menuliskannya melalui jaringan secepat mungkin - yang baik-baik saja - Saya hanya tidak mengerti mengapa hard disk harus berhenti dibaca saat data sedang dikirim keluar melalui jaringan.

Malvine
sumber
1
Kebanyakan alat unix sama sekali tidak dioptimalkan untuk bandwidth dalam hal ini, bukan rsync, bahkan cp sederhana. Mereka adalah aplikasi single-threaded menggunakan pemblokiran IO.
peterh
1
Di suatu tempat sekitar 100 MB / s juga apa yang dapat Anda lihat pada HDD rotasi 7200 rpm umum modern dalam beban kerja murni berurutan. Itu turun setelah Anda mulai mencari, seperti untuk memperbarui metadata atau jika sistem file terfragmentasi, karena Anda kemudian menjadi terikat IOPS.
CVn
dapatkah Anda menginstal rsync pada NAS?
Jasen

Jawaban:

27

Setelah beberapa penyelidikan lebih lanjut, sepertinya masalah ini kurang terkait dengan kernel dan lebih banyak tentang bagaimana rsyncdan CIFS berinteraksi.

Sejauh yang saya bisa tahu, apa yang terjadi adalah ketika rsyncmenutup file tujuan, CIFS (dan mungkin semua sistem file jaringan) memastikan file tersebut benar-benar memerah dan ditulis ke disk jarak jauh sebelum closesyscall kembali. Ini untuk memastikan aplikasi apa pun yang setelah operasi tutup selesai dengan sukses, file telah sepenuhnya disimpan dan tidak ada risiko kesalahan lebih lanjut yang dapat menyebabkan kehilangan data.

Jika ini tidak dilakukan, maka mungkin untuk aplikasi untuk menutup file, keluar berpikir operasi save berhasil, kemudian (mungkin karena masalah jaringan) data tidak dapat ditulis setelah semua, tetapi pada saat itu sudah terlambat bagi aplikasi untuk melakukan apa pun tentangnya, seperti menanyakan kepada pengguna apakah mereka ingin menyimpan file di tempat lain.

Persyaratan ini berarti bahwa setiap kali rsyncselesai menyalin file, seluruh buffer disk harus dikosongkan melalui jaringan sebelum rsyncdiizinkan untuk melanjutkan membaca file berikutnya.

Solusinya adalah memasang saham CIFS dengan opsi cache=noneyang menonaktifkan fitur ini, dan menyebabkan semua I / O langsung menuju ke server. Ini menghilangkan masalah dan memungkinkan membaca dan menulis untuk dieksekusi secara paralel, namun kelemahan dari solusi ini adalah bahwa kinerjanya agak lebih rendah. Dalam kasus saya, kecepatan transfer jaringan turun dari 110MB / detik ke 80MB / detik.

Ini mungkin berarti bahwa jika Anda menyalin file besar, kinerja mungkin lebih baik dengan perilaku baca / tulis bergantian. Dengan banyak file yang lebih kecil, menonaktifkan cache akan menghasilkan lebih sedikit cache cache setiap kali file ditutup sehingga kinerja dapat meningkat di sana.

Tampaknya rsyncperlu opsi untuk menutup pegangan file-nya di utas lain, sehingga dapat mulai membaca file berikutnya sementara yang terakhir masih memerah.

EDIT: Saya telah mengkonfirmasi bahwa cache=nonepasti membantu ketika mentransfer banyak file kecil (membawanya dari 10MB / detik hingga 80MB / detik) tetapi ketika mentransfer file besar (1GB +) cache=nonemenjatuhkan transfer dari 110MB / detik ke 80MB / detik yang sama. Ini menunjukkan bahwa transfer lambat dari banyak file kecil kurang tentang mencari disk sumber, dan lebih banyak tentang memiliki begitu banyak cache flush dari semua file kecil.

Malvine
sumber
2
Itu masalah yang sangat menarik, dan terima kasih sudah memposting penjelasannya. rsynctidak membaca file di utas yang berbeda (sebenarnya, proses yang berbeda) karena itu dirancang sehingga satu salinan rsyncberjalan di setiap sisi jaringan, meskipun dalam kasus Anda kedua salinan berada di sisi yang sama (dan sistem file menyembunyikan fakta bahwa ada jaringan). Saya kira itu tidak membantu, karena proses pembaca sangat cepat mengisi pipa sementara proses penulis memblokir pada a close(). rsyncakan berkinerja lebih baik jika Anda menggunakan rsynckabel, bukan CIFS.
Celada
1
Saya akan membayangkan bahwa solusi lain adalah Anda tidak dapat berjalan rsyncdi NAS akan digunakan rsyncmelalui jaringan (seperti rsync -a files localhost:/dest/path) sementara entah bagaimana secara artifisial memperkenalkan buffer besar (seperti, multple megabita, setidaknya) ke dalam koneksi jaringan. Tidak yakin seperti apa peretasan terbaik untuk melakukan itu.
Celada
@Celada: Terima kasih! Ya saya membayangkan menjalankan rsyncpada kotak NAS itu sendiri akan mengatasi masalah ini juga. Agak sedikit lebih rumit (izin NAS aneh, harus membuang symlink, dll.) Tetapi jika saya memiliki sedikit lebih banyak data untuk menyalin, itu akan bernilai investasi waktu untuk melakukan itu saya pikir.
Malvineous
2
Mungkin tidak terkait dengan kasus Anda: Saya memiliki masalah yang sama beberapa tahun yang lalu menulis output dump(8)ke NAS yang dipasang di NFS. Pada saat itu saya mendiagnosis masalah sebagai memaksimalkan CPU pada NAS, karena efek gabungan dari server NFS dan firewall yang berjalan pada NAS (kotak tidak berakar, dan firewall tidak dapat dinonaktifkan sepenuhnya dari antarmuka web). Masalahnya hilang ketika kami mengganti NAS dengan PC lama. FWIW.
Satō Katsura
@SatoKatsura: Pasti kemungkinan untuk perangkat NAS yang lebih tua, meskipun dalam kasus itu saya bayangkan Anda akan melihat transfer keseluruhan yang lebih lambat daripada yang meledak seperti ini? NAS saya adalah Atom dual-core (~ 2GHz) yang duduk di sekitar 30% penggunaan CPU ketika memaksimalkan NIC satu gigabit tanpa bingkai jumbo sehingga harus ok di sana.
Malvineous