Valkey თავის მონაცემებს მეხსიერებაში ინახავს და დისკზე ასლს ორიდან ერთი ან ორივე გზით წერს. RDB snapshot არის მთელი მონაცემთა ნაკრები, რომელიც ინტერვალებით ერთ კომპაქტურ ფაილში იწერება; append-only ფაილი (AOF) ყოველ ჩაწერას მისი მოხდენისთანავე ლოგავს და გაშვებისას თავიდან სრულდება. ჩართული AOF-ითა და appendfsync everysec-ით - რაც გონივრული პარამეტრია - ავარია მაქსიმუმ დაახლოებით ერთი წამის ჩანაწერებს კარგავს. მხოლოდ snapshot-ებით ავარია კარგავს ყველაფერს ბოლო snapshot-ის შემდეგ, რაც ნაგულისხმევად შეიძლება საათამდე იყოს. ორივეს გაშვება გაძლევს AOF-ის მცირე დანაკარგის ფანჯარასა და კომპაქტურ snapshot ფაილს სხვაგან გადასაწერად. არცერთი თავისთავად backup არ არის, რადგან ორივე იმავე დისკზე ცხოვრობს, სადაც სერვერი, და არცერთი არ აქცევს Valkey-ს ბაზად, რომელიც იძლევა გარანტიას, რომ commit-ებული ჩანაწერი გადარჩება.
ორი მექანიზმი ერთ სურათზე#
კლიენტი თავის OK-ს იღებს, როგორც კი ჩანაწერი მეხსიერებაშია. ყველაფერი, რაც ამის მარჯვნივაა, მოგვიანებით ხდება, და ეს Valkey-ში შენახვის მთავარი ფაქტია: დადასტურებული ჩანაწერი ჯერ დისკზე არ არის. რამდენ ხანს რჩება ის მხოლოდ მეხსიერებაში, ქვემოთ მოცემულ პარამეტრებზეა დამოკიდებული.
RDB snapshot-ები#
Snapshot არის მთელი მონაცემთა ნაკრები, სერიალიზებული ერთ ფაილში, ნაგულისხმევად dump.rdb, დირექტორიაში, რომელსაც dir ასახელებს. Valkey მას ავტომატურად იღებს, როცა შენახვის წერტილი მიიღწევა, და სუფთა გამორთვისას.
save 3600 1 300 100 60 10000dbfilename dump.rdbrdbcompression yesrdbchecksum yesstop-writes-on-bgsave-error yessave ხაზი წამებისა და ცვლილებების წყვილებია: snapshot 3600 წამის შემდეგ, თუ ერთი გასაღები მაინც შეიცვალა, 300 წამის შემდეგ, თუ 100 მაინც შეიცვალა, 60 წამის შემდეგ, თუ 10,000 მაინც შეიცვალა. ეს სამი წყვილი ნაგულისხმევია. save "" ავტომატურ snapshot-ებს სრულად თიშავს.
ის, თუ როგორ კეთდება snapshot, მის ძლიერ მხარესაც ხსნის და მის ფასსაც. Valkey იძახებს fork()-ს, და შვილობილი პროცესი მონაცემთა ნაკრებს დროებით ფაილში წერს და დასრულებისას ძველის ადგილას გადაარქმევს. მშობელი მთელი ამ დროის განმავლობაში კლიენტებს ემსახურება. Fork იყენებს copy-on-write-ს: მშობელი და შვილობილი მეხსიერების გვერდებს იზიარებენ, სანამ მშობელი რომელიმეს არ შეცვლის, და ამ მომენტში ბირთვი იმ გვერდს აკოპირებს. მშვიდი მონაცემთა ნაკრების snapshot-ს თითქმის არანაირი დამატებითი მეხსიერება არ სჭირდება; მონაცემთა ნაკრებს, რომელიც snapshot-ის დროს ინტენსიურ ჩანაწერებს იღებს, უარეს შემთხვევაში შეიძლება თავისი ზომის თითქმის ორმაგი დასჭირდეს, რადგან ყოველი შეხებული გვერდი დუბლირდება.
RDB-ის ძლიერი მხარეები: ერთი კომპაქტური ფაილი, რომლის მანქანიდან გადაწერაც მარტივია; სწრაფი ჩატვირთვა გაშვებისას, ლოგის თავიდან შესრულებაზე გაცილებით სწრაფი; და თითქმის ნულოვანი ფასი snapshot-ებს შორის. სუსტი მხარე: ყველაფერი, რაც ბოლო snapshot-ის შემდეგ ჩაიწერა, მხოლოდ მეხსიერებაში არსებობს.
stop-writes-on-bgsave-error yes, ნაგულისხმევი პარამეტრი, ღირს, რომ გაიგო, სანამ გაგაკვირვებს. თუ ფონური შენახვა ჩავარდება - დისკი სავსეა, fork ვერ მოხერხდა - Valkey შემდგომ ჩანაწერებს MISCONF შეცდომით უარყოფს, იმ ლოგიკით, რომ ჯობია იცოდე, რომ შენახვა შეჩერდა, ვიდრე ეს ავარიის შემდეგ აღმოაჩინო. გაასწორე მიზეზი და ეს შემდეგი წარმატებული შენახვისას მოიხსნება.
ბრძანებები: BGSAVE ახლავე იწყებს ფონურ snapshot-ს; SAVE მას წინა პლანზე იღებს და ყველა კლიენტს ბლოკავს, სანამ არ დასრულდება, ამიტომ ცოცხალ სერვერზე ნუ გამოიყენებ; LASTSAVE აბრუნებს ბოლო წარმატებული შენახვის Unix დროს.
Append-only ფაილი#
AOF ჩაწერს ყოველ ბრძანებას, რომელიც მონაცემებს ცვლის, იმავე პროტოკოლით, რომელსაც კლიენტები იყენებენ, და ლოგს უმატებს. გაშვებისას სერვერი ლოგს თავიდან ასრულებს და იმავე მდგომარეობას უბრუნდება.
appendonly yesappendfilename "appendonly.aof"appenddirname "appendonlydir"appendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-use-rdb-preamble yesaof-load-truncated yesპარამეტრი, რომელიც წყვეტს, რამდენის დაკარგვა შეგიძლია, არის appendfsync. ფაილში ჩაწერა მონაცემებს ოპერაციული სისტემის ქეშში დებს; მხოლოდ fsync აიძულებს მათ დისკზე მოხვედრას.
appendfsync | როდის აღწევს მონაცემები დისკს | დანაკარგი უარეს შემთხვევაში | ფასი |
|---|---|---|---|
always | ყოველი ჩამწერი ბრძანების შემდეგ | თითქმის არაფერი | ყოველი ჩაწერა დისკს ელოდება |
everysec | წამში ერთხელ, ფონურ thread-ში | დაახლოებით ერთი წამი | მცირე; ნაგულისხმევი |
no | როცა ბირთვი გადაწყვეტს | ათეულობით წამი | უმცირესი |
everysec თითქმის ყველასთვის სწორი არჩევანია. სწრაფ NVMe საცავზე always იმაზე ნაკლებად მტკივნეულია, ვიდრე მისი რეპუტაცია, მაგრამ ყოველ ჩაწერას დისკის round trip-ად აქცევს, და თუ ეს გარანტია გჭირდება, დიდი ალბათობით გინდა ბაზა ნამდვილი ტრანზაქციებით. მძიმე დატვირთვისას, თუ ფონური fsync ნელია, everysec-ის რისკი ხანმოკლედ დაახლოებით ორ წამამდე შეიძლება გაიზარდოს.
ლოგი უსასრულოდ იზრდება, თუ არ შეიკუმშება. Rewrite მიმდინარე მონაცემთა ნაკრებიდან ახალ, მინიმალურ ლოგს აშენებს - მილიონი INCR ბრძანება ერთ გასაღებზე ერთ SET-ად იქცევა - fork-ირებულ შვილობილში, ზუსტად ისე, როგორც snapshot. auto-aof-rewrite-percentage 100 rewrite-ს იწყებს, როცა ლოგი ბოლო rewrite-ის შემდეგ გაორმაგდა, ხოლო auto-aof-rewrite-min-size პაწაწინა ლოგებს მუდმივი გადაწერისგან იცავს. BGREWRITEAOF მას ხელით იწყებს.
Redis 7.0-იდან, და შესაბამისად ყველა Valkey რელიზში, AOF ერთი ფაილი კი არა, დირექტორიაა, appendonlydir, რომელიც შეიცავს საბაზისო ფაილს, ერთ ან მეტ ინკრემენტულ ფაილს და მანიფესტს, რომელიც მათ ჩამოთვლის. aof-use-rdb-preamble yes-ით (ნაგულისხმევი) საბაზისო ფაილი RDB ფორმატით იწერება, რაც rewrite-ებსა და ჩატვირთვას გაცილებით აჩქარებს; ინკრემენტული ფაილები შეიცავს მას შემდეგ შესრულებულ ბრძანებებს. დირექტორიას ერთიანად მოეპყარი - მისგან ერთი ფაილის გადაწერა ფრაგმენტს გაძლევს და არა მონაცემთა ნაკრებს.
ორივეს გამოყენება და რა იტვირთება გაშვებისას#
გაუშვი ორივე. AOF გაძლევს ერთწამიან დანაკარგის ფანჯარას; RDB გაძლევს კომპაქტურ ფაილს backup-ებისთვის და უფრო სწრაფ restart-ს, თუ ოდესმე მისგან დაწყება დაგჭირდება.
გაშვებისას, თუ appendonly არის yes, Valkey ტვირთავს AOF-ს და dump.rdb-ს უგულებელყოფს, რადგან ლოგი უფრო სრულია. თუ AOF გამორთულია, snapshot-ს ტვირთავს. ერთი შედეგი ადამიანებს ხაფანგში აგდებს: appendonly yes-ის ჩართვა იმ სერვერის კონფიგურაციის ფაილში, რომლის მონაცემებიც მხოლოდ dump.rdb-შია, და შემდეგ restart, ცარიელი AOF-იდან იწყება და სერვერი ცარიელი ჩნდება. AOF-ის ჩასართავად გაშვებულ სერვერზე, რომელსაც არსებული მონაცემები აქვს, გამოიყენე CONFIG SET appendonly yes სანამ მუშაობს, დაელოდე საწყისი rewrite-ის დასრულებას (aof_rewrite_in_progress:0 INFO persistence-ში), და შემდეგ კონფიგურაციის ფაილი შესაბამისობაში მოიყვანე.
საპირისპირო არჩევანიც ლეგიტიმურია. სერვერი, რომელიც მხოლოდ ქეშს ინახავს, შეიძლება მუშაობდეს save ""-ითა და appendonly no-ით: არც fork, არც დისკზე ჩაწერა, არც MISCONF შეცდომები, და ყოველი restart ცარიელიდან იწყება. ეს გონივრული გაცვლაა, როცა ქეშის ხელახლა აშენება იაფია და მის უკან მდგომ ბაზას ცივი სტარტის ატანა შეუძლია. ეს არასწორი გაცვლაა იმ მომენტიდან, როცა ვინმე იმავე სერვერზე სესიებს ან ამოცანების რიგს დებს, და სწორედ ასე მთავრდება გაზიარებული ინსტანციების უმეტესობა იმ მონაცემების შენახვით, რომელთა დაკარგვაც არავის უნდოდა. გადაწყვიტე თითო სერვერზე, ჩაიწერე გადაწყვეტილება და, თუ შეგიძლია, სხვადასხვა მდგრადობის მოთხოვნების მქონე მონაცემები სხვადასხვა სერვერზე შეინახე.
ჩატვირთვას მონაცემების პროპორციული დრო სჭირდება. სანამ ის მიმდინარეობს, სერვერი ბრძანებებს LOADING შეცდომით პასუხობს; კლიენტებმა ცდა უნდა გაიმეორონ და არა ფატალურად მიიჩნიონ.
რას კარგავს თითოეული სახის გაჩერება#
დანაკარგი დამოკიდებულია იმაზე, როგორ გაჩერდა პროცესი, და არა მხოლოდ პარამეტრებზე.
| მოვლენა | მხოლოდ RDB | AOF everysec (RDB-ით ან მის გარეშე) |
|---|---|---|
სუფთა გამორთვა (SHUTDOWN, SIGTERM) | არაფერი, თუ შენახვის წერტილები დაკონფიგურირებულია | არაფერი |
პროცესი მოკლულია (SIGKILL, მეხსიერების ამოწურვა) | ყველაფერი ბოლო snapshot-ის შემდეგ | დაახლოებით ბოლო წამი |
| ოპერაციული სისტემის ავარია ან დენის გათიშვა | ყველაფერი ბოლო snapshot-ის შემდეგ | დაახლოებით ბოლო წამი, თუ დისკი fsync-ს პატივს სცემს |
| დისკი დაიკარგა ან დაზიანდა | ყველაფერი, მანქანის გარეთ ასლის გარეშე | ყველაფერი, მანქანის გარეთ ასლის გარეშე |
შეცდომით გაშვებული FLUSHALL | აღდგენადია ძველი snapshot-ის ასლიდან | FLUSHALL-იც ლოგშია - იხილე ქვემოთ |
ბოლო სტრიქონი შენიშვნას იმსახურებს. FLUSHALL ისეთივე ჩაწერაა, როგორც ნებისმიერი სხვა, ამიტომ AOF-ში ხვდება. თუ შემდეგ rewrite-მდე შეამჩნევ, შეგიძლია სერვერი გააჩერო, ბოლოში მდგომი FLUSHALL ამოიღო appendonlydir-ის უახლესი ინკრემენტული ფაილიდან და თავიდან გაუშვა. rewrite-ის შემდეგ მონაცემები ლოგიდან გამქრალია და მხოლოდ ადრე აღებული ასლი დაგეხმარება. ამიტომაა შენახვა და backup სხვადასხვა თემა.
დაზიანებული ფაილის აღდგენა#
ფაილები იჭრება - ჩაწერის შუაში ავარია AOF-ის ბოლოს ნახევარ ბრძანებას ტოვებს. aof-load-truncated yes-ით (ნაგულისხმევი) Valkey ტვირთავს ყველაფერს დაზიანებულ ბოლო ბრძანებამდე, წერს გაფრთხილებას ლოგში და ეშვება. თუ დაზიანება ფაილის შუაშია, ის გაშვებაზე უარს ამბობს, და მას ხელით ასწორებ:
$ valkey-check-aof appendonlydir/appendonly.aof.manifest$ valkey-check-aof --fix appendonlydir/appendonly.aof.manifest$ valkey-check-rdb dump.rdbvalkey-check-aof --fix ლოგს პირველ არავალიდურ ბრძანებაზე ჭრის, რაც იმ წერტილის შემდეგ ყველაფერს კარგავს - გაშვებამდე დირექტორია დააკოპირე. valkey-check-rdb გეუბნება, წაკითხვადია თუ არა snapshot. თუ AOF აღდგენას აღარ ექვემდებარება, snapshot კი რიგზეა, შეგიძლია snapshot-იდან დაიწყო: გამორთე AOF, გაუშვი, შემდეგ კი ხელახლა ჩართე მუშაობისას, როგორც ზემოთაა აღწერილი.
თუმცა აღდგენების უმეტესობა დაზიანებულ ფაილებს საერთოდ არ ეხება. ისინი ეხება სერვერს, რომელიც გაეშვა, ჩატვირთა თავისი AOF და აქვს ის მონაცემები, რაც უნდა ჰქონდეს. ეს ჩვეულებრივი შემთხვევაა, და სწორედ ესაა მთელი ამის აზრი.
შენახვაზე დაკვირვება#
შენახვა ჩუმად ფუჭდება, სანამ restart არ გამოააშკარავებს, ამიტომ შეამოწმე ის ისე, როგორც ყველაფერი დანარჩენი. INFO persistence-ს ყველაფერი აქვს:
$ valkey-cli -h db.example.net -p 6380 --askpass INFO persistenceloading:0rdb_changes_since_last_save:184rdb_bgsave_in_progress:0rdb_last_save_time:1791449103rdb_last_bgsave_status:okaof_enabled:1aof_rewrite_in_progress:0aof_last_bgrewrite_status:okaof_last_write_status:okველები, რომლებზეც alert-ი ღირს: rdb_last_bgsave_status და aof_last_bgrewrite_status უნდა იყოს ok; aof_last_write_status უნდა იყოს ok; rdb_last_save_time ახალი უნდა იყოს, თუ მონაცემები იცვლება. rdb_changes_since_last_save, რომელიც შენახვის გარეშე იზრდება, ნიშნავს, რომ snapshot-ები შეჩერდა. სერვერის ლოგში ხაზი, რომელიც ამბობს, რომ fork ჩავარდა ან ფონური შენახვა შეცდომით დასრულდა, ადრეული გაფრთხილებაა, რომ მეხსიერების მარაგი ამოიწურა.
შენახვა backup არ არის#
ორივე ფაილი იმავე დისკზე დევს, სადაც სერვერი. წაშლილი სერვერი, ჩავარდნილი დისკი, შეცდომით გაშვებული FLUSHALL, რომელიც მას შემდეგ AOF-ში გადაიწერა, ან აპლიკაციის ბაგი, რომელმაც გასაღებების ნახევარი გადააწერა - ყველა მათგანი გიტოვებს არასწორი მდგომარეობის მდგრად ასლებს. Backup არის ასლი სხვაგან, პრობლემამდე არსებული დროიდან.
Valkey-სთვის ეს მარტივია, რადგან snapshot ერთი ფაილია:
- დაიწყე ახალი snapshot
BGSAVE-ით და დაელოდე, სანამLASTSAVEშეიცვლება. - გადაწერე
dump.rdbმანქანიდან - სხვა სერვერზე, ობიექტების საცავში, სადმე, რაც ავარიას არ იზიარებს. - შეინახე რამდენიმე თაობა, რომ ერთი კვირით გვიან შემჩნეული პრობლემაც აღდგენადი იყოს.
სადაც სერვერი ამის საშუალებას იძლევა, valkey-cli --rdb backup.rdb snapshot-ს ქსელით იღებს სერვერის დისკზე შეხების გარეშე, რაც backup ჰოსტიდან მოსახერხებელია. და დროდადრო აღადგინე ერთი სატესტო ინსტანციაში - აღდგენის შემოწმება, სანამ დაგჭირდება ხსნის, რატომაა სწორედ ეს ნაბიჯი მნიშვნელოვანი. ბაზის backup-ები და აღდგენა ფარავს უფრო ფართო გრაფიკს.
შემდეგ გადაწყვიტე, საერთოდ სჭირდება თუ არა მონაცემებს backup. ქეშს არ სჭირდება: ის ბაზიდან შეიძლება ხელახლა აშენდეს. სესიებს ჩვეულებრივ არ სჭირდება: მათი დაკარგვა ადამიანებს სისტემიდან აგდებს. მომლოდინე ამოცანების რიგებს, მთვლელებს, რომლებზეც ანგარიშს წერ, და ყველაფერს, რასაც სხვა ასლი არ აქვს - სჭირდება.
შენახვა RE:NODE-ის Valkey სერვერზე#
Valkey სერვერები ბაზების ხაზზე დისკზე AOF-ითაც და snapshot-ებითაც ინახავს, ამიტომ restart - იქნება ეს ღილაკზე დაჭერა, თუ სერვერის გაჩერება მეხსიერების ლიმიტზე და სუფთად თავიდან გაშვება, რაც პლატფორმის მიერ მეხსიერების ამოწურვის დამუშავების გზაა - ლოგს თავიდან ასრულებს და იმ მონაცემებით ბრუნდება, რაც ჰქონდა, მაქსიმუმ ჩანაწერების ბოლო მომენტის გამოკლებით. მეხსიერების ლიმიტის ეს ქცევა ასევე პრაქტიკული მიზეზია, რომ მონაცემთა ნაკრები თითოეული გეგმის მიერ მითითებული გამოსაყენებელი მოცულობის ფარგლებში შეინახო და არა სათაურში მოცემული რიცხვის: snapshot-ისა და rewrite-ის შვილობილებს ადგილი სჭირდებათ. Backup slot-ები მოჰყვება ყველა Valkey გეგმას 512 MB-იდან ზემოთ; 256 MB გეგმას ისინი არ აქვს, ამიტომ ამ გეგმაზე, თუ მონაცემები მნიშვნელოვანია, საკუთარი ასლები მანქანის გარეთ გააკეთე, როგორც ზემოთაა აღწერილი. Backup-ები პანელში ღილაკით აღდგება.
FAQ#
AOF გამოვიყენო თუ RDB?
ორივე, თუ მონაცემებს საერთოდ რაიმე მნიშვნელობა აქვს. AOF appendfsync everysec-ით ავარიას დაახლოებით ერთი წამის დაკარგულ ჩანაწერებამდე ზღუდავს; RDB გაძლევს კომპაქტურ ფაილს მანქანიდან გადასაწერად და უფრო სწრაფ restart-ს. თუ სერვერი მხოლოდ ქეშს ინახავს, მხოლოდ snapshot-ები ან საერთოდ შენახვის გარეშე მუშაობა გონივრულია.
კარგავს Valkey მონაცემებს restart-ისას?
არა სუფთა restart-ისას ჩართული შენახვით: ის გამორთვისას ინახავს და გაშვებისას თავიდან ტვირთავს. იძულებითი გაჩერება კარგავს იმას, რაც დისკამდე ვერ მივიდა - დაახლოებით ერთ წამს AOF everysec-ით, ან ყველაფერს ბოლო snapshot-ის შემდეგ AOF-ის გარეშე.
რატომ უარყოფს ჩემი სერვერი ჩანაწერებს MISCONF შეცდომით?
ფონური შენახვა ჩავარდა და stop-writes-on-bgsave-error ჩართულია, ამიტომ სერვერი ჩანაწერების მიღებას წყვეტს, სანამ შენახვა ისევ არ იმუშავებს. მიზეზი თითქმის ყოველთვის სავსე დისკი ან fork-ია, რომელიც მეხსიერების ნაკლებობის გამო ჩავარდა. სერვერის ლოგი გეტყვის, რომელი.
ღირს appendfsync always თავის ფასად?
იშვიათად. ის ყოველ ჩაწერას აიძულებს, დაელოდოს დისკის დადასტურებას, რაც გამტარუნარიანობას მკვეთრად ამცირებს, ხოლო მონაცემები, რომლებსაც ის იცავს, ავარიამდე ბოლო წამია. თუ ამ წამის დაკარგვა მიუღებელია, მონაცემებს, დიდი ალბათობით, ტრანზაქციულ ბაზაში აქვს ადგილი, მაგალითად PostgreSQL-ში, Valkey-ით მის წინ.
რამდენად დიდი გახდება AOF?
ყოველი rewrite-ის შემდეგ დაახლოებით მონაცემთა ნაკრების პროპორციული, rewrite-ებს შორის კი ყოველი ჩაწერით იზრდება. ნაგულისხმევი პარამეტრებით ის გადაიწერება, როცა გაორმაგდება, ამიტომ ელოდე, რომ მონაცემების ზომის ერთიდან ორჯერადამდე დარჩება, პლუს snapshot ფაილი მის გვერდით. დატოვე დისკზე ადგილი ორივესთვის და rewrite-ის დროებითი ასლისთვის.




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