Cloudflare D1 თუ Turso: ცუდ ინდექსს rows-read ბილინგი აძვირებს

|ავტორი: QUASA-ს სარედაქციო გუნდი|6 წთ საკითხავი
Cloudflare D1 თუ Turso: ცუდ ინდექსს rows-read ბილინგი აძვირებს

თუ აპლიკაცია მხოლოდ Cloudflare Workers-ზე მუშაობს, D1 ჩვეულებრივ უფრო პირდაპირი არჩევანია: Worker ბაზას binding-ით უკავშირდება. თუ კოდი მოწყობილობაზე ან საკუთარ სერვერზეც სრულდება და მონაცემთა ბაზის მდგრადი ლოკალური ფაილი აქვს, Turso-ს embedded replica წაკითხვის ქსელურ გზას ამოკლებს. ორივე არჩევანში მოთხოვნის გეგმა მნიშვნელოვანია: D1-ის ბილინგის წესით ითვლება მოთხოვნის მიერ წაკითხული მწკრივები და არა მხოლოდ პასუხში დაბრუნებული ჩანაწერები. ამიტომ შეუსაბამო ან არმყოფმა ინდექსმა მცირე შედეგის მქონე მოთხოვნაც შეიძლება გააძვიროს.

Turso-ს embedded replica-ის აღწერის მიხედვით, წაკითხვა ლოკალური ფაილიდან სრულდება, ხოლო ნაგულისხმევ რეჟიმში ჩაწერა Cloud-ის ძირითად ბაზაში იგზავნება. წარმატებული ჩაწერა გამომგზავნ ასლში აისახება; სხვა ასლები ცვლილებას სინქრონიზაციის შემდეგ ხედავენ. ეს Turso-ს მიმზიდველს ხდის ხშირი წაკითხვისთვის, მაგრამ ლოკალური პასუხის სისწრაფე და მონაცემის სიახლე ცალ-ცალკე უნდა შეფასდეს.

სად სრულდება მოთხოვნა

Turso-ს ლოკალური SQLite ასლი მოწყობილობაზე ხელმისაწვდომია მაშინაც, როცა სინქრონიზაცია დროებით შეწყვეტილია.

D1-ში Worker-ის binding მონაცემთა ბაზასთან წვდომის უშუალო გზაა. აპლიკაციას Turso-ს მსგავსი ცალკე კავშირის URL-ისა და ტოკენის გამართვა არ სჭირდება. D1-ის რეგიონული read replica მოთხოვნას მომხმარებელთან უფრო ახლოს შეიძლება მოემსახუროს, მაგრამ SQL მაინც მონაცემთა ბაზის ქსელურ ასლზე სრულდება და არა თვით Worker-ის მუდმივ ლოკალურ ფაილში. ეს განსხვავება მნიშვნელოვანია მაშინ, როცა წაკითხვის დაყოვნება არჩევანის მთავარი მიზეზია.

Turso Worker-იდანაც ხელმისაწვდომია: Cloudflare-ის დაკავშირების ინსტრუქცია დისტანციურ libSQL კლიენტს, ბაზის URL-სა და ავტორიზაციის ტოკენს იყენებს. ასეთი კავშირი Turso-ს embedded replica-ის ლოკალურ წაკითხვას არ უდრის. ლოკალურ ასლს ფაილური სისტემა სჭირდება; მდგრადი ფაილის არმქონე serverless გარემოში მისი დაყენება ვერ იმუშავებს. ამიტომ Workers API-სა და მობილურ აპს ერთი და იგივე Turso ბაზასთან კავშირი შეიძლება ჰქონდეს, მაგრამ განსხვავებული დაყოვნება და სინქრონიზაციის ქცევა ექნებათ.

მრავალ გარემოში Turso-ს უპირატესობა სწორედ ამ განაწილებაშია: სერვერს ან მოწყობილობას საკუთარი ასლიდან კითხვა შეუძლია, Worker კი Cloud-ის ბაზას დისტანციურად უკავშირდება. D1 უფრო მარტივია, როდესაც მთელი მოთხოვნის გზა Workers-ში რჩება. თუ მონაცემთა ბაზას სხვა runtime-იდანაც მიმართავენ, D1-ის binding-ით მიღებული სიმარტივე იმ დამატებითი წვდომის გზებთან ერთად უნდა შეფასდეს, რომლებიც ამ გარემოებს სჭირდება.

Read-heavy სცენარი: ლოკალური პასუხი სრულ სკანირებას ვერ შველის

წარმოიდგინეთ პირობითი კატალოგი, სადაც მომხმარებელი ხშირად ფილტრავს ჩანაწერებს კატეგორიისა და სტატუსის მიხედვით, ახალი ჩანაწერები კი იშვიათად ემატება. მუდმივი ფაილის მქონე აპში Turso-ს embedded replica ასეთ კითხვას ადგილზე ასრულებს. D1-ის რეგიონულ ასლსაც შეუძლია ქსელური მანძილის შემცირება, თუ რეპლიკაცია გამოყენებულია. ამ ორი გზის დაყოვნება ერთი და იმავე საზომით არ უნდა გამოცხადდეს: ერთი ლოკალური ფაილის კითხვაა, მეორე — რეგიონულ ბაზასთან მიმართვა.

ფილტრისთვის გამოსადეგი ინდექსის გარეშე მოთხოვნამ შეიძლება მთელი ცხრილი გაიაროს, თუნდაც მხოლოდ რამდენიმე ჩანაწერი დააბრუნოს. D1-ში გავლილი მწკრივები rows_read მაჩვენებელში ხვდება. Turso-ს ლოკალურ ასლზე იგივე სკანირება Cloud-თან ყოველი კითხვისას კავშირს არ საჭიროებს, მაგრამ მოწყობილობის გამოთვლით რესურსსა და დროს მაინც ხარჯავს. დისტანციური Turso მოთხოვნისა და embedded replica-ის ლოკალური კითხვის ერთ ბილინგის ოპერაციად მიჩნევა მცდარი შედარება იქნებოდა.

ინდექსის სახელის არსებობაც საკმარისი არ არის. თუ მოთხოვნა ერთდროულად კატეგორიასა და სტატუსს ამოწმებს, მხოლოდ ერთ სვეტზე შექმნილი ინდექსის გამოყენების შემდეგ ბაზას შესაძლოა დარჩენილი ჩანაწერების დამატებითი შემოწმება დასჭირდეს. მოთხოვნის რეალური გეგმა აჩვენებს, სრული SCAN სრულდება თუ მიზნობრივი SEARCH ინდექსით. D1-ის პასუხის meta.rows_read კი უშუალოდ აჩვენებს, რამდენი მწკრივი დაითვალა კონკრეტულ შესრულებაზე; ეს უფრო სანდო საწყისია, ვიდრე დაბრუნებული შედეგების რაოდენობა.

როგორ გადაიქცევა სკანირება თვიურ ხარჯად

თვიური rows read გამოითვლება ასე: თითოეული ტიპის მოთხოვნის თვიური გამოძახებები გამრავლდეს მის საშუალო დასკანირებულ მწკრივებზე, შემდეგ კი შედეგები შეიკრიბოს. სხვადასხვა ფილტრს, ცხრილის ზომასა და ინდექსს განსხვავებული მაჩვენებელი აქვს, ამიტომ ერთი „საშუალო მოთხოვნა“ ხარჯს ადვილად ფარავს. D1-ში ფორმულას შეიძლება დაუმატოთ rows written და შენახვის მოცულობა; Worker-ის შესრულების საფასურიც ცალკე რჩება, ხოლო D1 მონაცემთა გატანას ცალკე არ აბეგრებს.

პირობითად, ცხრილში 100 000 მწკრივია და ერთ ფილტრიან მოთხოვნას დღეში 30 000-ჯერ იძახებენ. თუ თითოეული გამოძახება სრულ ცხრილს სკანირებს, 30-დღიან თვეში ეს 90 მილიარდ წაკითხულ მწკრივს იძლევა. თუ შეცვლილი მოთხოვნის გეგმა საშუალოდ 20 მწკრივს კითხულობს, იმავე დატვირთვის შედეგი 18 მილიონია. ეს არის არითმეტიკული მაგალითი და არა რომელიმე სერვისის გაზომილი წარმადობა; რეალურ ხარჯში სწორედ გაზომილი rows_read უნდა ჩაიწეროს.

Turso-ს თვიური ტარიფების ცხრილში Free გეგმას 500 მილიონი წაკითხული მწკრივი აქვს, Developer გეგმას კი $5.99-ად თვეში 2.5 მილიარდი; გეგმებში ასევე ცალკეა ჩაწერილი მწკრივები, შენახვა და სინქრონიზაციის მოცულობა. ამდენად, Cloud-ში შესრულებული მოთხოვნების rows-read შეფასებას embedded replica-ების სინქრონიზაციისა და შენახვის შეფასებაც უნდა დაემატოს. უმოქმედო ბაზა გამოყენებით წაკითხვასა და ჩაწერას არ ქმნის, მაგრამ შენახვის რესურსს მაინც იკავებს.

ინდექსის დამატება მხოლოდ წაკითხვის მხარეს არ ცვლის. ინდექსირებული სვეტის შეცვლისას ბაზა ინდექსსაც აახლებს, ხოლო ინდექსი შენახვის ადგილს მოითხოვს. ხშირი ფილტრიანი კითხვა ამ დამატებით სამუშაოს ხშირად ამართლებს; იშვიათი კითხვა და მუდმივი ჩაწერა — შესაძლოა ნაკლებად. ამ მიზეზით read-heavy და write-heavy დატვირთვებისთვის ერთი და იგივე ინდექსების ნაკრები ავტომატურად საუკეთესო ვერ იქნება.

Write-heavy სცენარი: ჩაწერა ძირითად ბაზამდე მიდის

ახლა წარმოიდგინეთ შეკვეთების პირობითი ნაკადი: ახალი ჩანაწერები ხშირად ემატება და მომხმარებელს მათი სწრაფად ნახვა სურს. D1-ის რეგიონული read replica მხოლოდ კითხვის გზას ამოკლებს; ჩაწერა ძირითად ბაზაში სრულდება. Turso-ს embedded replica-ის ნაგულისხმევ რეჟიმშიც ჩაწერა Cloud-ის ძირითად ბაზამდე მიდის. ამიტომ ლოკალური კითხვის მცირე დაყოვნება ჩაწერის ქსელურ გზას ვერ აუქმებს, ხოლო ხშირი ჩაწერა ინდექსების განახლების ფასსაც ზრდის.

ამ სცენარში პირველი კითხვა ის არის, სად უნდა დასრულდეს ჩაწერა წარმატებით. თუ ოპერაციას Cloud-ის ძირითად ბაზაში დაუყოვნებლივ დაფიქსირება სჭირდება, ორივე არქიტექტურაში უნდა გაითვალისწინოთ გზა ამ ბაზამდე. თუ აპს კავშირის გარეშეც სჭირდება ჩაწერა, Turso-ს embedded replica-ში არსებობს ცალკე offline პარამეტრი, ხოლო ახალი Turso Sync ლოკალურ ჩაწერასა და აშკარა push/pull სინქრონიზაციას იყენებს. ეს რეჟიმები ნაგულისხმევი დისტანციური ჩაწერის ქცევისგან განსხვავდება და მათი კონფლიქტებისა და სინქრონიზაციის მოთხოვნები ცალკე გადაწყვეტილებაა.

მრავალი ხშირად ცვალებადი სვეტის ინდექსირება შეიძლება განსაკუთრებით ძვირი აღმოჩნდეს, თუ აპი მათზე იშვიათად ფილტრავს. პირიქით, ხშირად გამოძახებული ძიებისთვის ერთი შესაფერისი ინდექსი სკანირებას მკვეთრად შეამცირებს. არჩევანი დამოკიდებულია არა მხოლოდ read/write მოთხოვნების რაოდენობაზე, არამედ თითოეული მოთხოვნის მიერ გავლილ მწკრივებზე, ჩაწერის გზასა და იმ დროზე, რომლის განმავლობაშიც სხვა ასლებს ძველი მონაცემის ჩვენება შეუძლიათ.

Consistency-ის გადაწყვეტილების ხე

Cloudflare D1-ის რეგიონული ასლი ახალ ჩანაწერს სინქრონიზაციის შემდეგ აჩვენებს.

D1-ის გლობალური რეპლიკაციის წესებით read replica ასინქრონულად ახლდება; მის გამოსაყენებლად Workers binding-ის Sessions API საჭიროა, სხვა შემთხვევაში მოთხოვნები ძირითად ბაზაში სრულდება. Session-ის bookmark მომდევნო კითხვას სულ მცირე უკვე ნანახ ვერსიამდე მიჰყავს. ეს იცავს იმავე მომხმარებლის თანმიმდევრულ კითხვას, თუმცა რეპლიკას საჭირო ვერსიის მიღებამდე ლოდინი შეიძლება დასჭირდეს.

  • თუ კითხვა აუცილებლად ძირითადი ბაზის უახლეს მდგომარეობას მოითხოვს, D1 session დაიწყეთ first-primary პირობით. Turso-ში მოთხოვნა ძირითად Cloud ბაზას მიმართეთ ან ლოკალური ასლი კითხვის წინ განაახლეთ.
  • თუ მომხმარებელმა თავისი წარმატებული ჩაწერა უნდა დაინახოს, D1-ში შეინარჩუნეთ იგივე session ან მომდევნო მოთხოვნას მისი bookmark გადააწოდეთ. Turso-ს embedded replica ნაგულისხმევ რეჟიმში საკუთარ წარმატებულ ჩაწერას ასახავს.
  • თუ სხვა მოწყობილობის ცვლილება მცირე დაგვიანებითაც მისაღებია, რეგიონული D1 replica ან Turso-ს ლოკალური ასლი კითხვის გზას ამოკლებს. Turso-ს სხვა ლოკალურ ასლზე ახალი მონაცემი სინქრონიზაციის შემდეგ გამოჩნდება.

არჩევანის პრაქტიკული საზღვარი ასე იკვეთება: Workers-ში თავმოყრილი API-სთვის D1 ნაკლებ კავშირის მართვას მოითხოვს; მდგრადი ფაილის მქონე მრავალ გარემოში Turso-ს embedded replica ხშირ კითხვას ქსელის გარეშე ასრულებს. საბოლოო გადაწყვეტილება იმ მოთხოვნების სკანირებულ მწკრივებზე, ჩაწერის წილზე და საჭირო consistency-ზე დგას. სწორედ ამ სამის ერთად შეფასება აჩვენებს, გადაიქცევა თუ არა სწრაფი კითხვა მისაღებ თვიურ ხარჯად.

ასევე წაიკითხეთ:

გაზიარება:

გამოიწერეთ ჩვენი ბიულეტენი

მიიღეთ უახლესი ამბები Web3-ის, AI-სა და კრიპტოს შესახებ პირდაპირ თქვენს ელფოსტაზე.

0