გვერდი, რომელიც ლოკალურ Redis-თან 200 ms-ში პასუხობს, ოთხ წამს იღებს, როგორც კი კლიენტი VPN-ის უკან აღმოჩნდება, მაშინ როცა სერვერის მრიცხველები უმოქმედოდ რჩება. ნელი ჟურნალი არაფერს აჩვენებს ერთ მილიწამზე მეტს, CPU-ის გრაფიკი ბრტყელია და ინსტანსი სხვა კლიენტებს უჩივლელად ემსახურება. შეიცვალა მანძილი და მანძილს ამრავლებს ის, რამდენჯერ ჩერდება და ელოდება თქვენი კოდი. გაიარეთ მოთხოვნის გზა კლიენტიდან გარეთკენ და გადაწყვეტა თითქმის ყოველთვის ნაკლები თანმიმდევრული ლოდინია და არა უფრო სწრაფი სერვერი.

დაიწყეთ კლიენტიდან და არა სერვერის მეტრიკებიდან

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

გაზომეთ თავად გზა, სანამ კოდს შეეხებით. redis-cli -h redis.example.internal --latency უგზავნის განმეორებით PING-ებს და ბეჭდავს მოთხოვნისა და პასუხის საშუალო დროს, რაც თქვენი ხარჯია ერთ გაცვლაზე. გაამრავლეთ ის ერთ მომხმარებლის მოქმედებაში თანმიმდევრული ბრძანებების რაოდენობაზე და მიიღებთ საბოლოო წერტილის ქვედა ზღვარს.

დათვალეთ მიმოქცევები, რომლებიც ერთ მომხმარებლის მოქმედებას ნამდვილად სჭირდება

აიღეთ ერთი საბოლოო წერტილი და თანმიმდევრობით ჩაწერეთ ყოველი Redis გამოძახება, მათ შორის ORM-ში, სესიის შუამავალში ან ფუნქციის დროშის ძიებაში დამალული. ნელი საბოლოო წერტილების უმეტესობა აღმოჩნდება, რომ ოცი ან ოცდაათი გამოძახებას აკეთებს იქ, სადაც სამი საკმარისი იქნებოდა, და დამალულები ჩვეულებრივ უმრავლესობას შეადგენენ.

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

მთავარი რიცხვი თანმიმდევრული ლოდინებია და არა ბრძანებების ჯამი. ერთ პარტიაში ოცდაათი ბრძანება მაინც ერთი ლოდინი ღირს.

დააჯგუფეთ მხოლოდ ის ბრძანებები, რომლებიც ერთმანეთზე არ არიან დამოკიდებული

მილსადენი დამოუკიდებელ ბრძანებებს რიგში აყენებს და პასუხებს თანმიმდევრობით აგროვებს, N ლოდინს ერთად აქცევს. კლიენტების უმეტესობა ამას ცალკე კავშირის რეჟიმის ნაცვლად ბლოკის, უკუგამოძახების ან კონტექსტის მართვის სახით გვთავაზობს, ამიტომ შეამოწმეთ API, რომელსაც თქვენი დაყენებული ვერსია გთავაზობთ. მოგება მიმოქცევის დროსთან ერთად იზრდება და სწორედ ამიტომ აქვს მნიშვნელობა VPN-ზე და თითქმის არ იგრძნობა localhost-ზე.

import redis

r = redis.Redis(host="redis.example.internal", port=6379, socket_timeout=2)
pipe = r.pipeline(transaction=False)
for key in ("user:1001", "user:1002", "user:1003"):
    pipe.get(key)
print(pipe.execute())

გადასცეთ transaction=False, როდესაც მხოლოდ დაჯგუფება გსურთ. ნაგულისხმევად კლიენტი პარტიას MULTI და EXEC-ში ახვევს, რაც მას ატომურად აქცევს და ცვლის, თუ რას შეძლებენ სხვა კლიენტები შენიშვნას შუა გზაზე. ატომურობა სისწორის გადაწყვეტილებაა და არა წარმადობის ღილაკი, და მილსადენი ტრანზაქცია არ არის მხოლოდ იმიტომ, რომ ორივე ამცირებს მიმოქცევებს.

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

შეინახეთ კავშირი ცოცხალი მოქმედებებს შორის

ყოველი ახალი კავშირი იხდის სახელების გარჩევას, TCP ხელის ჩამორთმევას, TLS ხელის ჩამორთმევას და AUTH-ს, ხოლო VPN-ის გავლით თითოეული მათგანი მიმოქცევაა, რომელსაც ვერ დაჯგუფებთ. შექმენით კლიენტი ერთხელ პროცესზე და ხელახლა გამოიყენეთ, ან გამოიყენეთ თქვენი ბიბლიოთეკის მიერ შემოთავაზებული შეზღუდული ზომის აუზი. ყოველ მოთხოვნაზე ხელახალი დაკავშირება ამ სიმპტომის მეორე ყველაზე გავრცელებული მიზეზია ბრძანებაზე ლოდინის შემდეგ.

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

დააყენეთ გამოკვეთილი socket-ის დროის ლიმიტი, რათა გაჭედილი გვირაბი მუშის ჩამოკიდების ნაცვლად სწრაფად ჩავარდეს. შემდეგ დაადასტურეთ, რომ აუზი ნამდვილად ხელახლა გამოიყენება კლიენტში კავშირების შექმნის ჟურნალში ჩაწერით.

განსაზღვრეთ პარტიის ზომა, სანამ ის მეხსიერების პრობლემად იქცევა

Redis ინახავს რიგში მდგარ პასუხებს პარტიის მთელი ხანგრძლივობის განმავლობაში, ხოლო კლიენტი შემდეგ ინახავს გაანალიზებულ შედეგს. ათი ათასი დიდი მნიშვნელობის მილსადენი ქსელურ ლოდინებს ცვლის მეხსიერების ნახტომებზე და ხანგრძლივ პაუზებზე ორივე ბოლოში.

აირჩიეთ პარტიის ზომა პასუხის მოცულობის მიხედვით და არა ბრძანებების რაოდენობის. ერთ პარტიაში რამდენიმე ასეული პატარა ბრძანება ჩვეულებრივ კომფორტულია, ხოლო ასი რამდენიმე კილობაიტიანი დატვირთვა არა. დაყავით ბაიტებისა და რაოდენობის მიხედვით, და შეინახეთ ყოველი პარტია საბოლოო წერტილის რეალური შეყოვნების ბიუჯეტში.

ცვლილების შემდეგ გაზომეთ თავიდან ბოლომდე: redis-cli -h redis.example.internal --latency-history აჩვენებს, სტაბილურია თუ არა თავად გზა, ხოლო თქვენი მოთხოვნების ტაიმერი აჩვენებს, გაუმჯობესდა თუ არა საბოლოო წერტილი. თუ საბოლოო წერტილი ჯერ კიდევ ნელია, მაშინ როცა შეყოვნების ისტორია ბრტყელია, დარჩენილი ხარჯი სერვერის მხარის სამუშაოა ან თქვენი სერიალიზაცია, და შემდეგი ნაბიჯი დამმუშავებლის პროფილია და არა კიდევ ერთი დაჯგუფების ცვლილება.

დაკავშირებული სტატიები