Lebih cepat rsync dari direktori besar yang tidak diubah

13

Kami menggunakan rsync ke server cadangan.

Sayangnya jaringan ke beberapa server lambat.

Butuh rsync hingga lima menit untuk mendeteksi, bahwa tidak ada yang berubah di direktori besar. Pohon direktori besar ini mengandung banyak file kecil (sekitar 80 ribu file).

Saya kira klien rsync mengirim data untuk masing-masing file 80k.

Karena jaringan lambat, saya ingin menghindari mengirim informasi 80k kali tentang setiap file.

Apakah ada cara untuk memberitahu rsync untuk membuat hash-sum dari pohon direktori?

Dengan cara ini klien rsync hanya akan mengirim beberapa byte untuk pohon direktori besar.

Memperbarui

Hingga kini strategi saya adalah menggunakan rsync. Tetapi jika alat yang berbeda lebih cocok di sini, saya dapat beralih. Keduanya (server dan klien) berada di bawah kendali saya.

Pembaruan2

Ada 80 ribu file dalam satu pohon direktori . Setiap direktori tunggal tidak memiliki lebih dari 2k file atau sub-direktori

Pembaruan3

Detail tentang kelambatan jaringan:

time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list
real    0m2.645s

Ukuran file tmp / daftar: 2MByte

time scp einswp:/tmp/list tmp/
real    0m2.821s

Kesimpulan: scp memiliki kecepatan yang sama (tidak mengejutkan)

time scp einswp:tmp/100MB tmp/
real    1m24.049s

Kecepatan: 1.2MB / s

guettli
sumber
1
Anda mungkin membaca di zsync. Saya belum menggunakannya sendiri, tetapi dari apa yang saya baca, itu pra-merender metadata di sisi server dan mungkin hanya mempercepat transfer dalam kasus Anda. Mungkin layak untuk diuji. Di luar itu, satu-satunya solusi yang saya ketahui adalah sinkronisasi tingkat blok waktu nyata yang hadir dengan beberapa solusi san / nas.
Aaron

Jawaban:

36

Beberapa poin yang tidak terkait:

80K adalah banyak file.

80.000 file dalam satu direktori? Tidak ada sistem operasi atau aplikasi yang menangani situasi itu dengan sangat baik secara default. Anda baru saja menyadari masalah ini dengan rsync.

Periksa versi rsync Anda

Rsync modern menangani direktori besar jauh lebih baik daripada sebelumnya. Pastikan Anda menggunakan versi terbaru.

Bahkan rsync lama menangani direktori besar dengan cukup baik melalui tautan latensi tinggi ... tapi file 80k tidak besar ... besar sekali!

Yang mengatakan, penggunaan memori rsync berbanding lurus dengan jumlah file dalam pohon. Direktori besar membutuhkan RAM dalam jumlah besar. Kelambatan mungkin karena kurangnya RAM di kedua sisi. Lakukan uji coba sambil menonton penggunaan memori. Linux menggunakan RAM sisa sebagai cache disk, jadi jika Anda kehabisan RAM, ada lebih sedikit caching disk. Jika Anda kehabisan RAM dan sistem mulai menggunakan swap, kinerjanya akan sangat buruk.

Pastikan --checksum tidak digunakan

--checksum(atau -c) mengharuskan membaca setiap dan setiap blok dari setiap file. Anda mungkin dapat bertahan dengan perilaku default hanya dengan membaca waktu modifikasi (disimpan dalam inode).

Bagi pekerjaan menjadi beberapa kelompok kecil.

Ada beberapa proyek seperti Gigasync yang akan "Memotong beban kerja dengan menggunakan perl untuk recurse pohon direktori, membangun daftar file yang lebih kecil untuk ditransfer dengan rsync."

Pemindaian direktori tambahan akan menjadi jumlah besar overhead, tapi mungkin itu akan menjadi kemenangan bersih.

Default OS tidak dibuat untuk situasi ini.

Jika Anda menggunakan Linux / FreeBSD / etc dengan semua defaultnya, kinerja akan mengerikan untuk semua aplikasi Anda. Default mengasumsikan direktori yang lebih kecil agar tidak membuang RAM pada cache yang terlalu besar.

Tune sistem file Anda untuk menangani direktori besar dengan lebih baik: Apakah ukuran folder besar memperlambat kinerja IO?

Lihatlah "namei cache"

Sistem operasi mirip BSD memiliki cache yang mempercepat pencarian nama ke inode ("namei" cache "). Ada cache namei untuk setiap direktori. Jika terlalu kecil, itu adalah penghalang lebih dari optimasi. Karena rsync melakukan lstat () pada setiap file, inode sedang diakses untuk setiap satu dari file 80k. Itu mungkin meniup cache Anda. Meneliti bagaimana mengatur kinerja direktori file pada sistem Anda.

Pertimbangkan sistem file yang berbeda

XFS dirancang untuk menangani direktori yang lebih besar. Lihat Filesystem sejumlah besar file dalam satu direktori

Mungkin 5 menit adalah yang terbaik yang bisa Anda lakukan.

Pertimbangkan menghitung berapa banyak blok disk yang sedang dibaca, dan hitung seberapa cepat Anda seharusnya mengharapkan perangkat keras dapat membaca banyak blok itu.

Mungkin harapan Anda terlalu tinggi. Pertimbangkan berapa banyak blok disk yang harus dibaca untuk melakukan rsync tanpa file yang diubah: setiap server harus membaca direktori dan membaca satu inode per file. Mari kita asumsikan tidak ada yang di-cache karena, well, 80 ribu file mungkin telah menghancurkan cache Anda. Katakanlah itu 80k blok untuk menjaga matematika sederhana. Itu sekitar 40 juta data, yang seharusnya bisa dibaca dalam beberapa detik. Namun jika perlu ada pencarian disk antara setiap blok, itu bisa memakan waktu lebih lama.

Jadi, Anda perlu membaca sekitar 80.000 blok disk. Seberapa cepat hard drive Anda dapat melakukannya? Menimbang bahwa ini adalah I / O acak, bukan bacaan linear panjang, 5 menit mungkin cukup bagus. Itu 1 / (80000/600), atau disk membaca setiap 7,5ms. Apakah itu cepat atau lambat untuk hard drive Anda? Tergantung modelnya.

Tolak ukur terhadap sesuatu yang serupa

Cara lain untuk memikirkannya adalah ini. Jika tidak ada file yang berubah, ls -Llrlakukan aktivitas disk dalam jumlah yang sama tetapi tidak pernah membaca data file apa pun (hanya metadata). Waktu yang ls -Llrdiperlukan untuk berlari adalah batas atas Anda.

  • Apakah rsync (tanpa file berubah) secara signifikan lebih lambat daripada ls -Llr? Maka opsi yang Anda gunakan untuk rsync dapat ditingkatkan. Mungkin -cdiaktifkan atau flag lain yang membaca lebih dari sekadar direktori dan metadata (data inode).

  • Apakah rsync (tanpa file berubah) hampir secepat ls -Llr? Kemudian Anda telah menyetel rsync sebaik mungkin. Anda harus menyetel OS, menambah RAM, mendapatkan drive yang lebih cepat, mengubah sistem file, dll.

Bicaralah dengan devs Anda

File 80k hanya desain yang buruk. Sangat sedikit sistem file dan alat sistem yang menangani direktori besar dengan sangat baik. Jika nama file abcdefg.txt, pertimbangkan untuk menyimpannya di abdc / abcdefg.txt (perhatikan pengulangannya). Ini memecah direktori menjadi lebih kecil, tetapi tidak memerlukan perubahan besar pada kode.

Juga .... pertimbangkan untuk menggunakan basis data. Jika Anda memiliki 80 ribu file dalam suatu direktori, mungkin pengembang Anda mengatasi kenyataan bahwa apa yang sebenarnya mereka inginkan adalah database. MariaDB atau MySQL atau PostgreSQL akan menjadi pilihan yang jauh lebih baik untuk menyimpan sejumlah besar data.

Hei, ada apa dengan 5 menit?

Terakhir, apakah 5 menit benar-benar buruk? Jika Anda menjalankan cadangan ini sekali sehari, 5 menit bukanlah waktu yang banyak. Ya, saya suka kecepatan. Namun jika 5 menit "cukup baik" untuk pelanggan Anda, maka itu cukup baik untuk Anda. Jika Anda tidak memiliki SLA tertulis, bagaimana dengan diskusi informal dengan pengguna Anda untuk mengetahui seberapa cepat mereka mengharapkan pencadangan.

Saya berasumsi Anda tidak mengajukan pertanyaan ini jika tidak ada kebutuhan untuk meningkatkan kinerja. Namun, jika pelanggan Anda senang dengan 5 menit, nyatakan kemenangan dan beralih ke proyek lain yang membutuhkan upaya Anda.

Pembaruan: Setelah beberapa diskusi, kami menentukan bahwa bottleneck adalah jaringan. Saya akan merekomendasikan 2 hal sebelum saya menyerah :-).

  • Cobalah untuk memeras lebih banyak bandwidth dari pipa dengan kompresi. Namun kompresi membutuhkan lebih banyak CPU, jadi jika CPU Anda kelebihan beban, itu dapat membuat kinerja lebih buruk. Coba rsync dengan dan tanpa -z, dan konfigurasikan ssh Anda dengan dan tanpa kompresi. Atur waktu semua 4 kombinasi untuk melihat apakah ada di antaranya yang berperforma lebih baik daripada yang lain.
  • Tonton lalu lintas jaringan untuk melihat apakah ada jeda. Jika ada jeda, Anda dapat menemukan apa yang menyebabkannya dan mengoptimalkannya. Jika rsync selalu mengirim, maka Anda benar-benar berada di batas Anda. Pilihan Anda adalah:
    • jaringan yang lebih cepat
    • sesuatu selain rsync
    • pindahkan sumber dan tujuan lebih dekat bersama. Jika Anda tidak bisa melakukan itu, bisakah Anda rsync ke mesin lokal kemudian rsync ke tujuan sebenarnya? Mungkin ada manfaat untuk melakukan ini jika sistem harus turun selama rsync awal.
TomOnTime
sumber
80K adalah banyak file .: Ada 80k file di satu pohon direktori . Setiap direktori tunggal tidak memiliki lebih dari 2k file / subdirektori.
guettli
Periksa versi rsync Anda: selesai, Pastikan --checksum tidak sedang digunakan: selesai. Bagi pekerjaan menjadi beberapa kelompok: Terima kasih, saya akan melihat gigasync. Default OS tidak dibuat untuk situasi ini: selesai (hambatannya adalah jaringan bukan OS). Lihatlah "namei cache": selesai (ini bersih, bukan OS). Pertimbangkan sistem file yang berbeda: sekali lagi bersih, bukan OS. Mungkin 5 menit adalah yang terbaik yang dapat Anda lakukan. Saya pikir itu bisa menjadi jauh lebih cepat. Bicaralah dengan devs Anda (gunakan DB): Ini akan menjadi perubahan besar. Mungkin sistem file dengan dukungan cadangan yang lebih baik akan menyelesaikannya.
guettli
File 2k per direktori jauh lebih baik. terima kasih atas pembaruannya. Anda tidak menyebutkan bahwa jaringan lambat. Apakah bandwidth rendah, latensi tinggi, atau keduanya? rsync biasanya berkinerja baik pada tautan latensi tinggi (ini dikembangkan oleh seseorang yang sedang mengerjakan gelar PhD dari Australia saat menangani komputer di AS). Coba lakukan itu "ls -lLR" lebih dari ssh dan waktu berapa lama untuk mengirimkan hasilnya. "waktu ssh remotehost 'cd / dest && ls -lLR'> / tmp / list". Pastikan / tmp / list dibuat pada host lokal.
TomOnTime
ya jaringannya lambat. Ini sangat menyebalkan.
guettli
Seberapa lambat? Jika Anda menggunakan "scp" untuk menyalin file 100M, berapa lama? Juga, apa output dari "time ssh remotehost 'cd / dest && ls -lL'> / tmp / list"?
TomOnTime
2

Tidak, itu tidak mungkin dengan rsync dan itu akan sangat tidak efisien dalam hal lain:

Biasanya, rsynchanya membandingkan tanggal modifikasi file dan ukuran file. Pendekatan Anda akan memaksanya untuk membaca dan memeriksa konten semua file dua kali (pada sistem lokal dan jarak jauh) untuk menemukan direktori yang diubah.

Sven
sumber
1
AFAIK rsync memeriksa waktu dan ukuran. Jika keduanya cocok, file tidak ditransfer lagi (setidaknya dalam pengaturan default). Akan cukup untuk mengirim hash dari tuple (nama file, ukuran, mtime). Tidak perlu checksum konten.
guettli
Ya, Anda benar, tetapi bagaimanapun, rsynctidak melakukan ini.
Sven
2

Untuk sinkronisasi sejumlah besar file (di mana sedikit telah berubah), ada baiknya juga mengatur noatimepartisi sumber dan tujuan. Ini menghemat waktu akses penulisan ke disk untuk setiap file yang tidak diubah.

Andy Beverley
sumber
Ya, opsi noatime masuk akal. Kami menggunakannya sejak beberapa tahun. Saya kira alternatif untuk rsync diperlukan.
guettli
2

Anda juga dapat mencoba lsyncd, yang akan melakukan rsync hanya ketika perubahan terdeteksi pada sistem file dan hanya subdirektori yang berubah. Saya telah menggunakannya untuk direktori dengan hingga dua juta file di server yang layak.

Juanga Covas
sumber