ทุก server ที่รัน app ใช้ AppSignal ส่ง collection ของ samples และ metrics ไป Push API ทุก 30 วินาที
แต่ละ request มี key เราใช้ determine ว่า app ไหนส่งข้อมูลมา เพื่อทำนี้ เราต้อง query database หา app สำหรับแต่ละ incoming request ด้วย 30 พันล้าน requests ต่อเดือน เราพยายามหาวิธีลด queries เพื่อทำให้ AppSignal เร็วขึ้น
เรา implement caching ลด queries บน database clusters ทุกครั้งที่ fetch app จาก database เราเก็บใน Memcached 1 นาที หลัง deploy change นี้ไป production เราพบว่าเราทำ มากกว่า queries ก่อนหน้า ดูเหมือน cache ถูก invalidate บ่อยเกินไป เพื่อหาว่าเกิดที่ไหน เราเพิ่ม custom metrics หาจุดที่ cache invalidated ผิด
มีหลายจุดที่ invalidate cache เช่นเมื่อ push processed time updated หรือเมื่อ detect new namespace
# Update last push processed at time
if app.last_push_processed_at < 5.minutes.ago
app.set(:last_push_processed_at => Time.now)
Rails.cache.delete(cache_key)
end
if namespaces_diff.any?
app.add_to_set(:namespaces => namespaces_diff)
Rails.cache.delete(cache_key)
end
เราเพิ่ม multiple counters determine ว่าคุณของ cache invalidations ไหนเป็นผู้กระทำร้าย ในตัวอย่างนี้เรา increment app.cache.invalidate counter นับ total invalidations และใช้ specific keys อย่าง app.cache.invalidate_push_time และ app.cache.invalidate_namespaces สำหรับ specific invalidations
# Update last push processed at at time
if app.last_push_processed_at < 5.minutes.ago
app.set(:last_push_processed_at => Time.now)
Rails.cache.delete(cache_key)
Appsignal.increment_counter('app.cache.invalidate', 1)
Appsignal.increment_counter('app.cache.invalidate_push_time', 1)
end
if namespaces_diff.any?
app.add_to_set(:namespaces => namespaces_diff)
Rails.cache.delete(cache_key)
Appsignal.increment_counter('app.cache.invalidate', 1)
Appsignal.increment_counter('app.cache.invalidate_namespaces', 1)
end
เพิ่ม custom metrics ข้างต้น เรา graph cache hits over time ได้ ทันทีเห็นว่า cache key ไหนทำให้ queries เพิ่มขึ้น app.cache.invalidate_namespaces key ถูก invalidate สำหรับแต่ละ request
Total number of cacheable requests นับเป็น app.cache.maybe.
หลัง deploy fix สำหรับ issue นี้ จำนวน invalidations ตกเป็นศูนย์ตราบใดที่ namespaces สำหรับ app ไม่ได้ updated
การเพิ่ม custom metrics ทำให้เข้าใจง่ายขึ้นว่าเกิดอะไรขึ้นที่ไหน เมื่อไหร่ และบ่อยแค่ไหน ในกรณีนี้ การรู้จำนวน cache invalidations และแสดงใน readable graph ช่วยหา issue ได้เร็ว แค่เพิ่ม幾บรรทัดโค้ด increment ค่าและสร้าง dashboard
บอกเราถ้ามีคำถามเกี่ยว custom metrics และเราช่วย setup ใน application ของคุณได้ เรายินดีช่วย!