Mencadangkan sejumlah besar proyek web heterogen

Tampaknya topik sudah basi - banyak yang telah dikatakan dan ditulis tentang cadangan, jadi tidak ada yang menemukan kembali roda, ambil saja dan lakukan. Namun demikian, setiap kali ketika administrator sistem proyek web menghadapi tugas mengatur cadangan, bagi banyak orang menggantung di udara dengan tanda tanya besar. Bagaimana cara mengumpulkan cadangan data dengan benar? Di mana menyimpan cadangan? Bagaimana cara menyediakan tingkat penyimpanan salinan retrospektif yang diperlukan? Bagaimana cara menyatukan proses pencadangan untuk seluruh kebun binatang dari berbagai perangkat lunak?



Bagi kami sendiri, kami pertama-tama memecahkan masalah ini pada 2011. Kemudian kami duduk dan menulis skrip cadangan kami. Selama bertahun-tahun, kami hanya menggunakan mereka, dan mereka berhasil menyediakan proses yang andal untuk mengumpulkan dan menyinkronkan cadangan proyek web klien kami. Cadangan disimpan di kami atau beberapa penyimpanan eksternal lainnya, dengan kemungkinan penyempurnaan untuk proyek tertentu.


Saya harus mengatakan, skrip ini bekerja sepenuhnya. Tetapi semakin jauh kami tumbuh, semakin kami memiliki beragam proyek dengan berbagai perangkat lunak dan repositori eksternal yang tidak didukung oleh skrip kami. Misalnya, kami tidak memiliki dukungan untuk Redis dan cadangan MySQL dan PostgreSQL yang muncul kemudian. Proses pencadangan tidak dipantau, hanya ada peringatan email.


Masalah lain adalah proses dukungan. Selama bertahun-tahun, skrip kami yang dulu kompak telah tumbuh dan berubah menjadi monster canggung yang besar. Dan ketika kami berkumpul dan merilis versi baru, layak upaya terpisah untuk meluncurkan pembaruan untuk bagian dari pelanggan yang menggunakan versi sebelumnya dengan semacam penyesuaian.


Akibatnya, pada awal tahun ini, kami membuat keputusan dengan tekad kuat: untuk mengganti skrip cadangan lama kami dengan sesuatu yang lebih modern. Karena itu, pada awalnya kami duduk dan menulis semua Daftar Keinginan untuk solusi baru. Ternyata kira-kira sebagai berikut:


  • Cadangkan data perangkat lunak yang paling sering digunakan:
    • File (menyalin diskrit dan inkremental)
    • MySQL (cadangan dingin / panas)
    • PostgreSQL (cadangan dingin / panas)
    • Mongodb
    • Redis
  • Simpan cadangan di repositori populer:
    • Lokal
    • FTP
    • Ssh
    • SMB
    • Nfs
    • Webdav
    • S3
  • Terima peringatan jika ada masalah selama proses pencadangan
  • Memiliki satu file konfigurasi yang memungkinkan Anda mengelola cadangan secara terpusat
  • Tambahkan dukungan untuk perangkat lunak baru dengan menghubungkan modul eksternal
  • Tentukan opsi tambahan untuk mengumpulkan dump
  • Memiliki kemampuan untuk memulihkan cadangan dengan cara biasa
  • Konfigurasi awal yang mudah

Kami menganalisis solusi yang tersedia


Kami melihat solusi open-source yang sudah ada:


  • Bacula dan garpunya, misalnya, Bareos
  • Amanda
  • Borg
  • Duplikat
  • Duplicity
  • Rsnapshot
  • Cadangan tinggi

Tetapi masing-masing memiliki kelemahan. Sebagai contoh, Bacula kelebihan beban dengan fungsi yang tidak kita butuhkan, konfigurasi awal adalah tugas yang agak melelahkan karena banyaknya pekerjaan manual (misalnya, untuk menulis / mencari skrip cadangan basis data), dan untuk mengembalikan salinan Anda perlu menggunakan utilitas khusus, dll.


Pada akhirnya, kami sampai pada dua kesimpulan penting:


  1. Tidak ada solusi yang ada yang sepenuhnya sesuai untuk kita;
  2. Tampaknya kita sendiri memiliki cukup pengalaman dan kegilaan untuk mulai menulis keputusan kita.

Jadi kami melakukannya.


Kelahiran nxs-backup


Python dipilih sebagai bahasa untuk implementasi - mudah untuk menulis dan memelihara, fleksibel dan nyaman. Diputuskan untuk menggambarkan file konfigurasi dalam format yaml.


Untuk kenyamanan mendukung dan menambahkan cadangan perangkat lunak baru, arsitektur modular dipilih di mana proses pengumpulan cadangan dari setiap perangkat lunak tertentu (misalnya, MySQL) dijelaskan dalam modul terpisah.


Dukungan untuk file, database, dan penyimpanan jarak jauh


Saat ini, jenis cadangan file, database, dan repositori jarak jauh berikut ini didukung:


DB:


  • MySQL (cadangan panas / dingin)
  • PostgreSQL (cadangan panas / dingin)
  • Redis
  • Mongodb

File:


  • Penyalinan terpisah
  • Penyalinan tambahan

Repositori jarak jauh:


  • Lokal
  • S3
  • SMB
  • Nfs
  • FTP
  • Ssh
  • Webdav

Cadangan diskrit


Untuk tugas yang berbeda, baik cadangan diskrit atau inkremental cocok, oleh karena itu, mereka menerapkan kedua jenis ini. Anda dapat menentukan metode mana yang digunakan pada tingkat file dan direktori individual.


Untuk salinan diskrit (baik file dan database), Anda dapat mengatur retrospektif dalam format hari / minggu / bulan.


Cadangan tambahan


Salinan file tambahan dibuat sebagai berikut:


Pada awal tahun, cadangan penuh akan. Selanjutnya, pada awal setiap bulan - salinan bulanan tambahan relatif terhadap salinan tahunan. Dalam menstruasi - kenaikan decadal relatif terhadap bulanan. Dalam setiap sepuluh hari tambahan siang hari relatif terhadap periode sepuluh hari.


Perlu dicatat bahwa sementara ada beberapa masalah ketika bekerja dengan direktori yang mengandung banyak subdirektori (puluhan ribu). Dalam kasus seperti itu, koleksi salinan diperlambat secara signifikan dan dapat memakan waktu lebih dari sehari. Kami secara aktif menangani kekurangan ini.


Kami pulih dari cadangan inkremental


Tidak ada masalah dengan memulihkan dari cadangan diskrit - cukup ambil salinan untuk tanggal yang diperlukan dan gunakan dengan tar konsol biasa. Salinan tambahan sedikit lebih rumit. Untuk memulihkan, misalnya, pada 24 Juli 2018, Anda perlu melakukan yang berikut:


  1. Perluas cadangan satu tahun, bahkan jika dalam kasus kami mulai dari 1 Januari 2018 (dalam praktiknya, ini bisa tanggal kapan saja, tergantung pada saat diputuskan untuk menerapkan cadangan tambahan)
  2. Gulung padanya cadangan bulanan untuk bulan Juli
  3. Gulung cadangan dekade 21 Juli
  4. Gulung cadangan harian untuk 24 Juli

Pada saat yang sama, untuk melakukan 2-4 poin, Anda harus menambahkan -G beralih ke perintah tar, dengan demikian menunjukkan bahwa ini adalah cadangan tambahan. Tentu saja, ini bukan proses tercepat, tetapi ketika Anda menganggap bahwa tidak sering diperlukan untuk memulihkan dari cadangan dan efektivitas biaya itu penting, skema semacam itu cukup efektif.


Pengecualian


Seringkali, Anda perlu mengecualikan file atau direktori individual dari cadangan, misalnya, direktori dengan cache. Ini dapat dilakukan dengan menentukan aturan pengecualian yang sesuai:


contoh file konfigurasi
- target: - /var/www/*/data/ excludes: - exclude1/exclude_file - exclude2 - /var/www/exclude_3 

Rotasi cadangan


Dalam skrip lama kami, rotasi diimplementasikan sehingga salinan lama dihapus hanya setelah yang baru berhasil disusun. Hal ini menyebabkan masalah pada proyek-proyek di mana ruang untuk cadangan, pada prinsipnya, dialokasikan tepat untuk satu salinan - salinan baru tidak dapat dikumpulkan di sana karena kurangnya ruang.


Dalam implementasi baru, kami memutuskan untuk mengubah pendekatan ini: pertama-tama hapus yang lama dan baru kemudian kumpulkan salinan baru. Dan proses pengumpulan cadangan harus dipantau untuk mencari tahu tentang masalah apa pun.


Untuk cadangan diskrit, arsip dianggap sebagai salinan lama yang melampaui skema penyimpanan yang ditentukan dalam format hari / minggu / bulan. Dalam hal cadangan inkremental, cadangan disimpan secara default selama satu tahun, dan salinan lama dihapus pada awal setiap bulan, sedangkan arsip untuk bulan yang sama tahun lalu dianggap sebagai cadangan lama. Misalnya, sebelum mengumpulkan cadangan bulanan pada 1 Agustus 2018, sistem akan memeriksa apakah ada cadangan untuk Agustus 2017, dan jika demikian, itu akan menghapusnya. Ini memungkinkan penggunaan ruang disk yang optimal.


Penebangan


Dalam proses apa pun, dan terutama dalam pencadangan, penting untuk mengikuti dan mengetahui apakah ada kesalahan. Sistem menyimpan log pekerjaannya dan menangkap hasil dari setiap langkah: mulai / hentikan dana, mulai / berakhirnya tugas tertentu, hasil pengumpulan salinan dalam direktori sementara, hasil menyalin / memindahkan salinan dari direktori sementara ke lokasi permanen, hasil rotasi cadangan, dll. ..


Acara dibagi menjadi 2 level:


  • Info : tingkat informasi - penerbangan normal, tahap berikutnya selesai dengan sukses, entri informasi yang sesuai dibuat dalam log
  • Kesalahan : tingkat kesalahan - ada yang salah, tahap berikutnya gagal, catatan kesalahan yang sesuai dibuat di log

Pemberitahuan Email


Di akhir pengumpulan cadangan, sistem dapat mengirim pemberitahuan email.


2 daftar penerima didukung:


  • Administrator adalah mereka yang melayani server. Mereka hanya menerima pemberitahuan kesalahan, mereka tidak tertarik dengan pemberitahuan operasi yang berhasil
  • Pengguna bisnis - dalam kasus kami, ini adalah pelanggan yang terkadang ingin menerima pemberitahuan untuk memastikan bahwa semuanya baik-baik saja dengan cadangan. Atau, sebaliknya, tidak juga. Mereka dapat memilih apakah akan menerima log lengkap atau hanya log dengan kesalahan.

Struktur file konfigurasi


Struktur file konfigurasi adalah sebagai berikut:


contoh struktur
 /etc/nxs-backup ├── conf.d │ ├── desc_files_local.conf │ ├── external_clickhouse_local.conf │ ├── inc_files_smb.conf │ ├── mongodb_nfs.conf │ ├── mysql_s3.conf │ ├── mysql_xtradb_scp.conf │ ├── postgresql_ftp.conf │ ├── postgresql_hot_webdav.conf │ └── redis_local_ftp.conf └── nxs-backup.conf 

Di sini /etc/nxs-backup/nxs-backup.conf adalah file konfigurasi utama di mana pengaturan global ditunjukkan:


file konfigurasi
 main: server_name: SERVER_NAME admin_mail: project-tech@nixys.ru client_mail: - '' mail_from: backup@domain.ru level_message: error block_io_read: '' block_io_write: '' blkio_weight: '' general_path_to_all_tmp_dir: /var/nxs-backup cpu_shares: '' log_file_name: /var/log/nxs-backup/nxs-backup.log jobs: !include [conf.d/*.conf] 

Array tugas (pekerjaan) berisi daftar tugas (pekerjaan), yang merupakan deskripsi tentang apa yang harus dicadangkan, tempat menyimpan, dan dalam jumlah berapa. Sebagai aturan, mereka dipindahkan ke file yang terpisah (satu file per pekerjaan), yang terhubung melalui sertakan dalam file konfigurasi utama.


Mereka juga berusaha mengoptimalkan proses mempersiapkan file-file ini sebanyak mungkin dan menulis generator sederhana. Oleh karena itu, administrator tidak perlu menghabiskan waktu mencari templat konfigurasi untuk beberapa layanan, misalnya, MySQL, tetapi cukup jalankan perintah:


 nxs-backup generate --storage local scp --type mysql --path /etc/nxs-backup/conf.d/mysql_local_scp.conf 

Keluaran menghasilkan file /etc/nxs-backup/conf.d/mysql_local_scp.conf :


Isi file
  - job: PROJECT-mysql type: mysql tmp_dir: /var/nxs-backup/databases/mysql/dump_tmp sources: - connect: db_host: '' db_port: '' socket: '' db_user: '' db_password: '' auth_file: '' target: - all excludes: - information_schema - performance_schema - mysql - sys gzip: no is_slave: no extra_keys: '--opt --add-drop-database --routines --comments --create-options --quote-names --order-by-primary --hex-blob' storages: - storage: local enable: yes backup_dir: /var/nxs-backup/databases/mysql/dump store: days: '' weeks: '' month: '' - storage: scp enable: yes backup_dir: /var/nxs-backup/databases/mysql/dump user: '' host: '' port: '' password: '' path_to_key: '' store: days: '' weeks: '' month: '' 

Di mana itu tetap hanya untuk menggantikan beberapa nilai yang diperlukan.


Mari kita ambil contoh. Misalkan pada server kami di direktori / var / www ada dua situs dari toko online 1C-Bitrix (bitrix-1.ru, bitrix-2.ru), yang masing-masing berfungsi dengan basis datanya sendiri dalam berbagai instance MySQL (port 3306 untuk bitrix_1_db dan 3307 port untuk bitrix_2_db).


Struktur file dari proyek Bitrix pada umumnya kira-kira sebagai berikut:


 ├── ... ├── bitrix │ ├── .. │ ├── admin │ ├── backup │ ├── cache │ ├── .. │ ├── managed_cache │ ├── .. │ ├── stack_cache │ └── .. ├── upload └── ... 

Sebagai aturan, direktori unggah sangat berbobot, dan hanya bertambah seiring waktu, sehingga akan didukung secara bertahap. Semua direktori lain bersifat diskrit, dengan pengecualian direktori dengan cache dan cadangan yang dikumpulkan oleh alat Bitrix asli. Biarkan skema penyimpanan cadangan untuk kedua situs ini harus sama, sedangkan salinan file harus disimpan secara lokal dan pada penyimpanan ftp jarak jauh, dan basis data harus disimpan hanya pada penyimpanan jarak jauh seseorang.


File konfigurasi yang dihasilkan untuk pengaturan seperti itu akan terlihat seperti ini:


bitrix-desc-files.conf (file konfigurasi dengan deskripsi tugas untuk cadangan diskrit)
  - job: Bitrix-desc-files type: desc_files tmp_dir: /var/nxs-backup/files/desc/dump_tmp sources: - target: - /var/www/*/ excludes: - bitrix/backup - bitrix/cache - bitrix/managed_cache - bitrix/stack_cache - upload gzip: yes storages: - storage: local enable: yes backup_dir: /var/nxs-backup/files/desc/dump store: days: 6 weeks: 4 month: 6 - storage: ftp enable: yes backup_dir: /nxs-backup/databases/mysql/dump host: ftp_host user: ftp_usr password: ftp_usr_pass store: days: 6 weeks: 4 month: 6 

bitrix-inc-files.conf (file konfigurasi dengan deskripsi tugas untuk cadangan tambahan)
  - job: Bitrix-inc-files type: inc_files sources: - target: - /var/www/*/upload/ gzip: yes storages: - storage: ftp enable: yes backup_dir: /nxs-backup/files/inc host: ftp_host user: ftp_usr password: ftp_usr_pass - storage: local enable: yes backup_dir: /var/nxs-backup/files/inc 

bitrix-mysql.conf (file konfigurasi dengan deskripsi tugas untuk backup MySQL)
  - job: Bitrix-mysql type: mysql tmp_dir: /var/nxs-backup/databases/mysql/dump_tmp sources: - connect: db_host: localhost db_port: 3306 db_user: bitrux_usr_1 db_password: password_1 target: - bitrix_1_db excludes: - information_schema - performance_schema - mysql - sys gzip: no is_slave: no extra_keys: '--opt --add-drop-database --routines --comments --create-options --quote-names --order-by-primary --hex-blob' - connect: db_host: localhost db_port: 3307 db_user: bitrix_usr_2 db_password: password_2 target: - bitrix_2_db excludes: - information_schema - performance_schema - mysql - sys gzip: yes is_slave: no extra_keys: '--opt --add-drop-database --routines --comments --create-options --quote-names --order-by-primary --hex-blob' storages: - storage: smb enable: yes backup_dir: /nxs-backup/databases/mysql/dump host: smb_host port: smb_port share: smb_share_name user: smb_usr password: smb_usr_pass store: days: 6 weeks: 4 month: 6 

Opsi untuk mulai mengumpulkan cadangan


Dalam contoh sebelumnya, kami menyiapkan file konfigurasi pekerjaan untuk mengumpulkan cadangan semua elemen sekaligus: file (diskrit dan inkremental), dua database dan menyimpannya di penyimpanan lokal dan eksternal (ftp, smb).


Masih menjalankan semuanya. Peluncuran dilakukan dengan perintah:


 nxs-backup start $JOB_NAME -c $PATH_TO_MAIN_CONFIG 

Ada beberapa nama pekerjaan yang dipesan:


  • file - eksekusi sembarang dari semua pekerjaan dengan tipe desc_files , inc_files (yaitu, pada dasarnya, hanya file yang didukung )
  • database - mengeksekusi semua pekerjaan secara acak dengan tipe mysql , mysql_xtradb , postgresql , postgresql_hot , mongodb , redis (yaitu, cadangan hanya database)
  • eksternal - mengeksekusi semua pekerjaan secara acak dengan tipe eksternal (hanya menjalankan skrip khusus tambahan, lebih lanjut tentang ini di bawah)
  • semua - meniru menjalankan perintah satu per satu dengan file pekerjaan, database , eksternal (nilai default)

Karena kita perlu mendapatkan backup data dari kedua file dan database pada saat yang sama (atau dengan perbedaan minimum) pada output, disarankan untuk menjalankan backup-nxs dengan pekerjaan semua , yang akan memastikan eksekusi yang konsisten dari pekerjaan yang dijelaskan (Bitrix-desc- file, Bitrix-inc_files, Bitrix-mysql).


Artinya, poin penting - cadangan tidak akan dikumpulkan secara paralel, tetapi secara berurutan, satu demi satu, dengan perbedaan waktu minimum. Selain itu, pada awal berikutnya, perangkat lunak itu sendiri memeriksa proses yang sudah berjalan dalam sistem dan jika terdeteksi, ia akan secara otomatis mengakhiri kerjanya dengan tanda yang sesuai di log. Pendekatan ini secara signifikan mengurangi beban pada sistem. Minus - cadangan elemen individu dikumpulkan tidak sekaligus, tetapi dengan beberapa perbedaan waktu. Tetapi sementara latihan kami menunjukkan bahwa ini tidak kritis.


Modul eksternal


Sebagaimana disebutkan di atas, berkat arsitektur modular, kemampuan sistem dapat diperluas menggunakan modul pengguna tambahan yang berinteraksi dengan sistem melalui antarmuka khusus. Tujuannya adalah agar di masa depan dapat menambahkan dukungan untuk cadangan perangkat lunak baru tanpa perlu menulis ulang cadangan-nxs.


contoh file konfigurasi
  - job: TEST-external type: external dump_cmd: '' storages: …. 

Perhatian khusus harus diberikan pada kunci dump_cmd , di mana nilainya adalah perintah penuh untuk menjalankan skrip eksternal. Selain itu, setelah menyelesaikan perintah ini, diharapkan bahwa:


  • Arsip data perangkat lunak yang sudah jadi akan dikumpulkan
  • Data akan dikirim ke stdout dalam format json, dari bentuk:
     { "full_path": "ABS_PATH_TO_ARCHIVE", "basename": "BASENAME_ARCHIVE", "extension": "EXTERNSION_OF_ARCHIVE", "gzip": true/false } 

    • Dalam hal ini, nama kunci, ekstensi , gzip diperlukan secara eksklusif untuk pembentukan nama cadangan akhir.
  • Jika naskah berhasil diselesaikan, kode pengembalian harus 0 dan yang lainnya jika ada masalah.

Sebagai contoh, misalkan kita memiliki skrip untuk membuat snapshot, etcd /etc/nxs-backup-ext/etcd.py :


kode skrip
 #! /usr/bin/env python3 # -*- coding: utf-8 -*- import json import os import subprocess import sys import tarfile def archive(snapshot_path): abs_tmp_path = '%s.tar' %(snapshot_path) with tarfile.open(abs_tmp_path, 'w:') as tar: tar.add(snapshot_path) os.unlink(snapshot_path) return abs_tmp_path def exec_cmd(cmdline): data_dict = {} current_process = subprocess.Popen([cmdline], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, executable='/bin/bash') data = current_process.communicate() data_dict['stdout'] = data[0][0:-1].decode('utf-8') data_dict['stderr'] = data[1][0:-1].decode('utf-8') data_dict['code'] = current_process.returncode return data_dict def main(): snapshot_path = "/var/backups/snapshot.db" dump_cmd = "ETCDCTL_API=3 etcdctl --cacert=/etc/ssl/etcd/ssl/ca.pem --cert=/etc/ssl/etcd/ssl/member-node1.pem"+\ " --key=/etc/ssl/etcd/ssl/member-node1-key.pem --endpoints 'https://127.0.0.1:2379' snapshot save %s" %snapshot_path command = exec_cmd(dump_cmd) result_code = command['code'] if result_code: sys.stderr.write(command['stderr']) else: try: new_path = archive(snapshot_path) except tarfile.TarError as e: sys.exit(1) else: result_dict = { "full_path": new_path, "basename": "etcd", "extension": "tar", "gzip": False } print(json.dumps(result_dict)) sys.exit(result_code) if __name__ == '__main__': main() 

Konfigurasi untuk menjalankan skrip ini adalah sebagai berikut:


file konfigurasi
  - job: etcd-external type: external dump_cmd: '/etc/nxs-backup-ext/etcd.py' storages: - storage: local enable: yes backup_dir: /var/nxs-backup/external/dump store: days: 6 weeks: 4 month: 6 

Dalam hal ini, program saat menjalankan pekerjaan etcd-external :


  • Jalankan script /etc/nxs-backup-ext/etcd.py tanpa parameter
  • Setelah skrip selesai, ia akan memeriksa kode penyelesaian dan ketersediaan data yang diperlukan di stdout
  • Jika semua pemeriksaan berhasil, maka mekanisme yang sama digunakan seperti dengan modul yang sudah terpasang, di mana nilai kunci full_path digunakan sebagai tmp_path. Jika tidak, itu akan menyelesaikan tugas ini dengan tanda yang sesuai di log.

Dukungan dan pembaruan


Proses mengembangkan dan mendukung sistem cadangan baru telah dilaksanakan dengan semua kanon CI / CD. Tidak ada lagi pembaruan dan suntingan skrip di server pertempuran. Semua perubahan melewati repositori central git kami di Gitlab, tempat perakitan versi baru paket deb / rpm terdaftar dalam pipa, yang kemudian diunggah ke repositori deb / rpm kami. Dan setelah itu, melalui manajer paket, mereka dikirim ke server klien akhir.


Bagaimana cara mengunduh nxs-backup?


Kami membuat proyek open-source nxs-backup. Siapa pun dapat mengunduh dan menggunakannya untuk mengatur proses pencadangan dalam proyek mereka, serta memodifikasi kebutuhan mereka, menulis modul eksternal.


Kode sumber untuk cadangan-nxs dapat diunduh dari repositori Github di tautan ini . Ada juga petunjuk instalasi dan konfigurasi.


Kami juga menyiapkan gambar Docker dan mempostingnya di DockerHub .


Jika Anda memiliki pertanyaan selama proses pengaturan atau penggunaan, tuliskan kepada kami. Kami akan membantu untuk memahami dan menyelesaikan instruksi.


Kesimpulan


Dalam waktu dekat, kami akan menerapkan fungsi berikut:


  • Memantau integrasi
  • Enkripsi cadangan
  • Antarmuka berbasis web untuk mengelola pengaturan cadangan
  • Menyebarkan cadangan menggunakan nxs-cadangan
  • Dan masih banyak lagi

Source: https://habr.com/ru/post/id424717/


All Articles