restic საუკეთესო ზოგადი დანიშნულების ხელსაწყოა სერვერის S3 საცავზე backup-ისთვის. ყოველი გაშვება ტვირთავს მხოლოდ იმ ნაწილებს, რომლებიც წინა გაშვების შემდეგ შეიცვალა, ყველაფერი მანქანიდან გასვლამდე იშიფრება, ყოველი გაშვება არის snapshot, რომლის ცალკე აღდგენაც შეგიძლია, ხოლო შენახვის ვადა ერთი ბრძანებაა - restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune. მისი დაყენება ოთხი გარემოს ცვლადი და restic init-ია. ნაწილები, რომლებიც ფიქრს მოითხოვს, არის პაროლი, რომელსაც შენ მაგივრად ვერავინ აღადგენს, გზა, რომლითაც მას ბაზის dump-ებს აწვდი, და ჩვევა, რომ დროდადრო რაღაც აღადგინო და დაამტკიცო, რომ მთელი ჯაჭვი მუშაობს. ეს პოსტი ყველაფერ ამას ფარავს ნებისმიერი S3-თავსებადი endpoint-ისთვის.
როგორ ინახავს restic backup-ს#
რეპოზიტორიის ფორმატის გაგება restic-ის ქცევას ხსნის - რატომ არის მეორე backup სწრაფი, რატომ არ ათავისუფლებს forget ადგილს და რატომ აქვს პაროლს ასეთი დიდი მნიშვნელობა.
- Chunk-ები. restic ფაილებს ცვლადი ზომის chunk-ებად ყოფს შიგთავსზე დაფუძნებული დაყოფით, ასე რომ ფაილის შუაში ბაიტების ჩამატება მხოლოდ ჩამატების ირგვლივ მყოფ chunk-ებს ცვლის. ყოველი chunk იდენტიფიცირდება თავისი SHA-256 hash-ით.
- დედუპლიკაცია. Chunk, რომელიც რეპოზიტორიაში უკვე არის, ხელახლა არასოდეს იტვირთება - იმავე ფაილიდან, სხვა ფაილიდან, სხვა snapshot-იდან თუ სხვა მანქანიდან, რომელიც იმავე რეპოზიტორიაში აკეთებს backup-ს.
- Pack-ები. Chunk-ები pack ფაილებად იკვრება, და ეს ის ობიექტებია, რომლებსაც bucket-ში
data/-ის ქვეშ ხედავ. ინდექსებიindex/-ში აღრიცხავს, რომელი chunk რომელ pack-შია. - Snapshot-ები. Snapshot
snapshots/-ში პატარა ჩანაწერია, რომელიც მიუთითებს დირექტორიებისა და ფაილების ხეზე, ისინი კი chunk-ებზე. ყოველი snapshot სრული backup-ია, რომლის აღდგენაც შეგიძლია, მიუხედავად იმისა, რომ თითქმის ყველა მონაცემს მეზობლებთან იზიარებს. - დაშიფვრა. ყველაფერი - მონაცემები, ფაილების სახელები, ინდექსები, snapshot-ები - ატვირთვამდე იშიფრება AES-256-ით და ავთენტიფიცირდება Poly1305-ით. საცავის პროვაიდერი გაუმჭვირვალე ობიექტებს ხედავს.
- შეკუმშვა. რეპოზიტორიის ფორმატის მეორე ვერსია, restic 0.14-დან ნაგულისხმევი, მონაცემებს დაშიფვრამდე zstd-ით კუმშავს.
რეპოზიტორიის მთავარი key შენი პაროლით არის დაშიფრული. აღდგენა არ არსებობს. დაკარგავ პაროლს და რეპოზიტორია წაუკითხავი ხდება, შენთვისაც და ნებისმიერი სხვისთვისაც. ეს დიზაინის არსია და მიზეზი, რის გამოც ქვემოთ პირველი განყოფილება იმაზეა, სად ცხოვრობს პაროლი.
რეპოზიტორიის დაყენება#
დააყენე restic შენი დისტრიბუციიდან, თუ ის ახალია, ან ჩამოტვირთე binary პროექტის GitHub-ის რელიზებიდან; ამ პოსტში ყველაფრისთვის restic version-მა 0.17 ან უფრო ახალი უნდა აჩვენოს, ხოლო restic self-update ოფიციალურ binary-ს ადგილზე ანახლებს.
პარამეტრები შეინახე ფაილში, რომლის წაკითხვაც მხოლოდ root-ს შეუძლია:
export AWS_ACCESS_KEY_ID=RNAKEXAMPLE123export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYexport AWS_DEFAULT_REGION=us-east-1export RESTIC_REPOSITORY=s3:https://s3.example.com/my-bucket/restic/web-01export RESTIC_PASSWORD_FILE=/root/.restic-password$ chmod 600 /root/.restic-env /root/.restic-password$ . /root/.restic-env$ restic -o s3.bucket-lookup=path initcreated restic repository 2f1c9e7a8b at s3:https://s3.example.com/my-bucket/restic/web-01შემადგენელი ნაწილები:
- `RESTIC_REPOSITORY` არის
s3:, რასაც მოსდევს endpoint-ის URL, bucket და არასავალდებულო პრეფიქსი. პრეფიქსი თითოეულ მანქანაზე (restic/web-01) რეპოზიტორიებს ერთ bucket-ში ერთმანეთისგან აცალკევებს. უბრალო HTTP endpoint-ისთვის დაწერეs3:http://host:port/bucket/prefix. - `-o s3.bucket-lookup=path` path-style მისამართებს აიძულებს. restic-ის ნაგულისხმევი,
auto, უკვე იყენებს path-style-ს endpoint-ებისთვის, რომლებიც Amazon-ის ან Google-ის არ არის, მაგრამ მისი მითითება არაფერი ჯდება და მომავალში ნაგულისხმევის ცვლილებას გადაურჩება. - რეგიონი მოდის
AWS_DEFAULT_REGION-იდან, ან-o s3.region=us-east-1-იდან. Endpoint-თან, რომელიც ნებისმიერ რეგიონს იღებს, ნებისმიერი სახელი მუშაობს, მაგრამ ის თანმიმდევრული უნდა იყოს. - `RESTIC_PASSWORD_FILE` მიუთითებს ფაილზე, რომელიც რეპოზიტორიის პაროლს ინახავს. დააგენერირე გრძელი შემთხვევითი პაროლი (
openssl rand -base64 32) და ასლი ახლავე შეინახე პაროლების მენეჯერში, პირველ backup-მდე და არა მის შემდეგ.
RE:NODE-ზე access key და secret key საცავის სერვერისთვის გენერირდება და პანელში ჩანს, და რეპოზიტორიის განსათავსებლად პირველი bucket უკვე არსებობს. Endpoint არის გეგმის მისამართი და პორტი უბრალო HTTP-ით, ან შენი ჰოსტის სახელი HTTPS-ით გეგმის proxy slot-ის გავლით, რომელიც სერტიფიკატს გასცემს და ანახლებს. restic ორივე შემთხვევაში ყველაფერს ატვირთვამდე შიფრავს, მაგრამ HTTPS ასევე მალავს შენს access key ID-სა და მოთხოვნების მეტამონაცემებს, ამიტომ ის ამჯობინე.
ფაილების backup#
$ restic backup /srv/minecraft /etc \ --exclude-file /root/restic-excludes.txt \ --exclude-caches --one-file-system \ --tag nightly/srv/minecraft/logs/srv/minecraft/cache*.tmp**/node_modulesოფციები ამ ბრძანებაში:
--exclude-fileშაბლონებს თითო ხაზზე თითოს კითხულობს;--excludeერთს ბრძანების ხაზზე იღებს.--iexcludeვარიანტები რეგისტრს არ არჩევს.--exclude-cachesგამოტოვებს დირექტორიებს, რომლებიც სტანდარტულCACHEDIR.TAGფაილს შეიცავს.--exclude-if-present .nobackupგამოტოვებს დირექტორიებს, რომლებიც შენ მიერ შექმნილ მარკერ ფაილს შეიცავს.--one-file-systemმოცემული გზების ფაილურ სისტემებზე რჩება, ასე რომ მიერთებული ქსელური საქაღალდე ან/procშიგნით არ ითრევა.--tagsnapshot-ს ჭდეს ადებს; ჭდეებით snapshot-ების არჩევა შეიძლებაforget-სა დაrestore-ში.
პირველი გაშვება ყველაფერს ტვირთავს. შემდეგი გაშვებები ყოველი ფაილის მეტამონაცემებს კითხულობს, ხელახლა კითხულობს ფაილებს, რომელთა ზომა ან ცვლილების დრო შეიცვალა, და მხოლოდ ახალ chunk-ებს ტვირთავს - 30 GB სერვერი რამდენიმე ასეული მეგაბაიტის ყოველდღიური ცვლილებით ჩვეულებრივ წუთებში სრულდება. ბოლოს შემაჯამებელი ხაზი გაჩვენებს, რამდენი დაემატა; ეს რიცხვი ლოგში ჩაწერად ღირს, რადგან ღამის backup, რომელიც უცებ არაფერს ამატებს, ან ჩვეულებრივზე ათჯერ მეტს, შენი ყველაზე ადრეული გაფრთხილებაა, რომ რაღაც შეიცვალა.
Backup თანმიმდევრულ მონაცემებს გაუკეთე. თამაშის სერვერი, რომელიც backup-ის დროს სამყაროს წერს, ნახევრად ჩაწერილი სამყაროს snapshot-ს იძლევა. ჯერ სერვერი გააჩერე, ან flush გააკეთე და შენახვა შეაჩერე, როგორც ამას ხსნის სერვერის backup-ები, რომლებიც მართლა აღდგება; კონკრეტულად თამაშის სერვერებისთვის შენახვის ბრძანებებს თითოეული თამაშისთვის ფარავს თამაშის სერვერის backup-ები S3-ზე.
ბაზების backup#
მომუშავე ბაზის მონაცემების დირექტორიის backup ფაილურ ხელსაწყოთი არასოდეს გააკეთო. Backup dump-ს გაუკეთე. restic-ს შეუძლია dump დროებითი ფაილის გარეშე შეინახოს, ბრძანებიდან წაკითხვით:
$ restic backup --stdin-from-command --stdin-filename app.sql --tag mysql \ -- mysqldump --single-transaction --routines --triggers app--stdin-from-command (restic 0.17 და უფრო ახალი) უშვებს ბრძანებას და მის გამოსავალს snapshot-ში app.sql ფაილად ინახავს. რაც მთავარია, თუ mysqldump შეცდომით დასრულდება, restic snapshot-ს არ ქმნის. ძველი ფორმა, mysqldump app | restic backup --stdin --stdin-filename app.sql, dump-ის დასრულების სტატუსს ვერ ხედავს: dump, რომელიც შუაში ჩავარდა, ინახება როგორც წარმატებული, შეკვეცილი backup. თუ ძველ restic-ზე ხარ გაჭედილი, bash-ში გამოიყენე set -o pipefail და დასრულების სტატუსი თავად შეამოწმე.
Dump restic-ისთვის გადაცემამდე ნუ შეკუმშავ. შეუკუმშავი dump-ები კარგად დედუპლიცირდება - გუშინდელი ჩანაწერების უმეტესობა დღესაც იქ არის - და restic თავად კუმშავს. Gzip-ით შეკუმშული dump ერთი დღიდან მეორემდე თითქმის მთლიანად იცვლება და დედუპლიკაციას აზრს უკარგავს.
იგივე შაბლონი მუშაობს pg_dump-ისთვის, mongodump --archive-ისთვის და მსგავსებისთვის. Dump-ის credential-ები კლიენტის ოფციების ფაილს ეკუთვნის, მაგალითად ~/.my.cnf MySQL-ისთვის, და არა ბრძანების ხაზს, სადაც ps მათ აჩვენებს. თითოეულ ძრავას ფარავს ბაზის dump-ები S3-ზე განრიგით, ხოლო dump-ის flag-ებს - mysqldump backup და აღდგენა.
Snapshot-ები, შენახვის ვადა, forget და prune#
$ restic snapshotsID Time Host Tags Paths----------------------------------------------------------------4f2a1c9e 2026-10-06 04:30:12 web-01 nightly /etc, /srv/minecrafta81d0b37 2026-10-07 04:30:09 web-01 nightly /etc, /srv/minecraftc5e9f210 2026-10-08 04:30:11 web-01 nightly /etc, /srv/minecraftშენახვის ვადა ორი ნაბიჯია. forget snapshot-ის ჩანაწერებს პოლიტიკის მიხედვით შლის; prune შლის მონაცემებს, რომლებსაც არცერთი დარჩენილი snapshot არ მიმართავს. სანამ prune-ს არ გაუშვებ, ადგილი არ თავისუფლდება.
| Flag | ინახავს |
|---|---|
--keep-last n | n ყველაზე ახალ snapshot-ს |
--keep-hourly n | ბოლო snapshot-ს თითოეული n ბოლო საათიდან, რომელსაც snapshot აქვს |
--keep-daily n | თითოს დღეში, n დღისთვის, რომლებსაც snapshot-ები აქვს |
--keep-weekly n | თითოს კვირაში |
--keep-monthly n | თითოს თვეში |
--keep-yearly n | თითოს წელიწადში |
--keep-within 30d | ყველაფერს, რაც მითითებულ ხანგრძლივობაზე ახალია |
--keep-tag name | ყოველ snapshot-ს ამ ჭდით |
პოლიტიკები ერთიანდება - snapshot ინახება, თუ რომელიმე წესი ინახავს - და ცალ-ცალკე მოქმედებს snapshot-ების თითოეულ ჯგუფზე ერთი და იგივე ჰოსტითა და გზებით (--group-by host,paths ნაგულისხმევია), ასე რომ ბაზის snapshot-ებს და ფაილების snapshot-ებს თითოეულს თავისი ისტორია აქვს.
$ restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run$ restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneპირველ ჯერზე ყოველთვის წაიკითხე --dry-run-ის გამოსავალი. --keep-tag locked სასარგებლო დამატებაა: ცნობილ კარგ snapshot-ს ჭდე locked დაადე და არცერთი პოლიტიკა მას არ წაშლის.
Prune ძვირი ნაბიჯია. ის ხელახლა წერს pack-ებს, რომლებიც ნაწილობრივ გამოუყენებელია, რაც მათ ჩამოტვირთვასა და ხელახლა ატვირთვას ნიშნავს, და მას ექსკლუზიური lock სჭირდება, ასე რომ, სანამ ის მუშაობს, ვერცერთი backup ვერ გაეშვება. მისი --max-unused ოფცია, ნაგულისხმევად 5%, ნაწილობრივ გამოყენებულ pack-ებს ხელს არ ახლებს, სანამ ნარჩენი ამ წილს არ გადააჭარბებს, და ცოტა ადგილს გაცილებით ნაკლებ ტრაფიკში ცვლის. forget ღამით გაუშვი, თუ გინდა, მაგრამ prune კვირაში ერთხელ სავსებით საკმარისია.
რეპოზიტორიის შემოწმება#
restic check რეპოზიტორიის სტრუქტურას ამოწმებს: რომ ყოველი snapshot-ის ხე სრულია და ყოველი მიმართული chunk არსებობს ინდექსში ჩამოთვლილ pack-ში. ის მხოლოდ მეტამონაცემებს კითხულობს და სწრაფია.
$ restic check$ restic check --read-data-subset=5%$ restic check --read-data-subset=1/12 # a different twelfth each monthსტრუქტურის შემოწმება არ ამტკიცებს, რომ pack-ების შიგნით მონაცემები მთელია. --read-data ყველაფერს ჩამოტვირთავს და ამოწმებს, რაც დიდ რეპოზიტორიაზე ბევრი ტრაფიკია; --read-data-subset ნაწილს კითხულობს. ყოველთვიურად მბრუნავი n/12 ქვესიმრავლე მთელ რეპოზიტორიას წელიწადში ერთხელ კითხულობს, თითო გაშვებაზე ფასის მეთორმეტედით.
აღდგენა#
ბრძანება, რისთვისაც სინამდვილეში ამ ყველაფერს აკეთებ:
# ყველაფერი ბოლო snapshot-იდან დროებით დირექტორიაში$ restic restore latest --target /tmp/restore# ერთი საქაღალდე კონკრეტული snapshot-იდან$ restic restore a81d0b37 --target /tmp/restore --include /srv/minecraft/world# stdin backup, უკან ფაილად ჩაწერილი$ restic dump latest /app.sql > /tmp/app.sql# ყველა snapshot-ის დათვალიერება ფაილურ სისტემად (Linux, macOS FUSE-ით)$ restic mount /mnt/resticჯერ დროებით დირექტორიაში აღადგინე, შეამოწმე, შემდეგ გადაიტანე ადგილზე - არასოდეს პირდაპირ ცოცხალ სერვერზე, რაც მტკიცებულებას ანადგურებს, თუ არასწორი snapshot აირჩიე. latest ითვალისწინებს --host-ს, --path-სა და --tag-ს, ამიტომ რამდენიმე მანქანის მიერ გაზიარებულ რეპოზიტორიაზე გამოიყენე restic restore latest --host web-01.
ახალ მანქანაზე აღსადგენად ზუსტად სამი რამ გჭირდება: endpoint, access key-ები და რეპოზიტორიის პაროლი. სამივე შეინახე სადმე, სადაც სერვერთან ერთად არ მოკვდება.
განრიგით გაშვება#
Wrapper სკრიპტი, რომელსაც cron ან systemd timer უშვებს, job-ს თანმიმდევრულს ინარჩუნებს:
#!/bin/bashset -euo pipefail. /root/.restic-envrestic backup /srv /etc --exclude-file /root/restic-excludes.txt \ --one-file-system --tag nightly --retry-lock 10mrestic backup --stdin-from-command --stdin-filename app.sql --tag mysql \ --retry-lock 10m -- mysqldump --single-transaction apprestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \ --keep-tag locked --retry-lock 10mif [ "$(date +%u)" = 7 ]; then restic prune --retry-lock 30m restic check --read-data-subset=5%fi--retry-lock (restic 0.16 და უფრო ახალი) სხვა პროცესის lock-ს ელოდება, ნაცვლად იმისა, რომ მაშინვე ჩავარდეს. თუ გაშვება მოკლულია, მას შეიძლება ძველი lock დარჩეს; restic unlock შლის lock-ებს, რომელთა პროცესიც აღარ არსებობს, და მისი გაშვება უსაფრთხოა, ხოლო restic unlock --remove-all ყველა lock-ს შლის და უსაფრთხოა მხოლოდ მაშინ, როცა დარწმუნებული ხარ, რომ სხვა არაფერი მუშაობს.
restic რეპოზიტორიის მეტამონაცემების ლოკალურ ქეშს ინახავს ~/.cache/restic-ში, რაც ყოველ ოპერაციას აჩქარებს. დიდ რეპოზიტორიებზე ის რამდენიმე გიგაბაიტამდე შეიძლება გაიზარდოს; restic cache --cleanup შლის იმ რეპოზიტორიების ქეშებს, რომლებსაც აღარ იყენებ. სკრიპტის გამოსავალი ლოგში გაგზავნე და არანულოვან სტატუსზე გაფრთხილება დააყენე - backup, რომელიც ერთი თვის განმავლობაში ყოველ ღამე ჩუმად ვარდება, ყველაზე გავრცელებული გზაა იმის აღმოსაჩენად, რომ backup არ გაქვს.
სად ჯდება restic S3-ზე 3-2-1 გეგმაში#
restic ასლს სანდოს ხდის - დაშიფრულს, დედუპლიცირებულს, გადამოწმებადს - მაგრამ მის უკან მდგომ საცავს იმაზე საიმედოს ვერ გახდის, ვიდრე ის არის. RE:NODE-ის S3 საცავი შენი მონაცემების ერთ ასლს ინახავს NVMe-ზე ერთ ლოკაციაზე, არარეპლიცირებულს. ეს მასზე არსებულ restic რეპოზიტორიას კარგ მანქანის გარეთა ასლად აქცევს: იმ სერვერისგან ცალკე, რომელსაც იცავს, ფორმატში, რომლის აღდგენაც ყველგან შეგიძლია, სადაც restic მუშაობს. ეს მას შენს ერთადერთ ასლად არ აქცევს.
მონაცემებისთვის, რომელთა დაკარგვაც არ შეგიძლია, მეორე რეპოზიტორია სხვაგან შეინახე და snapshot-ები მასში დააკოპირე:
$ restic -r s3:https://other-storage.example.net/backups/web-01 \ copy --from-repo s3:https://s3.example.com/my-bucket/restic/web-01 \ --from-password-file /root/.restic-passwordrestic copy snapshot-ებს რეპოზიტორიებს შორის გადაიტანს, დანიშნულების key-ით ხელახლა შიფრავს და მხოლოდ იმ chunk-ებს აგზავნის, რომლებიც დანიშნულებას აკლია. მეორე რეპოზიტორია ინიციალიზაცია გაუკეთე init --from-repo ... --copy-chunker-params-ით, რომ ორივემ ერთნაირი დაყოფა გამოიყენოს და დედუპლიკაცია ერთიდან მეორეზე გადავიდეს. რამდენი ადგილი სჭირდება თითოეულ ასლს, დეტალურად განიხილავს S3 საცავის ზომა და 3-2-1 წესი.
FAQ#
რა მოხდება, თუ restic-ის პაროლს დავკარგავ?
რეპოზიტორიის გაშიფვრა ვერავის შეეძლება. შეგიძლია restic key add-ით რამდენიმე key დაამატო, თითოეული თავისი პაროლით, რომ მისი გახსნა ერთზე მეტ ადამიანს ან საცავს შეეძლოს - მაგრამ თუ ყველა პაროლი დაიკარგა, მონაცემებიც დაიკარგა. პაროლი სერვერის გარეთ, პაროლების მენეჯერში შეინახე.
რატომ არ გაათავისუფლა forget-მა ადგილი?
forget მხოლოდ snapshot-ის ჩანაწერებს შლის. მონაცემები, რომლებსაც ისინი მიმართავდნენ, რჩება, სანამ prune არ წაშლის chunk-ებს, რომლებსაც არცერთი snapshot არ იყენებს. გაუშვი restic forget ... --prune, ან შემდეგ restic prune.
შეუძლია რამდენიმე სერვერს ერთ რეპოზიტორიაში backup-ის გაკეთება?
კი, და ისინი ერთმანეთის მიმართ დედუპლიცირდება, რაც ადგილს ზოგავს, როცა სერვერებს საერთო ფაილები აქვთ. ფასი საერთო რისკი და საერთო lock-ებია: prune რეპოზიტორიას ყველა მანქანისთვის ბლოკავს. ერთი რეპოზიტორია თითო სერვერზე, თითოეული თავის პრეფიქსში, უფრო მარტივია და სწორედ ამას ვარაუდობს ეს პოსტი.
restic თუ rclone?
ისინი სხვადასხვა საქმეს აკეთებენ. rclone ფაილებს აკოპირებს და სარკისებურად ასახავს; restic ქმნის ვერსიიან, დაშიფრულ, დედუპლიცირებულ snapshot-ებს შენახვის ვადით. ისტორიიანი backup-ებისთვის გამოიყენე restic; ფაილების გადატანისა და სარკისებური ასახვისთვის - rclone, იხილე rclone S3 საცავთან.
რამდენ ადგილს გამოიყენებს restic?
დაახლოებით მონაცემების ზომას ერთხელ, შეკუმშვისა და დედუპლიკაციის შემდეგ, პლუს შეცვლილ chunk-ებს ყოველი შენახული snapshot-ისთვის. სერვერს 20 GB მონაცემებითა და 1% ყოველდღიური ცვლილებით, რომელიც ინახავს 7 ყოველდღიურ, 4 ყოველკვირეულ და 6 ყოველთვიურ snapshot-ს, ჩვეულებრივ სადღაც 25-დან 40 GB-მდე სჭირდება. restic stats --mode raw-data შენი რეპოზიტორიის რეალურ მაჩვენებელს გაჩვენებს.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.