Memcached का उपयोग करना: डेटाबेस को अपडेट करते समय कैश को अपडेट करना अच्छा अभ्यास है?


13

यह प्रश्न वास्तुकला में सर्वोत्तम प्रथाओं के बारे में है।

हमारे वर्तमान वास्तुकला

मेरे पास एक PHP वर्ग है जो उपयोगकर्ता जानकारी के लिए MySQL तक पहुँचता है। चलो बुलावा आया UserUserकई बार पहुँचा जाता है, इसलिए हमने लोड कम करने के लिए कैशिंग की परतों को लागू किया है।

पहली परत वह है जिसे हम "प्रति अनुरोध" कैश कहते हैं। MySQL से डेटा पुनर्प्राप्त होने के बाद, हम डेटा को एक निजी संपत्ति में संग्रहीत करते हैं User। डेटा का कोई भी बाद का अनुरोध MySQL से डेटा को फिर से अनुरोध करने के बजाय संपत्ति लौटाता है।

चूंकि वेब अनुरोध एक प्रति-अनुरोध के आधार पर रहता है और मर जाता है, यह कैश केवल एक अनुरोध में एक से अधिक बार MySQL तक पहुंचने से रोकता है।

हमारी दूसरी परत मेमकेच्ड है। जब निजी संपत्ति खाली होती है, तो हम सबसे पहले डेटा के लिए मेमक्लेड की जांच करते हैं। यदि Memcached खाली है तो हम डेटा के लिए MySQL की क्वेरी करते हैं, Memcached को अपडेट करते हैं, और की निजी संपत्ति को अपडेट करते हैं User

प्रश्न

हमारा आवेदन एक खेल है, और कभी-कभी यह जरूरी है कि कुछ डेटा यथासंभव अद्यतित हों। लगभग पांच मिनट की अवधि में, उपयोगकर्ता डेटा के लिए एक रीड रिक्वेस्ट 10 या 11 बार हो सकता है; तब एक अद्यतन हो सकता है। बाद में पढ़े गए अनुरोधों को अद्यतित होना चाहिए या खेल यांत्रिकी विफल होना चाहिए।

इसलिए, हमने जो किया है वह कोड का एक टुकड़ा है जिसे डेटाबेस अपडेट होने पर निष्पादित किया जाता है। यह कोड अपडेट किए गए डेटा के साथ Memcached में कुंजी सेट करता है, इसलिए Memcached के सभी बाद के अनुरोध आज तक हैं।

क्या यह इष्टतम है? क्या इस तरह के "जीवित कैश" को बनाए रखने की कोशिश करते समय कोई प्रदर्शन चिंता या अन्य "गोच" हमें पता होना चाहिए?


डेटा को हटाने और फिर से जोड़ने के लिए इसका क्या करना है?
माइक नाकिस

प्रश्न शीर्षक को स्पष्ट किया।
स्टीफन

कैश्ड डेटा की समय सीमा समाप्त क्यों नहीं होती है? इसे अपडेट करने का मतलब है कि आपको यह सुनिश्चित करने की आवश्यकता होगी कि अपडेट बनाए रखा जाए (ताकि यदि नए डेटा को इस तरह अपडेट करना पड़े, तो आपको अपडेट को जारी रखना होगा)। कैश को समाप्त करने का मतलब है कि डेटाबेस से सब कुछ नया खींचा गया है --- और किसी भी नए अपडेट को अपडेट कोड में नए बदलाव की आवश्यकता नहीं है। नकारात्मक पक्ष यह है कि डेटाबेस लोड अधिक हो सकता है।
पीटर के।

@Peter हाँ, हमने इसके बारे में भी सोचा। यदि हमारे वर्तमान दृष्टिकोण के साथ कोई अन्य समस्या नहीं आती है, तो हम इसके साथ चिपके रहेंगे। अन्यथा हम आपके बताए अनुसार चल सकते हैं।
स्टीफन

1
@ स्टेपेन आप जिस दृष्टिकोण का वर्णन करते हैं उसे "लिखो कैश के माध्यम से" कहा जाता है, और एक काफी सामान्य दृष्टिकोण है।
श्रीपति कृष्णन

जवाबों:


10

मेरी अनुशंसा है कि आप कैश के लिए अपनी उपयोग प्रोफ़ाइल और अपनी आवश्यकताओं को देखें।

मैं कोई कारण नहीं देख सकता कि आप मेमेल्डेड में बासी डेटा क्यों छोड़ेंगे। मुझे लगता है कि आपने सही तरीका चुना है: DB को अपडेट करें।

किसी भी स्थिति में, आपको अपने DB अपडेट (जो आपने किया है) पर एक आवरण की आवश्यकता है। DB और इन-रैम में उपयोगकर्ता को अपडेट करने के लिए आपके कोड को मेमेकैक्ड, या मेम्केड में एक समाप्ति की ओर एक पुश भी करना चाहिए।

उदाहरण के लिए - यदि आपके उपयोगकर्ता आमतौर पर लॉग ऑफ के भाग के अनुसार सत्र के अनुसार एक बार अपडेट करते हैं, तो कैश में डेटा को अपडेट करने के लिए बहुत अधिक बिंदु नहीं हैं (जैसे उच्च स्कोर कुल) - आपको इसे सीधे समाप्त करना चाहिए।

यदि वे डेटा को अपडेट करने जा रहे हैं (जैसे वर्तमान गेम स्थिति) और फिर 0.2 सेकंड बाद आपको तत्काल PHP पेज हिट होगा जो डेटा का अनुरोध करने जा रहा है, तो आप इसे कैश में ताज़ा करना चाहेंगे।


3

मैं इसके बारे में बिल्कुल नहीं बताऊँगा जैसे आपने रेखांकित किया है। आपको यह तय करने की आवश्यकता है कि क्या आपने वास्तव में अप-टू-डेट डेटा की आवश्यकता है। फिर, यदि आपको इसकी आवश्यकता है, तो तय करें कि डेटा के किन हिस्सों को हर समय अप-टू-डेट होना चाहिए और उन्हें उन चीजों से अलग करना चाहिए जो आपके आर्किटेक्चर में कैश्ड हो सकते हैं।

उदाहरण के लिए, आप संभवतः अपने उपयोगकर्ता के ईमेल पते को अपडेट करना चाहते हैं जैसे ही वे इसे बदलते हैं, इसलिए आप गलत पते पर मेल नहीं भेजते हैं, लेकिन यह संभावना नहीं है कि उपयोगकर्ता की जन्म तिथि या उपनाम पूरी तरह से होने की आवश्यकता है एक सभ्य उपयोगकर्ता अनुभव प्रदान करने के लिए अप-टू-डेट। (एनबी मैं एक गेम-आर्किटेक्चर उदाहरण का उपयोग नहीं कर रहा हूं क्योंकि मुझे नहीं पता कि इसे किस तरह का खेल करना है, और मुझे लगता है कि यह समझना काफी आसान है)।

इस तरह आपके पास डेटा के दो स्पष्ट सेट हैं: शॉर्ट- और लॉन्ग-टर्म कैशेबल डेटा। आप शायद एक मिनट की कैश अवधि या छोटी अवधि के डेटा पर दूर हो सकते हैं, बस डीबी पर लोड को राहत देने के लिए, लेकिन लंबी अवधि के डेटा को कैश में एक स्लाइडिंग अवधि पर छोड़ दिया जा सकता है जब तक कि यह हो उपयोग किया गया।

फिर आपको अपडेट से निपटने की आवश्यकता है। मैं पहली बार डेट से बाहर होने पर कैश से आइटम निकालने के लिए डीबी ट्रिगर का उपयोग करना चाहूंगा। यह अगली बार जब आप डेटा का अनुरोध करते हैं, तो कैश में कुछ स्थान खाली करने पर आपकी व्यावसायिक परत को कैश ट्रिगर करने के लिए मजबूर करेगा यदि डेटा का उपयोग नहीं किया जा रहा है (उदाहरण के लिए यदि कोई उपयोगकर्ता अपना ईमेल पता बदलता है तो तुरंत लॉग आउट करता है) । यदि यह UI में प्रदर्शन समस्याओं का कारण बनने वाला है (यानी कैश रिफ्रेश के लिए प्रतीक्षा करते समय बहुत अधिक अंतराल का परिचय दें) तो आप कैश से आइटम को हटाए जाने के बाद बस कैश कॉल को ट्रिगर कर सकते हैं। मैं डेटा के इस छोटे से सेट के लिए DB पढ़ने के समय को अनुकूलित करने पर भी ध्यान देना चाहूंगा, यह सुनिश्चित करने के लिए कि कैश को ताज़ा करने में कोई भी अंतराल कम से कम है (यह आसान होना चाहिए क्योंकि आपको केवल डेटा लोड करने की आवश्यकता है जो आपको वास्तव में चाहिए)।

किसी भी परिस्थिति में, मैं क्या नहीं करूंगा, कैश भरने का एक अतिरिक्त तरीका जोड़ रहा हूं, क्योंकि तब आपको कॉल (और एपीआई हुक आदि) को दो स्थानों पर बनाए रखने की आवश्यकता होगी।

गोचैट्स के लिए, मुख्य बात यह है कि अगर आप सीधे कैश में लिख रहे हैं तो आपको सावधान रहना होगा। यदि कई थ्रेड्स आपके मौन अद्यतन को पढ़ने के दौरान पढ़ने की कोशिश करते हैं, तो आपके पास कुछ गंभीर अमान्य डेटा समस्याएँ हो सकती हैं, जो डेटा को अप-टू-डेट पहले स्थान पर रखने की कोशिश करने के बिंदु को परास्त कर देंगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.