Menyinkronkan struktur folder yang sangat besar

14

Kami memiliki struktur folder di intranet kami yang berisi sekitar 800.000 file yang dibagi menjadi sekitar 4.000 folder. Kami perlu menyinkronkan ini ke sekelompok kecil mesin di DMZ kami. Kedalaman struktur sangat dangkal (tidak pernah melebihi dua tingkat dalam).

Sebagian besar file tidak pernah berubah, setiap hari ada beberapa ribu file yang diperbarui dan 1-2 ribu file baru. Data tersebut adalah data pelaporan historis yang dikelola di mana data sumber telah dibersihkan (yaitu ini adalah laporan akhir yang datanya cukup lama yang kami arsipkan dan hapus). Sinkronisasi sekali per hari sudah cukup mengingat hal itu bisa terjadi dalam kerangka waktu yang masuk akal. Laporan dihasilkan dalam semalam, dan kami menyinkronkan hal pertama di pagi hari sebagai tugas yang dijadwalkan.

Tentunya karena sedikit file yang berubah secara teratur, kami dapat mengambil manfaat besar dari salinan tambahan. Kami telah mencoba Rsync, tetapi itu bisa memakan waktu delapan hingga dua belas jam hanya untuk menyelesaikan operasi "membangun daftar file". Sudah jelas bahwa kita dengan cepat melampaui kemampuan rsync (jangka waktu 12 jam terlalu lama).

Kami telah menggunakan alat lain yang disebut RepliWeb untuk menyinkronkan struktur, dan itu dapat melakukan transfer tambahan dalam waktu sekitar 45 menit. Namun sepertinya kami telah melampaui batasnya, ia sudah mulai melihat file muncul sebagai dihapus ketika mereka tidak (mungkin beberapa struktur memori internal telah habis, kami tidak yakin).

Adakah orang lain yang mengalami proyek sinkronisasi skala besar semacam ini? Apakah ada sesuatu yang dirancang untuk menangani struktur file besar seperti ini untuk sinkronisasi?

Perkasa
sumber
Sudahkah Anda mencoba membagi pekerjaan lebih dari beberapa contoh rsync berjalan pada saat yang sama? Saya tidak memiliki gambaran yang bagus tentang struktur direktori tetapi Anda dapat membaginya berdasarkan nama direktori atau nama file.
Kopling
Kami telah memikirkan hal itu, tetapi dengan struktur yang datar, sulit untuk menemukan garis pemisah yang baik untuk memisahkan pekerjaan. Ini rumit oleh fakta bahwa folder tersebut untuk sebagian besar bernama sangat mirip (ada konvensi penamaan yang membuat sebagian besar folder mulai dengan set awal yang sama dari 6 karakter).
Perkasa
Apakah Anda pernah menemukan solusi yang bagus, Dave? Saya sedang mempertimbangkan lsyncd untuk dir dengan 65535 sub-dirs, yang masing-masing dapat memiliki 65 ^ 16 file.
Mike Diehn
1
@ MikeDiehn Saya tidak pernah menemukan alat yang saya sangat senang di sini. Kami mendapat alat RepliWeb miliknya untuk memperbaiki bug tempat mereka melihat file sebagai penghapusan yang bukan, itu adalah struktur internal yang meluap. Saya meninggalkan pekerjaan itu bertahun-tahun yang lalu, saya berasumsi mereka masih menggunakannya. Untuk keperluan Anda, jika direktori Anda didistribusikan secara wajar, Anda bisa menggunakan sesuatu seperti solusi Ryan. Ia tidak akan melihat penghapusan tingkat atas, tetapi 65535 subdir menunjukkan kepada saya bahwa Anda mungkin tidak memilikinya.
MightyE

Jawaban:

9

Jika Anda dapat mempercayai cap waktu sistem berkas yang terakhir dimodifikasi, Anda dapat mempercepat dengan menggabungkan Rsync dengan utilitas 'find' UNIX / Linux. 'find' dapat menyusun daftar semua file yang menunjukkan waktu modifikasi terakhir dalam satu hari terakhir, dan kemudian pipa HANYA daftar file / direktori yang disingkat menjadi Rsync. Ini jauh lebih cepat daripada Rsync membandingkan metadata dari setiap file pada pengirim dengan server jauh.

Singkatnya, perintah berikut akan menjalankan Rsync ONLY pada daftar file dan direktori yang telah berubah dalam 24 jam terakhir: (Rsync TIDAK akan repot-repot memeriksa file / direktori lain.)

find /local/data/path/ -mindepth 1 -ctime -0 -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.

Jika Anda tidak terbiasa dengan perintah 'temukan', itu muncul melalui subtree direktori tertentu, mencari file dan / atau direktori yang memenuhi kriteria apa pun yang Anda tentukan. Sebagai contoh, perintah ini:

find . -name '\.svn' -type d -ctime -0 -print

akan mulai di direktori saat ini (".") dan berulang melalui semua sub-direktori, mencari:

  • direktori apa saja ("-type d"),
  • bernama ".svn" ("-name '.svn'"),
  • dengan metadata yang dimodifikasi dalam 24 jam terakhir ("-ctime -0").

Ini mencetak nama path lengkap ("-print") dari apa pun yang cocok dengan kriteria tersebut pada output standar. Opsi '-nama', '-jenis', dan '-waktu' disebut "tes", dan opsi '-cetak' disebut "tindakan". Halaman manual untuk 'find' memiliki daftar tes dan tindakan yang lengkap.

Jika Anda ingin menjadi benar-benar pintar, Anda dapat menggunakan tes 'find' command '-cnewer', alih-alih '-time' untuk membuat proses ini lebih toleran terhadap kesalahan dan fleksibel. '-cnewer' menguji apakah setiap file / direktori di dalam tree telah mengubah metadata-nya lebih baru daripada beberapa file referensi. Gunakan 'sentuh' untuk membuat file referensi NEXT run di awal setiap proses, tepat sebelum 'find ... | Perintah rsync ... 'dijalankan. Inilah implementasi dasarnya:

#!/bin/sh
curr_ref_file=`ls /var/run/last_rsync_run.*`
next_ref_file="/var/run/last_rsync_run.$RANDOM"
touch $next_ref_file
find /local/data/path/ -mindepth 1 -cnewer $curr_ref_file -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
rm -f $curr_ref_file

Script ini secara otomatis tahu kapan terakhir kali dijalankan, dan hanya mentransfer file yang dimodifikasi sejak terakhir kali dijalankan. Meskipun ini lebih rumit, ini melindungi Anda dari situasi di mana Anda mungkin telah melewatkan menjalankan pekerjaan selama lebih dari 24 jam, karena downtime atau kesalahan lainnya.

Ryan B. Lynch
sumber
Ini adalah solusi yang sangat cerdas! Saya pikir Anda bermaksud touch $next_ref_filepada akhirnya? Itu tidak meninggalkan kita tanpa kemampuan untuk mengatasi jalur yang dihapus (bahkan laporan arsip statis ini akhirnya menjadi cukup tua sehingga mereka diarsipkan dan dihapus). Itu mungkin bukan penghenti acara.
MightyE
Saya menemukan meskipun itu find . -ctime 0cukup lambat pada struktur direktori ini (masih menunggu untuk menyelesaikan untuk melaporkan waktunya). Itu sebenarnya membuat saya sedikit kecewa karena sepertinya ini mungkin operasi tingkat rendah yang mungkin menetapkan standar untuk tercepat yang bisa kita harapkan untuk diselesaikan pekerjaan ini. Ini mungkin kasus bahwa I / O disk adalah faktor pembatas di sini.
MightyE
Adapun scriptlet itu, ya, saya membuat kesalahan. Maksud saya jalankan 'touch' pada 'next_ref_file' (BUKAN 'curr_ref_file') tepat sebelum menjalankan 'find ... | perintah rsync ... '. (Saya akan memperbaiki jawaban saya.)
Ryan B. Lynch
3
Adapun perintah 'find' yang lambat: Apa filesystem yang Anda gunakan? Jika Anda menggunakan Ext3, Anda mungkin ingin mempertimbangkan dua tweak FS: 1) Jalankan 'tune2fs -O dir_index <DEVICE_NODE>' untuk mengaktifkan fitur 'dir_index' Ext3, untuk mempercepat akses ke dir dengan jumlah file yang besar. 2) Jalankan 'mount -o remount, noatime, nodiratime' untuk mematikan pembaruan waktu akses, yang mempercepat pembacaan, secara umum. 'dumpe2fs -h <DEVICE_NODE> | grep dir_index 'memberi tahu Anda jika' dir_index 'sudah diaktifkan (pada beberapa distro, itu adalah default), dan' mount | grep <DEVICE_NODE> 'memberi tahu Anda tentang pembaruan waktu akses.
Ryan B. Lynch
Sayangnya itu NTFS - Windows 2003 Server menggunakan Cygwin untuk perintah find. Saya akan mengingat opsi penyetelan (saran yang sangat baik) untuk ext3 jika kita pernah mengalami sesuatu yang serupa pada salah satu cluster Debian kami.
Perkasa
7

Coba serempak , itu secara khusus dirancang untuk menyelesaikan masalah ini dengan menjaga daftar perubahan (daftar file bangunan), secara lokal untuk setiap server, mempercepat waktu untuk menghitung delta, dan mengurangi jumlah yang dikirim melintasi kawat setelah itu.

Dave Cheney
sumber
Saya mencoba Unison. Sudah berjalan sekitar 2 jam sekarang pada tahap "Mencari perubahan", dan berdasarkan pada file yang sedang dikerjakannya, sepertinya sudah setengah jalan selesai (jadi mungkin total 4 jam sebelum transfer dimulai). Sepertinya akan lebih baik daripada rsync, tetapi masih di luar jendela operasional yang diinginkan.
MightyE
2
Pertama kali Anda membuat indeks di kedua sisi, waktu pembangunan kembali mirip dengan rsync karena harus hash setiap file. Setelah ini selesai, serentak menggunakan waktu terakhir yang dimodifikasi dari direktori untuk mengidentifikasi ketika file telah berubah, dan hanya perlu memindai file itu untuk perubahan.
Dave Cheney
Sayangnya saya adalah korban dari administrator Operasi yang terlalu bersemangat yang mengakhiri sesi saya sebelum katalog dibuat (kami membatasi jumlah login secara simultan ke server produksi). Saya kehilangan kemajuan yang dibuatnya dalam membangun katalog awal, jadi saya harus memulai dari awal lagi. Saya akan memberi tahu Anda bagaimana hasilnya.
MightyE
Dibutuhkan sekitar 2 jam sekarang karena katalog awal dibuat untuk memindai perubahan. Saya cukup terkejut berapa banyak RAM Unison digunakan untuk ini. Untuk koleksi file kami, server sumber menggunakan 635M, dan klien jarak jauh menggunakan 366M. Untuk menyinkronkan beberapa mesin dalam sebuah cluster akan menjadi jejak yang lumayan, terutama untuk server sumber!
Perkasa
1
Apakah Anda dapat menyusun data dengan cara yang memudahkan Anda mengidentifikasi data yang telah berubah baru-baru ini? Yaitu, menyimpannya dalam format tahun / bulan / hari / ...?
Dave Cheney
2

Jika Anda menggunakan tombol -z pada rsync, coba jalankan tanpanya. Untuk beberapa alasan saya telah melihat ini mempercepat bahkan enumerasi awal file.

Chris Thorpe
sumber
Kami telah mencoba dengan dan tanpa flag -z. Tampaknya tidak berdampak pada durasi eksekusi "building file list".
Perkasa
2

Mengambil -z dari perintah rsync yang tidak ada kompresi membuat "daftar file penerima" berjalan jauh lebih cepat dan kami harus mentransfer sekitar 500 GB. Sebelum butuh satu hari dengan saklar -z.

ryand32
sumber