← ყველა სტატია

ლაგი ნულზე ჩამოვიდა, მაგრამ არაფერი გამოსწორებულა: Kafka-ს გაჭედილი კონსიუმერი, დამალული group.id-ის გადარქმევით

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

Gambchamp-ის ერთ-ერთ პროდუქტის პლატფორმაზე კონსიუმერის ლაგის გრაფიკი ხუთ დღეს იზრდებოდა დაახლოებით 80 000 შეტყობინებამდე — შემდეგ კი ნულზე ჩამოვარდა და სწორ ხაზად დარჩა. ჩანდა, რომ პრობლემა თავისით წავიდა. ამავდროულად პანელი „ჯამური ლაგი“ უარყოფით რიცხვს აჩვენებდა, „აქტიური ჯგუფები“ კი — ერთს, მაშინ როცა კლასტერში ათობით ცოცხალი ჯგუფია.

სამი რამ, რომელთაგან თითოეული ნორმალურად გამოიყურებოდა, ერთდროულად იყო გაფუჭებული.

პირველი ფენა: კონსიუმერი ცოცხალია და არაფერს აკეთებს

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

სიმართლე თავად Kafka-მ მოგვცა, ექსპორტერის გვერდის ავლით:

kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group <group>

CURRENT-OFFSET, რომელიც არ იცვლება მზარდი LOG-END-OFFSET-ის დროს, გაჭედილი კონსიუმერია, რაც არ უნდა თქვას ჯგუფის წევრობამ.

მეორე ფენა: ნული არ არის გამოჯანმრთელება

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

ლაგის ალერტმა დაინახა, რომ სერია გაქრა, და დაიხურა. კიდევ სამი დღე წესი არაფერს უყურებდა, გრაფიკი კი ჯანმრთელად გამოიყურებოდა, რადგან მასზე არაფერი იყო.

მესამე ფენა: უარყოფითი ლაგი

kafka-exporter აბრუნებს lag = -1-ს პარტიციებისთვის committed offset-ის გარეშე — იქ, სადაც თავად Kafka აჩვენებს LAG = "-". პანელი, რომელიც ლაგს აჯამებდა, მინუსში გადიოდა, ალერტის ზღვარი კი ჩუმად იძვრებოდა ასეთი პარტიციების რაოდენობით.

ამას დაემატა, რომ თავად აპლიკაციის კონსიუმერების მეტრიკები არსებობდა, მაგრამ არ გროვდებოდა: ჩარტი მეტრიკების პორტად 9001-ს აცხადებდა, აპლიკაცია კი 9006-ს უსმენდა.

გამოსწორებები

  • რეალური პორტის scrape. vmagent-ის relabel დეკლარირებულ პორტს დედუბლიკაციისთვის ტოვებს, მაგრამ მისამართს იმ პორტზე გადაწერს, რომელსაც აპლიკაცია რეალურად უსმენს.
  • Blacklist whitelist-ის ნაცვლად. --group.filter=.* პლუს პოდზე მიბმული ეფემერული ჯგუფების გამორიცხვა. სახელით whitelist პირველივე გადარქმევაზე იშლება — სწორედ ამან დაგვაბრმავა.
  • clamp_min(..., 0) ლაგის პანელებში. შლის -1-ს და სერიას ინარჩუნებს; ფილტრი > 0 სერიას მთლიანად გადააგდებდა.
  • ალერტი კლიენტის მეტრიკაზე. highwater - position თავად კონსიუმერისგან არ არის დამოკიდებული არც ჯგუფების დასახელებაზე, არც ექსპორტერის ფილტრზე.

დასკვნები

  • ყოველ ზღვრულ ალერტს სჭირდება წყვილი absent(). თორემ მეტრიკის გაქრობა გამოჯანმრთელებად იკითხება — ზუსტად ეს მოხდა.
  • Whitelist მეტრიკების ექსპორტერში — ნაღმია, რომელიც შემდეგ გადარქმევას ელოდება.
  • LAG = "-" ნული არ არის, ექსპორტერის -1 კი ის რიცხვი არ არის, რომლის შეჯამებაც შეიძლება.
  • შეამოწმეთ, რომ ჩარტში დეკლარირებული პორტი ის პორტია, რომელსაც აპლიკაცია უსმენს.
  • ერთი არხი ყველა ალერტისთვის ალერტინგის არარსებობაა: ხუთდღიანი firing ათასობით შეტყობინებაში ჩაიძირა. მფლობელი და SLA warning-ებისთვის კიდევ ერთ წესზე მნიშვნელოვანია.