საიმედო, მაღალ ხელმისაწვდომი, მასშტაბირებადი განაწილებული სისტემის შექმნა მოითხოვს სპეციფიკური ტექნიკის, პრინციპებისა და შაბლონების დაცვას. ასეთი სისტემების დიზაინი მოიცავს უამრავ გამოწვევას. ყველაზე გავრცელებულ და ფუნდამენტურ საკითხებს შორის არის ორმაგი ჩაწერის პრობლემა .
"ორმაგი ჩაწერის პრობლემა" არის გამოწვევა, რომელიც წარმოიქმნება განაწილებულ სისტემებში, ძირითადად, როდესაც საქმე გვაქვს მონაცემთა მრავალ წყაროსთან ან მონაცემთა ბაზასთან, რომლებიც უნდა იყოს სინქრონული. ეს ეხება იმის უზრუნველსაყოფად, რომ მონაცემების ცვლილებები თანმიმდევრულად ჩაიწერება მონაცემთა სხვადასხვა მაღაზიებში, როგორიცაა მონაცემთა ბაზები ან ქეშები, ისეთი საკითხების დანერგვის გარეშე, როგორიცაა მონაცემთა შეუსაბამობა, კონფლიქტები ან შესრულების შეფერხებები.
მიკროსერვისების არქიტექტურა და შაბლონების მონაცემთა ბაზა თითო სერვისზე ბევრ სარგებელს მოაქვს, როგორიცაა დამოუკიდებელი განლაგება და მასშტაბირება, იზოლირებული წარუმატებლობები და განვითარების სიჩქარის პოტენციური გაძლიერება. თუმცა, ოპერაციები მოითხოვს ცვლილებებს მრავალ მიკროსერვისს შორის, რაც გაიძულებთ იფიქროთ ამ პრობლემის მოსაგვარებლად საიმედო გადაწყვეტაზე.
მოდით განვიხილოთ სცენარი, რომელშიც ჩვენი დომენი მოიცავს სესხის განაცხადების მიღებას, მათ შეფასებას და შემდეგ შეტყობინებების გაგზავნას მომხმარებლებისთვის.
ერთიანი პასუხისმგებლობის პრინციპის, კონვეის კანონისა და დომენზე ორიენტირებული დიზაინის მიდგომის სულისკვეთებით, რამდენიმე ღონისძიების შტორმის სესიის შემდეგ, მთელი დომენი დაიყო სამ ქვედომენად განსაზღვრული შემოსაზღვრული კონტექსტებით, რომლებსაც ჰქონდათ მკაფიო საზღვრები, დომენის მოდელები და ყველგან გავრცელებული ენა.
პირველს ევალება ახალი სესხის განაცხადების მიღება და შედგენა. მეორე სისტემა აფასებს ამ აპლიკაციებს და იღებს გადაწყვეტილებებს მოწოდებული მონაცემების საფუძველზე. შეფასების ეს პროცესი, მათ შორის KYC/KYB, თაღლითობის საწინააღმდეგო და საკრედიტო რისკის შემოწმებები, შეიძლება იყოს შრომატევადი, რაც მოითხოვს ათასობით აპლიკაციის ერთდროულად დამუშავების შესაძლებლობას. შესაბამისად, ეს ფუნქციონირება გადაეცა სპეციალურ მიკროსერვისს საკუთარი მონაცემთა ბაზებით, რაც საშუალებას იძლევა დამოუკიდებელი მასშტაბირება.
გარდა ამისა, ამ ქვესისტემებს მართავს ორი განსხვავებული გუნდი, თითოეულს აქვს საკუთარი გამოშვების ციკლები, მომსახურების დონის შეთანხმებები (SLA) და მასშტაბურობის მოთხოვნები.
და ბოლოს , არსებობს სპეციალიზებული შეტყობინებების სერვისი, რათა გაუგზავნოთ შეტყობინებები მომხმარებლებს.
აქ მოცემულია სისტემის პირველადი გამოყენების შემთხვევის დახვეწილი აღწერა:
ეს ერთი შეხედვით საკმაოდ მარტივი და პრიმიტიული სისტემაა, მაგრამ მოდით გავიგოთ, როგორ ამუშავებს სესხის განაცხადის სერვისი სესხის განაცხადის გაგზავნის ბრძანებას.
სერვისის ურთიერთქმედების ორი მიდგომა შეგვიძლია განვიხილოთ:
First-Local-Commit-Then-Publish: ამ მიდგომით, სერვისი განაახლებს ადგილობრივ მონაცემთა ბაზას (დავალებებს) და შემდეგ აქვეყნებს მოვლენას ან შეტყობინებას სხვა სერვისებისთვის.
First-Publish-Then-Local-Commit: პირიქით, ეს მეთოდი გულისხმობს მოვლენის ან შეტყობინების გამოქვეყნებას ადგილობრივ მონაცემთა ბაზაში ცვლილებების განხორციელებამდე.
ორივე მეთოდს აქვს თავისი ნაკლი და მხოლოდ ნაწილობრივ არის უსაფრთხო განაწილებულ სისტემებში კომუნიკაციისთვის.
ეს არის პირველი მიდგომის გამოყენების თანმიმდევრული დიაგრამა.
ამ სცენარში სესხის განაცხადის სერვისი იყენებს First-Local-Commit-Then-Publish მიდგომას, სადაც ის ჯერ ახორციელებს ტრანზაქციას და შემდეგ ცდილობს შეტყობინების გაგზავნას სხვა სისტემაში. თუმცა, ეს პროცესი მიდრეკილია წარუმატებლობისკენ, თუ, მაგალითად, არის ქსელის პრობლემები, შეფასების სერვისი მიუწვდომელია, ან სესხის განაცხადის სერვისი შეექმნება მეხსიერების ამოწურვას (OOM) შეცდომას და ავარია. ასეთ შემთხვევებში, შეტყობინება დაიკარგება, რის გამოც შეფასება დარჩება ახალი სესხის განაცხადის შესახებ შეტყობინების გარეშე, თუ არ განხორციელდება დამატებითი ზომები.
და მეორეც.
First-Publish-Then-Local-Commit სცენარის მიხედვით, სესხის განაცხადის სერვისი უფრო მნიშვნელოვანი რისკების წინაშე დგას. მან შესაძლოა შეატყობინოს შეფასების სამსახურს ახალი აპლიკაციის შესახებ, მაგრამ ვერ შეინახოს ეს განახლება ადგილობრივად ისეთი პრობლემების გამო, როგორიცაა მონაცემთა ბაზის პრობლემები, მეხსიერების შეცდომები ან კოდის შეცდომები. ამ მიდგომამ შეიძლება გამოიწვიოს მონაცემების მნიშვნელოვანი შეუსაბამობა, რამაც შეიძლება გამოიწვიოს სერიოზული პრობლემები, იმისდა მიხედვით, თუ როგორ ამუშავებს სესხის განხილვის სამსახური შემოსულ აპლიკაციებს.
ამიტომ, ჩვენ უნდა გამოვავლინოთ გამოსავალი, რომელიც გვთავაზობს მძლავრ მექანიზმს მოვლენების გამოქვეყნებისთვის გარე მომხმარებლებისთვის. მაგრამ, სანამ პოტენციურ გადაწყვეტილებებს ჩავუღრმავდებით, ჯერ უნდა განვმარტოთ შეტყობინების მიწოდების გარანტიების ტიპები, რომლებიც მიიღწევა განაწილებულ სისტემებში.
არსებობს ოთხი სახის გარანტია, რომლის მიღწევაც შეგვიძლია.
არანაირი გარანტია
არ არსებობს გარანტია, რომ შეტყობინება მიწოდებული იქნება დანიშნულების ადგილზე. მიდგომა First-Local-Commit-Then-Publish სწორედ ამაზეა. მომხმარებლებმა შეიძლება მიიღონ შეტყობინებები ერთხელ, რამდენჯერმე ან საერთოდ არასდროს.
მაქსიმუმ ერთხელ მიწოდება
მაქსიმუმ ერთხელ მიწოდება ნიშნავს, რომ შეტყობინება მიეწოდება დანიშნულების ადგილს მაქსიმუმ 1 ჯერ. მიდგომა First-Local-Commit-Then-Publish შეიძლება განხორციელდეს ამ გზით, ისევე როგორც ერთი მნიშვნელობის მქონე მცდელობების განმეორებითი პოლიტიკით.
ერთხელ მაინც მიწოდება\მომხმარებლები მიიღებენ და დაამუშავებენ ყველა შეტყობინებას, მაგრამ შეიძლება მიიღონ ერთი და იგივე შეტყობინება არაერთხელ.
ზუსტად ერთხელ მიწოდება\ზუსტად ერთხელ მიწოდება ნიშნავს, რომ მომხმარებელი მიიღებს შეტყობინებას ერთხელ.
ტექნიკურად, შესაძლებელია კაფკას ტრანზაქციებით და მწარმოებლისა და მომხმარებლის კონკრეტული იდემპოტენტური განხორციელებით.
უმეტეს შემთხვევაში, მიწოდების „ერთხელ მაინც“ გარანტიები ბევრ საკითხს აგვარებს იმით, რომ მესიჯები ერთხელ მაინც იქნება მიწოდებული, მაგრამ მომხმარებლები უნდა იყვნენ უძლურები. თუმცა, ქსელის გარდაუვალი უკმარისობის გათვალისწინებით, მომხმარებელთა მთელი ლოგიკა უნდა იყოს უძლური, რათა თავიდან აიცილოს დუბლიკატი შეტყობინებების დამუშავება, მიუხედავად მწარმოებლის გარანტიებისა. ამიტომ, ეს მოთხოვნა არ არის იმდენად ნაკლი, რამდენადაც ის ასახავს რეალობას.
ამ პრობლემის გადაჭრის უამრავი გზა არსებობს, რომელსაც აქვს თავისი დადებითი და უარყოფითი მხარეები.
ვიკიპედიის მიხედვით, ორფაზიანი შეთანხმება (2PC) არის განაწილებული ტრანზაქციის პროტოკოლი, რომელიც გამოიყენება კომპიუტერულ მეცნიერებაში და მონაცემთა ბაზის მართვის სისტემებში, რათა უზრუნველყოს განაწილებული ტრანზაქციების თანმიმდევრულობა და საიმედოობა. ის შექმნილია იმ სიტუაციებისთვის, როდესაც მრავალ რესურსს (მაგ. მონაცემთა ბაზას) სჭირდება მონაწილეობა ერთ ტრანზაქციაში და ის უზრუნველყოფს, რომ ან ყველა მათგანმა ჩაიდინოს ტრანზაქცია, ან ყველამ გააუქმოს იგი, რითაც შეინარჩუნებს მონაცემთა თანმიმდევრულობას. ჟღერს ზუსტად ის, რაც ჩვენ გვჭირდება, მაგრამ ორფაზიან დასრულებას აქვს რამდენიმე ნაკლი:
მიკროსერვისების არქიტექტურისთვის ყველაზე აშკარა გამოსავალი არის შაბლონის (ან ზოგჯერ ანტი-ნიმუშის) გამოყენება - საერთო მონაცემთა ბაზა. ეს მიდგომა ძალიან ინტუიციურია, თუ თქვენ გჭირდებათ ტრანზაქციის თანმიმდევრულობა მრავალ ცხრილზე სხვადასხვა მონაცემთა ბაზაში, უბრალოდ გამოიყენეთ ერთი საერთო მონაცემთა ბაზა ამ მიკროსერვისებისთვის.
ამ მიდგომის ნაკლოვანებები მოიცავს წარუმატებლობის ერთი წერტილის დანერგვას, მონაცემთა დამოუკიდებელი სკალირების დათრგუნვას და მონაცემთა ბაზის სხვადასხვა გადაწყვეტილებების გამოყენების შესაძლებლობის შეზღუდვას, რომელიც საუკეთესოდ შეეფერება კონკრეტულ მოთხოვნებსა და გამოყენების შემთხვევებს. გარდა ამისა, მიკროსერვისების კოდების ბაზების ცვლილებები საჭირო იქნება განაწილებული ტრანზაქციის ასეთი ფორმის მხარდასაჭერად.
„ ტრანზაქციის გამავალი ყუთი “ არის დიზაინის ნიმუში, რომელიც გამოიყენება განაწილებულ სისტემებში, რათა უზრუნველყოს შეტყობინებების საიმედო გავრცელება, თუნდაც არასანდო შეტყობინებების სისტემების პირობებში. ის მოიცავს მოვლენების შენახვას დანიშნულ "OutboxEvents" ცხრილში იმავე ტრანზაქციის ფარგლებში, როგორც თავად ოპერაცია. ეს მიდგომა კარგად ემთხვევა რელაციური მონაცემთა ბაზების ACID თვისებებს. ამის საპირისპიროდ, ბევრი No-SQL მონაცემთა ბაზა სრულად არ უჭერს მხარს ACID თვისებებს, ამის ნაცვლად ირჩევს CAP თეორემისა და BASE ფილოსოფიის პრინციპებს, რომლებიც პრიორიტეტს ანიჭებენ ხელმისაწვდომობას და საბოლოო თანმიმდევრულობას მკაცრ თანმიმდევრულობაზე.
ტრანზაქციული გასასვლელი იძლევა მინიმუმ ერთხელ გარანტიას და შეიძლება განხორციელდეს რამდენიმე მიდგომით:
ტრანზაქციის ჟურნალის კუდა
გამოკითხვის გამომცემელი
ტრანზაქციების ჟურნალის შემცირების მიდგომა გულისხმობს მონაცემთა ბაზის სპეციფიკური გადაწყვეტილებების გამოყენებას, როგორიცაა CDC (Change Data Capture). ამ მიდგომის მთავარი ნაკლოვანებებია:
მონაცემთა ბაზის სპეციფიკური გადაწყვეტილებები
გაზრდილი შეყოვნება CDC დანერგვის სპეციფიკის გამო
კიდევ ერთი მეთოდია Polling Publisher , რომელიც ხელს უწყობს გასასვლელი ყუთის გადმოტვირთვას გამავალი ცხრილის გამოკითხვით. ამ მიდგომის მთავარი ნაკლი არის მონაცემთა ბაზის დატვირთვის გაზრდის პოტენციალი, რამაც შეიძლება გამოიწვიოს უფრო მაღალი ხარჯები. გარდა ამისა, ყველა No-SQL მონაცემთა ბაზა არ უჭერს მხარს ეფექტურ მოთხოვნას კონკრეტული დოკუმენტის სეგმენტებისთვის. ამრიგად, მთელი დოკუმენტების ამოღებამ შეიძლება გამოიწვიოს შესრულების დეგრადაცია.
აქ არის პატარა თანმიმდევრობის დიაგრამა, რომელიც განმარტავს, თუ როგორ მუშაობს.
ძირითადი გამოწვევა ტრანზაქციის გასასვლელი შაბლონთან დაკავშირებით მდგომარეობს მის დამოკიდებულებაში მონაცემთა ბაზის ACID თვისებებზე. ეს შეიძლება იყოს მარტივი ტიპიური OLTP მონაცემთა ბაზებში, მაგრამ წარმოადგენს გამოწვევებს NoSQL სფეროში. ამის გადასაჭრელად, პოტენციური გამოსავალია დამატებების ჟურნალის (მაგალითად, კაფკას) გამოყენება მოთხოვნის დამუშავების დაწყებისთანავე.
„სესხის განაცხადის გაგზავნა“ ბრძანების პირდაპირ დამუშავების ნაცვლად, ჩვენ დაუყოვნებლივ ვუგზავნით მას შიდა კაფკას თემაში და შემდეგ ვუბრუნებთ კლიენტს „მიღებულ“ შედეგს. თუმცა, იმის გამო, რომ დიდი ალბათობით, ბრძანება ჯერ კიდევ უნდა დამუშავდეს, ჩვენ არ შეგვიძლია დაუყოვნებლივ ვაცნობოთ მომხმარებელს შედეგის შესახებ. ამ საბოლოო თანმიმდევრულობის სამართავად, ჩვენ შეგვიძლია გამოვიყენოთ ისეთი ტექნიკები, როგორიცაა ხანგრძლივი გამოკითხვა, კლიენტის მიერ ინიცირებული გამოკითხვა, ოპტიმისტური UI განახლებები ან WebSockets ან სერვერის მიერ გაგზავნილი მოვლენების გამოყენება შეტყობინებებისთვის. თუმცა, ეს სრულიად განსხვავებული თემაა, ამიტომ დავუბრუნდეთ საწყის თემას.
ჩვენ გავაგზავნეთ მესიჯი კაფკას შიდა თემაზე. შემდეგ სესხის განაცხადის სერვისი მოიხმარს ამ შეტყობინებას - იგივე ბრძანებას, რომელიც მიიღო კლიენტისგან - და იწყებს დამუშავებას. პირველი, ის ახორციელებს გარკვეულ ბიზნეს ლოგიკას; მხოლოდ მას შემდეგ, რაც ეს ლოგიკა წარმატებით განხორციელდება და შედეგები შენარჩუნდება, ის აქვეყნებს ახალ მესიჯებს საჯარო კაფკას თემაზე.
მოდით შევხედოთ ცოტა ფსევდო-კოდს.
public async Task HandleAsync(SubmitLoanApplicationCommand command, ...) { //First, process business logic var loanApplication = await _loanApplicationService.HandleCommandAsync(command, ...); //Then, send new events to public Kafka topic producer.Send(new LoanApplicationSubmittedEvent(loanApplication.Id)); //Then, commit offset consumer.Commit(); }
რა მოხდება, თუ ბიზნეს ლოგიკის დამუშავება ვერ ხერხდება? არ ინერვიულოთ, რადგან ოფსეტური ჯერ არ განხორციელებულა, შეტყობინება ხელახლა განმეორდება.
რა მოხდება, თუ კაფკას ახალი მოვლენების გაგზავნა ვერ მოხერხდა? არ ინერვიულოთ, რადგან ბიზნეს ლოგიკა უძლურია, ის არ შექმნის სესხის განაცხადს. ამის ნაცვლად, ის შეეცდება ხელახლა გაგზავნოს შეტყობინებები კაფკას საჯარო თემისთვის.
რა მოხდება, თუ შეტყობინებები ეგზავნება კაფკას, მაგრამ ოფსეტური ჩადენა ვერ მოხერხდება? არ ინერვიულოთ, რადგან ბიზნეს ლოგიკა უძლურია, ის არ შექმნის სესხის დუბლიკატს. ამის ნაცვლად, ის ხელახლა გაუგზავნის შეტყობინებებს კაფკას საჯარო თემას და იმედოვნებს, რომ ოფსეტური ჩადენა ამჯერად წარმატებული იქნება.
ამ მიდგომის მთავარი ნაკლოვანებები მოიცავს დამატებით სირთულეს, რომელიც ასოცირდება პროგრამირების ახალ სტილთან, საბოლოო თანმიმდევრულობასთან (რადგან კლიენტი დაუყოვნებლივ არ გაიგებს შედეგს) და მოთხოვნას, რომ ყველა ბიზნეს ლოგიკა იყოს უძლური.
რა არის მოვლენის წყარო და როგორ შეიძლება მისი აქ გამოყენება? Event Sourcing არის პროგრამული უზრუნველყოფის არქიტექტურული ნიმუში, რომელიც გამოიყენება სისტემის მდგომარეობის მოდელირებისთვის, მისი მონაცემების ყველა ცვლილების აღწერით, როგორც უცვლელი მოვლენების სერია. ეს მოვლენები წარმოადგენს ფაქტებს ან მდგომარეობათა გადასვლებს და ემსახურება როგორც სიმართლის ერთ წყაროს სისტემის ამჟამინდელი მდგომარეობისთვის. ასე რომ, ტექნიკურად, ივენთ-სორსინგის სისტემის დანერგვით, ჩვენ უკვე გვაქვს ყველა ღონისძიება EventStore-ში და ეს EventStore მომხმარებლებს შეუძლიათ გამოიყენონ, როგორც სიმართლის ერთი წყარო მომხდარის შესახებ. არ არის საჭირო მონაცემთა ბაზის სპეციფიკური გადაწყვეტა ყველა ცვლილების ან შეკვეთის შესახებ შეშფოთების თვალყურის დევნებისთვის, ერთადერთი პრობლემა არის წაკითხვის მხარეზე დგომა, რადგან ერთეულის რეალური მდგომარეობის მისაღებად საჭიროა ყველა მოვლენის ხელახლა დაკვრა.
ამ სტატიაში ჩვენ განვიხილეთ რამდენიმე მიდგომა განაწილებულ სისტემებში საიმედო შეტყობინებების შესაქმნელად. არსებობს რამდენიმე რეკომენდაცია, რომელიც შეიძლება გავითვალისწინოთ ამ მახასიათებლების მქონე სისტემების აშენებისას
შემდეგ ჯერზე, ჩვენ განვიხილავთ უფრო პრაქტიკულ მაგალითს ტრანზაქციული გზავნილის განხორციელების შესახებ. იხ
შენ!