การใช้ Memcached: เป็นการดีหรือไม่ที่จะอัพเดตแคชเมื่อทำการอัพเดตฐานข้อมูล?


13

คำถามนี้เกี่ยวกับหลักปฏิบัติที่ดีที่สุดในสถาปัตยกรรม

สถาปัตยกรรมปัจจุบันของเรา

ฉันมีคลาส PHP ที่เข้าถึง MySQL สำหรับข้อมูลผู้ใช้ Userขอเรียกว่า Userมีการเข้าถึงหลายครั้งดังนั้นเราจึงติดตั้งเลเยอร์ของแคชเพื่อลดภาระ

เลเยอร์แรกคือสิ่งที่เราเรียกว่าแคช "ต่อคำขอ" หลังจากที่ข้อมูลได้รับการเรียกข้อมูลจาก MySQL, Userเราเก็บข้อมูลในทรัพย์สินส่วนตัวของ การร้องขอใด ๆ ที่ตามมาสำหรับข้อมูลจะส่งคืนคุณสมบัติแทนการร้องขอข้อมูลจาก MySQL อีกครั้ง

เนื่องจากคำขอทางเว็บนั้นใช้งานและตายต่อการร้องขอแคชนี้จะป้องกันไม่ให้แอปพลิเคชันเข้าถึง MySQL มากกว่าหนึ่งครั้งในคำขอเดียว

ชั้นที่สองของเราคือ Memcached เมื่อคุณสมบัติส่วนตัวว่างเปล่าก่อนอื่นเราตรวจสอบ Memcached สำหรับข้อมูล หาก Memcached ว่างเรา MySQL แบบสอบถามสำหรับข้อมูลที่ปรับปรุง memcached Userและปรับปรุงทรัพย์สินส่วนตัวของ

คำถาม

แอปพลิเคชันของเราเป็นเกมและบางครั้งจำเป็นที่ข้อมูลบางอย่างจะเป็นข้อมูลล่าสุด ในช่วงเวลาประมาณห้านาทีคำขอการอ่านสำหรับข้อมูลผู้ใช้อาจเกิดขึ้น 10 หรือ 11 ครั้ง; จากนั้นการอัปเดตอาจเกิดขึ้น คำขอการอ่านครั้งต่อไปจะต้องทันสมัยหรือกลไกของเกมล้มเหลว

ดังนั้นสิ่งที่เราทำคือการใช้รหัสที่ดำเนินการเมื่อมีการอัพเดทฐานข้อมูล รหัสนี้ตั้งค่าคีย์ใน Memcached พร้อมข้อมูลที่อัปเดตดังนั้นการร้องขอต่อ Memcached ที่ตามมาทั้งหมดเป็นข้อมูลล่าสุด

สิ่งนี้ดีที่สุดหรือไม่? มีข้อกังวลด้านประสิทธิภาพหรือ "gotchas" อื่น ๆ ที่เราควรทราบเมื่อพยายามรักษา "แคชที่มีชีวิต" แบบนี้หรือไม่?


สิ่งนี้เกี่ยวข้องกับการลบและเพิ่มข้อมูลอีกครั้ง?
Mike Nakis

ชี้แจงชื่อคำถาม
Stephen

ทำไมไม่เพียงแค่หมดอายุข้อมูลแคช? การอัปเดตหมายความว่าคุณจะต้องตรวจสอบให้แน่ใจว่าการอัปเดตนั้นได้รับการปรับปรุง (ดังนั้นหากจำเป็นต้องอัปเดตข้อมูลใหม่ด้วยวิธีนี้คุณจะต้องเปลี่ยนการอัปเดตต่อไป) การหมดอายุแคชหมายความว่าทุกอย่างถูกดึงใหม่จากฐานข้อมูล --- และการอัพเดตใหม่ใด ๆ ไม่จำเป็นต้องมีการเปลี่ยนแปลงใหม่ในการอัพเดทรหัส ข้อเสียคือโหลดฐานข้อมูลอาจจะสูงกว่า
Peter K.

@ Peter ใช่เราก็คิดเช่นกัน หากไม่มีปัญหาอื่น ๆ เกี่ยวกับวิธีการในปัจจุบันของเราเกิดขึ้นเราจะยึดติดกับมัน มิฉะนั้นเราอาจไปกับสิ่งที่คุณอธิบาย
Stephen

1
@Stephen วิธีการที่คุณอธิบายเรียกว่า "Write Through Cache" และเป็นวิธีการทั่วไป
Sripathi Krishnan

คำตอบ:


10

คำแนะนำของฉันคือดูที่โปรไฟล์การใช้งานของคุณและข้อกำหนดสำหรับแคช

ฉันไม่เห็นเหตุผลว่าทำไมคุณถึงทิ้งข้อมูลค้างไว้ใน memcached ฉันคิดว่าคุณได้เลือกวิธีที่ถูกต้องเช่น: อัปเดตฐานข้อมูล

ไม่ว่าในกรณีใดคุณจะต้องมี wrapper ในการอัพเดทฐานข้อมูล (ซึ่งคุณได้ทำไปแล้ว) รหัสของคุณเพื่ออัพเดตผู้ใช้ในฐานข้อมูลและในแรมควรทำการพุชไปยัง memcached หรือหมดอายุใน memcached

ตัวอย่างเช่น - หากผู้ใช้ของคุณทำการอัปเดตหนึ่งครั้งต่อเซสชันโดยเป็นส่วนหนึ่งของการออกจากระบบไม่มีอะไรมากที่จะอัปเดตข้อมูลในแคช (เช่นคะแนนรวมสูง) - คุณควรจะหมดอายุทันที

หาก แต่พวกเขากำลังจะอัปเดตข้อมูล (เช่นสถานะเกมปัจจุบัน) จากนั้น 0.2 วินาทีต่อมาคุณจะพบหน้า PHP ทันทีที่จะขอข้อมูลคุณต้องการให้แคชใหม่


3

ฉันจะไม่ไปเกี่ยวกับเรื่องนี้เหมือนที่คุณอธิบายไว้ สิ่งที่คุณต้องทำคือตัดสินใจว่าจริง ๆ แล้วคุณจำเป็นต้องมีข้อมูลที่ทันสมัย จากนั้นหากคุณต้องการให้ตัดสินใจว่าส่วนใดของข้อมูลที่จำเป็นต้องได้รับการปรับปรุงตลอดเวลาและแยกออกจากสิ่งต่าง ๆ ที่สามารถเก็บไว้ในสถาปัตยกรรมของคุณ

ตัวอย่างเช่นคุณอาจต้องการอัปเดตที่อยู่อีเมลของผู้ใช้ของคุณทันทีที่พวกเขาเปลี่ยนดังนั้นคุณจะไม่ส่งอีเมลไปยังที่อยู่ผิด แต่ไม่น่าเป็นไปได้ว่าวันเกิดหรือนามสกุลของผู้ใช้จะต้องสมบูรณ์ ทันสมัยเพื่อมอบประสบการณ์การใช้งานที่ดี (NB ฉันไม่ได้ใช้ตัวอย่างสถาปัตยกรรมเกมเพราะฉันไม่รู้ว่าเกมแบบไหนที่จะเล็งมันและฉันคิดว่าเกมนี้ค่อนข้างเข้าใจง่าย)

วิธีนี้คุณมีชุดข้อมูลที่ชัดเจนสองชุด ได้แก่ ข้อมูลที่แคชได้ในระยะสั้นและระยะยาว คุณสามารถหนีไปได้ด้วยระยะเวลาแคชหนึ่งนาทีหรือมากกว่านั้นในข้อมูลระยะสั้นเพียงเพื่อลดภาระในฐานข้อมูล แต่ข้อมูลระยะยาวสามารถถูกเก็บไว้ในแคชในช่วงเวลาที่เลื่อนได้ตราบเท่าที่มันยังคงอยู่ ใช้

จากนั้นคุณต้องจัดการกับการปรับปรุง ก่อนอื่นฉันจะดูการใช้ทริกเกอร์ DB เพื่อลบรายการออกจากแคชเมื่อมันล้าสมัย ซึ่งจะบังคับให้ชั้นธุรกิจของคุณเรียกใช้การรีเฟรชแคชในครั้งต่อไปที่ร้องขอข้อมูลทำให้มีพื้นที่ว่างในแคชมากขึ้นหากไม่มีการใช้ข้อมูล (ตัวอย่างเช่นหากผู้ใช้เปลี่ยนที่อยู่อีเมลแล้วออกจากระบบทันที) . หากนี่จะทำให้เกิดปัญหาประสิทธิภาพการทำงานใน UI (เช่นแนะนำล่าช้ามากเกินไปในขณะที่รอการรีเฟรชแคช) จากนั้นคุณสามารถดูเพียงแค่เรียกการเรียกแคชเมื่อรายการถูกลบออกจากแคช ฉันยังดูที่การเพิ่มประสิทธิภาพเวลาอ่าน DB สำหรับชุดข้อมูลขนาดเล็กนี้เพื่อให้แน่ใจว่าความล่าช้าที่เกิดขึ้นในการรีเฟรชแคชนั้นน้อยมาก (นี่ควรจะง่ายกว่าเมื่อคุณต้องการโหลดข้อมูลที่คุณต้องการจริงๆ)

สิ่งที่ฉันจะไม่ทำในกรณีใด ๆ คือการเพิ่มวิธีการเพิ่มเติมในการกรอกแคชแล้วคุณจะต้องรักษาสาย (และ API hooks ฯลฯ ) ในสองสถานที่

สำหรับ gotchas สิ่งสำคัญที่คุณต้องระวังถ้าคุณเขียนไปที่แคชโดยตรงคือการซิงโครไนซ์ หากมีหลายเธรดพยายามอ่านในขณะที่คุณทำการอัปเดตแบบเงียบคุณอาจพบปัญหาข้อมูลที่ไม่ถูกต้องร้ายแรงซึ่งจะทำให้จุดข้อมูลพยายามอัปเดตอยู่เสมอตั้งแต่แรก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.