Kalau disuruh menyebutkan dua hal yang suka membuat “gemas” dalam mengajari pengguna Linux di tempat kerja saya, mungkin jawabannya dua-duanya berhubungan dengan rsync.

Yang pertama, mereka tidak kunjung menggunakan rsync dalam mentransfer file. Meskipun telah berulang kali diajari dan dianjurkan untuk memilih rsync, mereka kembali lagi ke cara-cara lama yang mereka tahu, seperti ftp atau scp atau bahkan wget (dengan terlebih dahulu menaruh file yang ingin ditransfer ke direktori public_html/ agar bisa ditransfer menggunakan webserver). Padahal cara-cara ini kalah unggul dibandingkan rsync karena lebih lambat, lebih boros bandwidth, dan tidak aman (biasanya file-file rahasia yang ditransfer lewat webserver tidak dilindungi password).

Yang kedua, dan lebih membuat gemas, mereka menggunakan rsync tapi sama sekali tidak memanfaatkan kelebihan yang ditawarkan oleh rsync. Mereka memperlakukan rsync seperti halnya scp atau wget biasa. Misalnya, alih-alih langsung meng-rsync 2 buah tree, mereka membuat tarball dari tree sumber dulu (.tar.gz) dan kadang bahkan men-split-nya dulu kecil-kecil, baru meng-rsync potongan-potongan ini ke host tujuan. Duh!

Tapi setelah dipikir-pikir, memang rsync adalah sebuah tool yang ampuh tapi sekaligus menyeramkan dan asing. Menyeramkan karena, saking fleksibelnya, tak kurang dari 100 opsi command line yang tersedia. Lalu ada jebakan dalam akhiran garis miring yang perlu dimengerti benar-benar agar tidak membingungkan. Atau penggunaan umum yang harus digabungkan dengan ssh sehingga mungkin agak menyulitkan. Dan terakhir, asing karena tidak seperti HTTP atau FTP, tool seperti ini tidak dikenal secara meluas oleh pengguna DOS/Windows (walaupun rsync kini tersedia pula di berbagai OS). Itu sebabnya mungkin mereka agak enggan berurusan dengan tool yang satu ini.

Artikel ini mencoba memperkenalkan rsync dan sedikit mempromosikan kelebihan-kelebihan dan fitur-fiturnya yang mudah-mudahan akan menarik pembaca untuk lebih banyak menggunakan rsync dalam pekerjaan sehari-hari.

Untuk apa rsync?

Rsync adalah tool untuk transfer dan sinkronisasi file atau tree (struktur direktori dan file) secara satu arah, baik transfer lokal (di sistem yang sama) maupun remote (jaringan/internet). Fungsi rsync mirip/identik dengan tool-tool ini: cp, mv, scp, FTP client. Rsync biasanya digabungkan dengan SSH sebagai metode transpor remotenya, walaupun dapat juga disetup untuk menjadi daemon sehingga tidak membutuhkan SSH. Dalam kasus-kasus tertentu rsync juga dapat digunakan menggantikan HTTP client (seperti wget).

Apa keunggulan rsync?

Irit bandwidth. Jika di sisi penerima, file yang ingin dikirimkan sudah ada, tapi belum tentu sama (misalnya ukurannya lebih kecil/besar atau terdapat perbedaan karena versinya lebih lama), maka rsync dapat melakukan serangkaian pengecekan perbandingan checksum terhadap blok-blok dalam file di kedua sisi, untuk meminimalisasi jumlah data yang harus ditransfer. Algoritma ini disebut algoritma rsync. Bahkan sebetulnya rsync bermula dari sebuah paper yang menjelaskan algoritma ini.

Jadi, misalnya Anda memiliki 2 buah versi file berukuran kurang lebih 100MB di dua tempat, dengan rsync Anda mungkin Anda hanya membutuhkan transfer data sebesar 50MB, 10MB, atau bahkan di bawah 1MB untuk menyamakan kedua buah versi file ini, bergantung pada seberapa mirip kedua file tersebut sebelumnya.

Atau, misalnya Anda sedang mentransfer file besar lalu putus di tengah jalan. Anda dapat jalankan kembali rsync dan rsync akan melanjutkan kembali transfer dari posisi putus dan memastikan hasil akhirnya nanti sama.

Cepat. Rsync cepat salah satunya karena algoritma rsync yang disebutkan di atas. Selain itu rsync dapat melakukan kompresi data saat transfer. Dibandingkan FTP pun rsync lebih cepat karena dapat melakukan pipelining, sementara transfer menggunakan FTP boros koneksi TCP/IP untuk setiap file yang ditransfer. Ini akan semakin kentara untuk tree berisi file kecil-kecil yang jumlahnya banyak (misalnya file-file website yang umumnya berisi banyak file HTML dan gambar), di mana rsync dapat beberapa kali hingga belasan kali lebih cepat dari FTP.

Fleksibel. Rsync tidak hanya bisa mentransfer file tunggal, tapi juga direktori dan tree secara rekursif. Anda bisa memilih untuk menghapus file/direktori yang sudah tidak ada dari sisi pengirim tapi masih ada di sisi penerima. Anda bisa memilih untuk mensinkronisasi juga metadata file seperti permission, kepemilikan, tanggal, ACL, dll. Rsync dapat menangani link simbolik, hardlink, device, dll. Dan ada banyak opsi lainnya, termasuk yang sering juga dijumpai di tool lain seperti tar, cp, dll.

Sintaks dasar

Pada umumnya sintaks-sintaks berikut ini yang paling sering digunakan. Untuk transfer lokal ke lokal:

$ rsync -av -P PATHSUMBER PATHTUJUAN

Untuk transfer lokal ke remote:

$ rsync -e ssh -av -P -z PATHSUMBER USER@HOST:PATHTUJUAN

Untuk transfer remote ke lokal, cukup kebalikan perintah sebelumnya:

$ rsync -e ssh -av -P -z USER@HOST:PATHSUMBER PATHTUJUAN

Opsi -a (archive) adalah untuk mensinkronkan segala sesuatu, termasuk file/direktori secara rekursif dan metadata (seperti tanggal, kepemilikan, permission) dan file-file spesial seperti link simbolik. Umumnya ini yang kita mau, tapi dalam kasus-kasus tertentu di mana Anda tidak ingin rekursif atau tidak ingin mensinkronkan salah satu dari tanggal/kepemilikan/dll, opsi -a dapat dihilangkan dan/atau diganti dengan opsi-opsi lain seperti -r, -g, -o,

Opsi -v (verbose) membuat rsync memperlihatkan ke layar nama-nama file yang sedang ditransfer. Opsi -P membuat rsync lebih verbose lagi, yaitu menampilkan juga progres/persentasi saat sebuah file sedang ditransfer. Jika kita menggunakan rsync dalam skrip noninteraktif, bisa jadi output yang dihasilkan terlalu banyak. Maka dalam kasus tersebut kita dapat menghilangkan opsi -v dan -P.

Opsi -z (compress) membuat rsync mengkompresi data yang ditransfer. Ini menghemat bandwidth. Untuk transfer remote, gunakanlah selalu opsi ini, kecuali jika Anda berada di intranet yang amat cepat bahkan lebih cepat dari bandwidth harddisk (mis: di lingkungan gigabit ethernet).

Akhiran garis miring

Poin berikut ini perlu benar-benar dipahami oleh pengguna rsync karena seringkali menjebak dan membuat bingung. Tidak seperti shell Unix yang pengampun, rsync membedakan keberadaan garis miring penutup dalam spesifikasi path.

Keberadaan garis miring di akhir path sumber berarti menghindari pembentukan level direktori tambahan. Contoh:

$ rsync -av /home/steven/mirrors/debian /backup/

maka hasilnya adalah /backup/debian karena path sumber tidak diakhiri garis miring. Tapi jika kita menambahkan garis miring:

$ rsync -av /home/steven/mirrors/debian/ /backup/

maka isi dari direktori debian-lah yang akan tersalin ke /backup/ (kemungkinan ini bukan hal yang Anda inginkan, karena direktori /backup/ mungkin saja berisi hal-hal lain). Jika Anda ingin mengganti nama debian di path tujuan, maka sintaks berikut ini yang benar:

$ rsync -av /home/steven/mirrors/debian/ /backup/mirror-debian

Sebagai salah satu patokan yang bisa dipakai, jika Anda ingin mengganti nama direktori di tujuan, gunakan akhiran garis miring. Jika tidak, sebaiknya tidak usah gunakan.

Beberapa pertanyaan umum dari pemula

Bagaimana jika transfer putus di tengah-tengah? Tidak masalah. Justru inilah manfaat utama rsync. Rsync akan meneruskan proses sinkronisasi dari titik terakhir sebelum putus. Bahkan Anda dapat sengaja menghentikan dulu perintah rsync yang sedang berjalan (mis: dengan menekan Ctrl-C di shell), lalu melanjutkannya lagi di lain waktu dengan perintah yang sama (mis: dengan menekan tekan panah atas untuk mengambil histori shell, lalu menekan Enter).

Ini juga berarti dalam mentransfer sebuah tree yang berukuran lumayan besar, Anda tidak perlu repot-repot membuat tarball-nya (.tar.gz) dulu, atau bahkan melakukan split agar ukuran file menjadi kecil-kecil. Cara ini hanya memboroskan ruang disk dan waktu. Cukup rsync langsung tree ke tujuan. Jika putus di tengah-tengah, jalankan kembali perintah rsync yang sama, sampai selesai. Rsync dapat melakukan kompresi transfer (opsi -z) sehingga membuat tarball terkompresi (.gz) tidak begitu bermanfaat.

Kenapa rsync diam dulu sebelum menampilkan daftar file yang ditransfer? Kenapa rsync lambat? Kadang saat melakukan transfer file besar yang terputus di tengah-tengah, rsync akan tampak diam dulu. Ini karena rsync sedang membangun ulang file temporer. Ada opsi-opsi seperti –append, –inplace, dan –whole-file untuk mempercepat ini, tapi kelakukan default rsync menggunakan file temporer adalah untuk alasan keselamatan.

Juga, saat melakukan transfer tree besar (tree dengan ribuan file ke atas) rsync akan membutuhkan sejumlah waktu untuk membangun daftar file. Cara kerja rsync memang membangun daftar file lengkap dulu di kedua sisi pengirim dan penerima agar bisa dibandingkan. Kadang jika filenya banyak sekali, misalnya ratusan ribu hingga jutaan, rsync membutuhkan waktu bermenit-menit atau lebih untuk membangun daftar file ini. Opsi -P akan memperlihatkan progres pembangunan daftar file ini, sehingga rsync tidak tampak diam begitu saja.

Kenapa hasilnya salah? Jika hasil transfer berada 1 level lebih dalam dari yang Anda harapkan (tree “terbungkus” satu level direktori lebih dalam dari yang seharusnya) atau sebaliknya 1 level lebih luar dari yang Anda harapkan (file-file/direktori di level teratas tree “meledak” atau “terbuka”), maka Anda mungkin masih belum memahami kelakuan garis miring di akhir path (lihat bagian sebelumnya).

Jika pengecekan checksum MD5 atau SHA1 terhadap hasil transfer ternyata tidak identik untuk file besar (kadang-kadang terjadi, walau amat jarang), maka Anda bisa menambahkan opsi -c (checksum) untuk memperteliti pengecekan kesamaan, walaupun ini berakibat jumlah waktu yang diperlukan bertambah. Umumnya opsi ini tidak diperlukan karena rsync sudah melakukan juga checksum selama transfer, di samping pembandingan tanggal dan ukuran file.

Tips dalam mirroring

Menghapus file yang sudah tidak ada di sumber. Secara default, rsync tidak akan menghapus file di sisi penerima. Misalnya Anda memiliki:

dir/file1
dir/file2

Lalu di-rsync ke tujuan. Kemudian di sisi sumber terjadi perubahan:

dir/file1 dihapus
dir/file2 dimodifikasi
dir/file3 ditambah

maka rsync akan mengirimkan file2 dan file3, tapi tidak akan menghapus file1 yang ada di tujuan.

Dalam mirroring, biasanya kita ingin mirror yang sama persis, dengan kata lain file1 ingin dihapus juga di tujuan. Untuk itu tambahkanlah opsi –del –force. (Sebetulnya ada berbagai pilihan opsi untuk melakukan penghapusan, misalnya –delete-before, –delete-after, tapi sebagai permulaan, Anda cukup menghafal –del –force saja).

Menghindari kecelakaan. Sebagai pengaman, Anda bisa juga menambahkan opsi –max-delete, misalnya –max-delete 1000. Dalam melakukan mirroring dari sebuah sumber remote yang di luar kekuasaan kita, bisa saja di pihak sumber tersebut terjadi perubahan path atau salah konfigurasi sesaat atau reorganisasi sehingga menyebabkan tree sumber menjadi kosong. Tanpa –max-delete, rsync akan dengan senang hati mengosongkan pula mirror Anda sehingga menghapus bergiga-giga file yang dengan susah payah dan mahal didownload. –max-delete akan membatasi jumlah maksimum file yang bisa didelete, sehingga jika tiba-tiba ada kejadian banyak delete seperti ini Anda bisa mendeteksinya dan mengganti sumber mirror lain misalnya.

Atomik. Dalam memaintain mirror yang besar, biasanya proses mirroring bisa memakan waktu yang lama, berjam-jam bahkan berhari-hari dengan keterbatasan bandwidth. Jika mirrornya sedang dipakai juga, maka bisa jadi proses rsync yang lama ini akan menyebabkan isi mirror menjadi tidak konsisten karena “setengah-setengah” (misalnya, untuk mirror Debian, direktori dists/ yang berisi indeks Releases dan Packages sudah terupdate, tapi di pool/-nya belum, menyebabkan proses apt-get yang memanfaatkan mirror kita menjadi gagal). Rsync menyediakan opsi seperti –delay-updates atau –link-dest untuk membantu proses updating lebih atomik. Pembahasan detilnya di luar cakupan artikel ini, silakan lihat manpage rsync.

Tips dalam melakukan backup

Selain opsi -av -P, dalam melakukan backup filesystem biasanya opsi -H dan -A juga berguna. Opsi -H untuk mempertahankan hubungan hardlink (contoh: /usr/bin/sudo dan /usr/bin/sudoedit di Debian adalah hardlink. Hanya ada satu salinan saja untuk kedua file tersebut. Tanpa opsi -H maka saat ditransfer akan menjadi dua salinan, menghabiskan ruang disk.

Opsi -A untuk menyalin juga metadata ACL, berguna jika Anda menggunakan ACL.

Sebuah contoh aplikasi rsync dalam membuat backup harian dengan histori backup akan dibahas dalam kesempatan lain.

Berbagai tips lainnya

Selektif. Rsync menyediakan berbagai cara yang sangat fleksibel agar kita dapat memilih-milih file mana yang ingin disinkronkan dan mana yang ingin diabaikan (exclude). Beberapa contoh:

Jangan ikut sertakan file-file backup:

$ rsync -av --exclude '*~' --exclude '*.bak' SUMBER TUJUAN

Jangan ikut sertakan direktori metadata .svn (berguna untuk mentransfer direktori source code dari direktori kerja langsung):

$ rsync -av --exclude '.svn' SUMBER TUJUAN

Jika kita menyebutkan path absolut di –exclude, maka itu akan berarti posisinya relatif terhadap SUMBER. Keberadaan garis miring di akhir SUMBER akan lagi-lagi menentukan apakah titik awal yang dianggap akar (root) adalah selevel dengan SUMBER atau satu level di dalam SUMBER. Contoh:

$ rsync -av --exclude '/.*' /home/steven/ /backup/steven/

Perintah di atas akan membackup direktori home saya, tapi tanpa mengikutsertakan “dotfiles” yang ada tepat di bawah home (umumnya berisi file konfigurasi). Tapi seandainya ada dotfiles di bawah direktori lain, misalnya, /home/steven/proj1/.config maka file tersebut tidak akan di-exclude karena kita hanya menginstruksikan meng-exclude dotfiles yang berada di “root” (/.*).

Opsi –exclude dan pasangannya –include dapat disebutkan berselingan dan berulang kali. Terdapat pula opsi –filter yang lebih fleksibel lagi. Terdapat juga opsi –delete-excluded untuk menghapus file-file yang diexclude di sisi tujuan. Berguna misalnya untuk menghapus file-file backup (*~, *.bak) yang mungkin berserakan di sisi tujuan.

Sebuah contoh yang agak lengkap, dari potongan skrip backup yang pernah saya gunakan untuk membackup direktori home saya. Untuk mengirit waktu dan ruang disk, saya meng-exclude berbagai “sampah” seperti cache browser, trash, direktori temporer, file-file backup, dll. Anda mungkin bisa mengembangkan sendiri opsi favorit Anda.

$ nice -n19 \
  rsync -av --del --force --delete-excluded \
    --exclude '*~' --exclude '*.bak' \
    --exclude '*/cache*' --exclude '*/Cache*' \
    --exclude '*/Trash' --exclude */tmp' \
    /home/steven /backup/

Batasi bandwidth. Rsync dapat diinstruksikan untuk hanya menggunakan bandwidth tidak lebih dari yang kita spesifikasikan. Berguna jika rumah atau kantor kita memiliki bandwidth internet yang terbatas dan tidak ingin proses mirroring regular mengganggu aktivitas lainnya. Tambahkan opsi –bwlimit K, di mana K adalah angka dalam KB/s (kilobyte per detik).

Hemat CPU. Untuk mempercepat dan mengirit resource CPU dalam transfer remote, gunakan opsi -e “ssh -c arcfour” atau -e “ssh -c blowfish” sebagai pengganti opsi -e ssh. Cipher default ssh adalah 3des, dan ini lebih lambat daripada blowfish atau arcfour, sehingga kadang menghabiskan terlalu banyak CPU dan mengakibatkan transfer tidak bisa memanfaatkan kecepatan penuh fast ethernet (100Mbps).

Mengirit bandwidth lebih lagi. Opsi –fuzzy membuat rsync berusaha mencari file di sisi penerima yang mungkin dulunya adalah file yang ingin ditransfer, dari kemiripan ukuran dan/atau nama. Misalnya, jika terjadi perubahan penamaan file, maka tanpa opsi –fuzzy ini rsync akan mentransfer ulang file secara keseluruhan, karena tidak ditemukan file sebelumnya dengan nama yang sama di sisi penerima. Opsi-opsi lain seperti –compare-dest (bisa disebutkan berulang kali), –copy-dest, –link-dest juga berhubungan dengan pengiritan bandwidth dengan berusaha mencari kemiripan/file sumber di sisi penerima jika ada.

Coba-coba dulu. Opsi –list-only akan membuat rsync hanya menampilkan daftar file yang akan diproses. Atau gunakan opsi -n (–dry-run) untuk proses simulasi, mencoba-coba dulu tanpa benar-benar melakukan transfer dan penghapusan. Berguna jika Anda pemula atau jika mencoba kombinasi opsi baru. Siapa tahu pilihan opsi Anda tidak tepat dan Anda justru menghapus atau mengkopi file ke tujuan yang salah! Opsi -i (–itemize-changes) dapat dikombinasikan dengan -n untuk melihat perubahan apa saja yang akan dilakukan pada file. Arti simbol-simbol pada output -i ini dapat dilihat di manpage rsync.

Keterbatasan rsync

Meskipun merupakan swiss-army knife dalam urusan transfer dan sinkronisasi tree, namun rsync tidaklah sempurna. Dua kelemahan utama rsync adalah sifat sinkronisasi yang 1 arah dan lambat jika ukuran tree sudah terlalu besar.

Hanya 1 arah. Sinkronisasi rsync hanya bersifat satu arah, dari pengirim (P1) ke penerima (P2). Jika misalnya baik tree di P1 maupun di P2 berubah secara independen oleh pihak ketiga, lalu P1 dan P2 ingin bertukar perubahan secara 2 arah, maka rsync tidak dapat digunakan. Ada opsi -u untuk melewati file-file di P2 yang lebih baru daripada P1, Anda bisa menggunakan opsi ini pada kasus-kasus tertentu, tapi secara umum, untuk melakukan sinkronisasi 2 arah, sebaiknya digunakan tool lain seperti unison (atau mungkin Anda butuh tool version control seperti subversion atau git).

Lambat untuk tree superbesar. Cara kerja rsync adalah dengan mula-mula membangun daftar file lengkap baik di sisi pengirim maupun penerima untuk kemudian dibandingkan. Untuk tree yang sudah amat besar proses ini akan memakan waktu dan juga memori amat besar. Misalnya direktori backup lokal di beberapa server shared hosting di tempat kerja saya yang isinya lebih dari 20 juta file, karena berisi histori backup menggunakan hardlink. Meng-rsync tree ini sekaligus membuat proses rsync memakan memori lebih dari 2-3GB untuk menyusun daftar file, sehingga menghabiskan memori dan mengganggu proses lain.

Kebutuhan memori dalam pembangunan daftar file lengkap di awal proses rsync ini juga membuat para penyedia situs mirror agak enggan menyediakan layanan via rsync. Atau setidaknya membatasi jumlah koneksi simultan rsync, misalnya hanya 1-5.

Diharapkan revisi program dan/atau algoritma rsync berikutnya dapat membuat inovasi dalam hal sinkronisasi tree superbesar, misalnya dengan membentuk daftar file secara paralel atau sambil jalan.

Penutup

Karena keterbatasan ruang, tidak mungkin membahas seluruh fitur rsync yang ada. Beberapa yang tidak dibahas dalam artikel ini: rsync daemon (sehingga tidak butuh ssh lagi untuk transfer remote), front-end GUI untuk rsync seperti grsync,

Rsync bagi saya pribadi adalah salah satu tool paling berharga dan bermanfaat dalam pekerjaan sehari-hari. Saya menggunakan rsync untuk berbagai hal. Misalnya untuk memindah-mindahkan file secara rutin. Atau memaintain situs mirror software. Atau melakukan backup lokal dan backup remote (dulu saya sempat menggunakan beberapa program seperti faubackup, rdiff-backup, dll, tapi akhirnya mudik lagi ke rsync karena alasan kecepatan dan keandalan. Untuk mempermudah pekerjaan, saya membungkus rsync dengan skrip-skrip Perl pendek buatan sendiri). Bahkan untuk melakukan transfer zona DNS pun, alih-alih menggunakan metode AXFR yang “seharusnya”, saya memilih menggunakan rsync+ssh saja. Praktis, andal, cepat, dan aman. Pokoknya dalam segala urusan yang melibatkan transfer file baik remote maupun lokal, rsync hampir selalu menjadi pilihan pertama.

Saya jamin, bagi Anda yang belum familiar dengan tool yang satu ini, akan pula ikut jatuh cinta begitu sudah mengakrabi dan mendalaminya. Selamat mencoba!