चतुर कैश निकालना (php 5 + Mongodb + memcached)

प्रस्तावना


आजकल, अत्यधिक भरी हुई परियोजनाओं की एक बड़ी संख्या, कैशिंग का विषय पहले से कहीं अधिक प्रासंगिक होगा। दोनों डेटाबेस क्वेरी, अलग-अलग पेज ब्लॉक और सभी पेज कैश हैं।

खुद के लिए, मैंने डेटाबेस को केवल प्रश्नों के परिणामों को कैश करने का फैसला किया, क्योंकि, IMHO, विशाल (या ऐसा नहीं) के साथ कैश लोड करना html ब्लॉक किसी तरह से संसाधनों की बर्बादी है। (यह कथन सबसे अधिक सही है, यदि आप टेम्पलेट इंजन का उपयोग नहीं कर रहे हैं)। और हां, मैं कैशिंग सेवा के रूप में प्रसिद्ध ज्ञापन का उपयोग करता हूं।
अब देखते हैं कि ऐसी कैशिंग के साथ हमें किन समस्याओं का इंतजार है।
और समस्या सिर्फ एक है, लेकिन सबसे व्यक्तिगत एक नहीं है - कैश को बनाए रखना हमेशा अद्यतित होता है।

कटौती के तहत - समस्या का मेरा समाधान, कैश को हमेशा के लिए रहने की अनुमति देता है (जब तक कि यह प्रासंगिक नहीं है और आप रैम से बाहर नहीं निकले हैं)।


अधिक जानकारी


अब फैशनेबल एमवीसी मॉडल का पालन करते हुए, डेटाबेस के सभी प्रश्नों को मॉडल में किया जाएगा। साइट के प्रत्येक अनुभाग के लिए मेरी परियोजनाओं में मेरा अपना अलग मॉडल है, साथ ही एक सामान्य मॉडल भी है, जिसमें से डेटा प्रत्येक अनुभाग में आवश्यक है।

इस तरह से कैश प्रविष्टि कुंजी में अनुभाग का नाम, फ़ंक्शन का नाम और इस फ़ंक्शन को दिए गए पैरामीटर शामिल हैं। यह सब md5 में चारों ओर घूमता है ताकि कैश की कुंजी के हिस्से के रूप में बहुत लंबी धाराओं या मापदंडों के एक सरणी को पारित किया जा सके।

अब 90% मामलों में डेटाबेस में जानकारी अपडेट करते समय, हम निश्चित रूप से कैश को जानेंगे कि हमें किन कार्यों को रीसेट करना होगा। लेकिन हमेशा ऐसा नहीं होता है। उदाहरण के लिए, उपयोगकर्ता ने अपने व्यक्तिगत खाते से अंतिम 5 संदेशों को हटा दिया, लेकिन चूंकि सभी संदेश टूट गए हैं, 10 प्रति पृष्ठ कहते हैं, केवल अंतिम पृष्ठ के कैश को रीसेट करते हुए, अन्य सभी पृष्ठ पुराने राज्य में कैश रहेंगे, और यह अब अच्छा नहीं है। कार्य फ़ंक्शन कैश को रीसेट करना है, इसके पैरामीटर (उपयोगकर्ता आईडी) के केवल 1 को जानना, लेकिन दूसरे (पृष्ठ संख्या) को नहीं जानना।

तो मेरा फैसला


संक्षेप में - हर बार कैश में एक नई प्रविष्टि जोड़ी जाती है, कुंजी के घटकों को मोंगो में दर्ज किया जाता है, जिससे कैश का पूरी तरह से फिर से बनाने का अवसर मिलता है, केवल इसका हिस्सा जानता है। मैं विवरण में नहीं जाऊंगा, बस कोड पर जाऊंगा।
class Cache extends Memcached { private $registry; public function __construct() { parent::__construct(); $this->addServer('localhost', 11211); $m = new Mongo(); $this->registry = $m->local->cache_registry; // ,      } public function set($name, $content) { //    $this->registry->insert(array('id' => $name)); parent::set(md5(print_r($name, 1)), $content); } public function delete($name) { //    $this->registry->remove(array('id' => $name)); parent::delete(md5(print_r($name, 1))); } public function get($name) { return parent::get(md5(print_r($name, 1))); } public function smart_delete($params) { //    $criteria = array(); $size = sizeof($params); for ($i = 0; $i < 2; $i++) { //       $criteria['id.' . $i] = $params[$i]; } if ($size == 3) { //     for ($i = 0; $i < sizeof($params[2]); $i++) { $criteria['id.2.' . $i] = $params[2][$i]; } } elseif ($size > 3) throw new Exception('Size of input parameters is out of expected range'); $cursor = $this->registry->find($criteria); while ($cursor->hasNext()) { //          $data = $cursor->getNext(); $id = $data['_id']; parent::delete(md5(print_r($data['id'], 1))); $this->registry->remove(array('_id' => new MongoId($id))); } } } 


और एक कॉल का एक उदाहरण है, ताकि सब कुछ अंत में जगह में गिर गया:
 $cache = new Cache(); $cache->smart_delete('user', 'messages', array(1));/*    messages   user    = 1*/ 


जैसा कि आप देख सकते हैं, यह अशोभनीय सरल है और काफी लाभ है:
  1. एक विशिष्ट अनुभाग से सभी प्रविष्टियों को हटा दें
  2. केवल फ़ंक्शन नाम से सभी अनुभाग प्रविष्टियों को हटाना
  3. सभी फ़ंक्शन प्रविष्टियों को निकालना, केवल आवश्यक पैरामीटर जानना और अनावश्यक लोगों को त्यागना।


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

PS पिछली छुट्टियों के साथ!

Source: https://habr.com/ru/post/In111508/


All Articles