+− THE DAILY DIFFdev & AI news
SHIP IT

Shopify-მ ინვენტარის რეზერვაციები MySQL-ში გადაიტანა

Shopify-მ თავისი ინვენტარის რეზერვაციის სისტემა Redis-დან MySQL მონაცემთა ბაზაში გადაიტანა, რომელიც უკვე შეიცავდა ინვენტარის აღრიცხვას.

Shopify-მ თავისი ინვენტარის რეზერვაციის სისტემა Redis-დან MySQL მონაცემთა ბაზაში გადაიტანა, რომელიც უკვე შეიცავდა ინვენტარის აღრიცხვას. ინდივიდუალურად დასაკეტი ერთეული რიგების შეზღუდული პული საშუალებას აძლევს კონკურენტულ გადახდებს გამოიყენონ SKIP LOCKED სხვადასხვა შესაბამისი ერთეულების ასარჩევად. დიზაინი ასევე დამოკიდებულია ტრანზაქციის საზღვრებზე, პირველადი გასაღების განლაგებაზე, შევსების წესებზე და კავშირის შეკავების დროის დაკვირვებაზე გადახდისას.

წაიკითხეთ წერილობითი გამოცემა (ინგლისური) ↗

რას მოიცავს ეს ვიდეო

  • ძველი Redis-ის რაოდენობრივი მრიცხველის მოდელი ამუშავებდა კონკურენციას, მაგრამ რეზერვაციის გასუფთავება და MySQL-ის აღრიცხვის განახლება ვერ იზიარებდა ერთ ლოკალურ ატომურ ტრანზაქციას.
  • ჩანაცვლება იყენებს ერთ რიგს თითოეული ხელმისაწვდომი ერთეულისთვის პულში, რომელიც შეზღუდულია 1,000-ით თითოეული ნივთის/მდებარეობის კომბინაციისთვის. ცარიელ პულს შეუძლია გამოიწვიოს შიდა შევსება კონკურენტული მოთხოვნებით, რომლებიც ელოდებიან შევსების საკეტის მიღმა.
  • კომპოზიტური პირველადი გასაღები არის (shop_id, inventory_item_id, inventory_group_id, id). Shopify-მ შეამცირა საკეტის დანახარჯები თავის პროტოტიპში და გამოიყენა READ COMMITTED, რათა თავიდან აეცილებინა ხარვეზის საკეტები, რომლებიც ბლოკავდა შევსებას.
  • რეზერვი შლის პულის რიგებს რეზერვაციის ჩანაწერების ჩასმამდე. კომიტირება ათავისუფლებს მონაცემთა ბაზის საკეტებს, ხოლო შენახული შეკავება გრძელდება გადახდისას; წარმატებული გადახდა აცხადებს აღრიცხვას და შლის რეზერვაციას მოგვიანებით ატომურ ტრანზაქციაში.
  • MySQL დოკუმენტაცია აღწერს SKIP LOCKED-ს, როგორც არათანმიმდევრულ ხედს, რომელიც გამორიცხავს ჩაკეტილ რიგებს. ის არ ადგენს სრულ მარაგის რაოდენობას ან სამართლიან რიგს, ვრცელდება მხოლოდ რიგის დონის საკეტებზე და არ არის უსაფრთხო განცხადებებზე დაფუძნებული რეპლიკაციისთვის.
  • წყაროს მაგალითი მოიცავს expires_at-ს, მაგრამ Shopify არ აღწერს MySQL-ის ვადის გასვლის გასუფთავების ალგორითმს. ვიდეოს გამოშვების/ვადის გასვლის ფილიალი არის განმარტებითი სასიცოცხლო ციკლის მოთხოვნა.
  • კავშირის შეკავების დრო სხვა გადახდის კოდში იყო საბოლოო გამტარუნარიანობის ბოთლ넥ი. Shopify-მ ორივე სისტემა ჩრდილოვანი წერით დაწერა, შეადარა შედეგები და თანდათან გადავიდა Redis-ის „მოკვლის გადამრთველის“ უკუქცევით.

ნათარგმნი ტრანსკრიპტი

ნათარგმნია ორიგინალური ინგლისური ნარატივიდან. ხელმისაწვდომი აუდიო და სუბტიტრები კონტროლდება YouTube-ის მიერ.

რატომ გადავიტანოთ რეზერვაციები MySQL-ში?

0:00 გადახდას სჭირდება Redis, რომ სწრაფად დარჩეს. Shopify-მ ინვენტარის რეზერვაციები MySQL-ში გადაიტანა თითოეული ერთეულისთვის თითო რიგის გამოყენებით შეზღუდული პული. რატომ ავირჩიოთ MySQL? როგორ გამოვტოვოთ საკეტები უსაფრთხოდ? ეს არის The Daily Diff, კაპოტის ქვეშ. და რატომ მაინც მიაღწია სწრაფმა მოთხოვნებმა ჭერს? Shopify არის კომერციული პლატფორმა ონლაინ და პირადად გაყიდვისთვის. Redis არის მეხსიერებაში არსებული მონაცემთა საცავი.

0:21 MySQL არის რელაციური მონაცემთა ბაზა და Shopify უკვე ინახავდა თავის ინვენტარის აღრიცხვას იქ. რეზერვაცია მოკლედ იკავებს მარაგს, სანამ მყიდველი იხდის.

რატომ იყო ორი მაღაზია სარისკო?

0:29 მათი Redis მოდელი ამცირებდა ნივთის მრიცხველს. გადახდილი შეკვეთის მოთხოვნა ნიშნავდა MySQL-ის აღრიცხვის განახლებას და Redis-ის გასუფთავებას. ამ ცალკეულ ჩაწერებს შეეძლო დაეტოვებინა მარაგი ორჯერ გაყიდული ან მიუწვდომელი, როდესაც ის უნდა იყოს გასაყიდი. ძველ მოდელს ასევე აკლდა მდებარეობის ცოდნა. ჩანაცვლებამ უნდა აირჩიოს მარაგი სადმე, რომელსაც შეუძლია შეკვეთის შესრულება. არასწორ კონტინენტზე მდებარე საწყობი ქმნის შესანიშნავ მონაცემთა ბაზის ჩანაწერს და საშინელ მიწოდების დაპირებას. ადრეულ MySQL მცდელობებში გამოიყენებოდა რაოდენობის რიგი, ამიტომ კონკურენტული გადახდები რიგში იდგა

რა ხდება ჩაკეტილი ერთეული?

0:56 იგივე საკეტი. წარმოიდგინეთ ხავერდოვანი თოკი ცხრილის უჯრედის გარშემო. მეტი მუშის დამატება მხოლოდ ახანგრძლივებს რიგს. Shopify-მ შეცვალა დასაკეტი ობიექტი. თითოეული ხელმისაწვდომი ერთეული იღებს საკუთარ რიგს. ჩამკეტი კითხვა გამოტოვებს ერთეულებს, რომლებსაც სხვა ტრანზაქცია იკავებს და ირჩევს სხვა შესაბამის ერთეულებს. სხვადასხვა მუშაკებს შეუძლიათ შეიძინონ სხვადასხვა რიგები, ხოლო ცხელი მრიცხველი მათ გზაზე არ დგება.

რა ხდება, როდესაც პული ცარიელდება?

1:15 ეს პული შეზღუდულია ათასი რიგით თითოეული ნივთისა და მდებარეობისთვის. შევსება აღრიცხვიდან ხორციელდება. თუ ის დაცარიელდება, რეზერვი გზა ახორციელებს შიდა შევსებას, კონკურენტული მოთხოვნებით ელოდება შევსების საკეტის მიღმა. ცარიელი პული არ ნიშნავს ცარიელ საწყობს. რეზერვი შლის არჩეულ პულის რიგებს, შემდეგ ჩასვამს რეზერვაციის ჩანაწერებს ტრანზაქცია. Commit ათავისუფლებს მონაცემთა ბაზის საკეტებს.

1:35 Rollback აუქმებს ცვლილებებს. რეზერვაცია გადახდის დამუშავებას გადაურჩება, როგორც შენახული მდგომარეობა. წარმატებული გადახდა აცხადებს აღრიცხვას და ატომურად შლის რეზერვაციას. მონაცემთა ბაზის საკეტებს არასდროს სჭირდებათ გადახდის ფორმის ძიება. მათი კომპოზიტური პირველადი გასაღები იწყება მაღაზიით, ნივთით, ჯგუფით, შემდეგ ერთეულის იდენტობით. ძიების შესატყვისმა შეამცირა ინდექსის ჩაკეტვა მათ პროტოტიპში. ისინი ასევე იყენებენ წაკითხულ კომიტირებულს, რათა თავიდან აიცილონ ხარვეზის საკეტები, რომლებიც ბლოკავდა პულის

1:57 შევსებას და თანმიმდევრულ ცხრილის წესრიგს ციკლური ლოდინის თავიდან ასაცილებლად. გამოქვეყნებული მაგალითი აღწერს ვადის გასვლის დროს. მიტოვებული გადახდებისთვის მარაგი საბოლოოდ უნდა გათავისუფლდეს, თორემ საყიდლების კალათა გახდება მეპატრონე. Shopify-ის პოსტი ამ გასუფთავების ალგორითმს დაუზუსტებელს ტოვებს, ამიტომ ეს დიაგრამა აჩვენებს სასიცოცხლო ციკლის მოთხოვნას. აი, დაჭერა.

რას ტოვებს SKIP LOCKED?

2:14 Skip locked გამორიცხავს ჩაკეტილ რიგებს, ამიტომ სახელმძღვანელო მის შედეგს არათანმიმდევრულ ხედვას უწოდებს. ის არ იძლევა არც სრულ მარაგის რაოდენობას და არც სამართლიან რიგს. შეინახეთ ხელმისაწვდომობის გადაწყვეტილება და შევსების წესები მის გარშემო.

სად იყო რეალური ჭერი?

2:26 და ის ჭერი? სხვა გადახდის კოდი მონაცემთა ბაზის კავშირებს ზედმეტად დიდხანს აჩერებდა. Shopify-მ მონიშნა გამომძახებლები და გაზომა კავშირის შეკავების დრო, შემდეგ გაასუფთავა გადახდის გზა და გადახედა თემების კონკურენციას. სწრაფი მოთხოვნები მაინც შეიძლება რიგში დადგეს მოთხოვნის მიღმა.

რატომ გამოვიტანდი ამ დიზაინს?

2:38 მათ ორივე სისტემა ჩრდილოვანი წერით დაწერეს, Redis ავტორიტეტული, შეადარეს შედეგები, შემდეგ თანდათან გადავიდნენ „მოკვლის გადამრთველით“. ჩემი ვერდიქტია SHIP IT. მე გამოვგზავნიდი გაზიარებულ ტრანზაქციის საზღვარს და ამ უკუქცევად განლაგებას, მთელი გადახდის გზის ინსტრუმენტირებით. გაქვთ შეკითხვა ამის შესახებ? დატოვეთ კომენტარებში. და ეს არის დღევანდელი განსხვავება.

2:54 მე ვარ ნიკო Axrisi-დან. პასუხისმგებლობით შეაერთეთ.

წყაროები

  1. We replaced Redis with MySQL for inventory reservations—and it scaledShopify Engineering — Emilie Noel
  2. Simplified reservation SQL embedded in Shopify's articleShopify Engineering / CourtneySymons on GitHub Gist
  3. MySQL 8.0 — Locking ReadsOracle / MySQL Reference Manual
  4. MySQL 8.0 — Transaction Isolation LevelsOracle / MySQL Reference Manual
  5. What Is Shopify and How Does It Work?Shopify
  6. Redis quick startsRedis documentation
  7. What is MySQL?Oracle / MySQL Reference Manual

მსგავსი ვიდეოები

under-the-hood · ka · 11 ოქტ. 2026

Stripe იმახსოვრებს თქვენს მოთხოვნას, როდესაც პასუხი ქრება

ტაიმაუტმა შეიძლება გაურკვეველი დატოვოს შეკვეთა სერვერის მიერ ოპერაციის დასრულების შემდეგ. ეს "კულუარული" განმარტება იყენებს Stripe API v1-ის დოკუმენტირებულ იდემპოტენტურობის კონტრაქტს, რათა აჩვენოს ოპე

2:54 ↗
under-the-hood · ka · 24 სექ. 2026

SAML, შიგნიდან: ხელმოწერა წერილის შიგნით

SAML თითქმის ყველა სამუშაო აპლიკაციაში გირთავთ, მისი ხელმოწერა კი XML-ის შიგნითაა, რომელსაც ის აწერს ხელს. შიგნიდან: შესვლის „ცეკვა“ აპლიკაციას, ბრაუზერსა და იდენტობის პროვაიდერს შორის, როგორ გამოიყურ

3:02 ↗
under-the-hood · ka · 23 სექ. 2026

როცა მოდელი კვდება, შიგნიდან

AI მოდელი არ კვდება — მას ეძლევა გათიშვის თარიღი, და მეორე დილით, თქვენი API ზარი აბრუნებს 404-ს: "მოდელი მოძველებულია, მეტი გაიგეთ აქ." შიგნიდან: ოთხ-მდგომარეობიანი მილსადენი (აქტიური → მოძველებული →

3:15 ↗
under-the-hood · ka · 21 სექ. 2026

კლოდმა RSA-896 დაშალა. აი, როგორ იშლება RSA სინამდვილეში

19 სექტემბერს Anthropic-ის ინჟინერმა დაშალა RSA-896 — 270-ნიშნა გამოწვევის რიცხვი — Claude-ის, ღია კოდის CADO-NFS საცრის GPU პორტის და ~30 GPU-წლის გამოყენებით 2,048 უმოქმედო GPU-ზე ათი დღის განმავლობ

3:39 ↗