Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

जटिल डेटा मॉडल का अनुकूलन: एक त्वरित कैशिंग रणनीति

जब आपका डेटा मॉडल जटिल हो जाता है, और आपके APIs उस दुखद 1 सेकंड प्रतिक्रिया समय को हिट करते हैं, तो आमतौर पर एक आसान फिक्स होता है: :includes। जब आप अपने मॉडल के एसोसिएशन को प्रीलोड करते हैं, तो आप उतने SQL कॉल नहीं करेंगे। और यह आपको बहुत समय बचा सकता है।

लेकिन फिर आपकी साइट फिर से धीमी हो जाती है, और आप प्रतिक्रियाओं को कैश करने के बारे में सोचते हैं। और अब आपके पास एक समस्या है। क्योंकि यदि आप कैश से प्रतिक्रियाएं प्राप्त करना चाहते हैं:

results = {lawyer_1: 1, lawyer_2: 2, lawyer_3: 3} cached_objects = Rails.cache.fetch_multi(results.keys) do |key| Lawyer.find(results[key]).as_json end 

आपने अब अपने सभी :includes खो दिए हैं। क्या आपके पास दोनों हो सकते हैं? आप अपने कैश्ड ऑब्जेक्ट्स के लिए तेज़ प्रतिक्रिया कैसे प्राप्त करते हैं, और फिर भी उन ऑब्जेक्ट्स को जल्दी से लोड करते हैं जो कैश में नहीं हैं?

बहुत कुछ करना है, इसलिए इसके बारे में सोचना कठिन है। यह आसान होता है जब आप समस्या को छोटे टुकड़ों में तोड़ते हैं, और एक सरल अगला कदम लेकर आते हैं।

तो पहली चीज़ जो आप कर सकते हैं वह क्या है? कुछ भी करने के लिए, आपको यह जानना होगा कि कौन से ऑब्जेक्ट्स आपके कैश में हैं, और कौन से आपको अभी भी ढूंढने की आवश्यकता है।

कैश्ड को अनकैश्ड से अलग करें

तो, मान लें कि आपके पास कैश कुंजियों का एक गुच्छा है:

cache_keys = [:key_1, :key_2, :key_3] 

आप कैसे बता सकते हैं कि इनमें से कौन सी कैश में हैं?

ActiveSupport::Cache में एक आसान मेथड है जिसे read_multi कहा जाता है:

# जब केवल lawyer_1 कैश्ड है cache_keys = [:lawyer_1, :lawyer_2, :lawyer_3] Rails.cache.read_multi(cache_keys) # => {:lawyer_1 => {"id": 1, "name": "Bob the Lawyer"} } 

read_multi कैश में पाए गए प्रत्येक कुंजी के लिए {key: value} का एक हैश लौटाता है। लेकिन आप उन सभी कुंजियों को कैसे ढूंढते हैं जो कैश में नहीं हैं? आप इसे सीधे तरीके से कर सकते हैं: सभी कैश कुंजियों के माध्यम से लूप करें और पता करें कि कौन सी read_multi द्वारा लौटाए गए हैश में नहीं हैं:

cache_keys = [:lawyer_1, :lawyer_2, :lawyer_3] uncached_keys = [] cached_keys_with_values = Rails.cache.read_multi(cache_keys) cache_keys.each do |key| uncached_keys << key unless cached_keys_with_values.has_key?(key) end 

तो, अब आपके पास क्या है?

  • उन सभी कैश कुंजियों की एक सरणी जिनके लिए आप ऑब्जेक्ट्स चाहते थे।
  • कैश में मिले प्रत्येक ऑब्जेक्ट के लिए {key: value} जोड़े का एक हैश।
  • उन कुंजियों की एक सूची जो कैश में नहीं थीं।

और आपको आगे क्या चाहिए?

  • कैश में नहीं मिली कुंजियों के लिए मान। अधिमानतः एक साथ सभी प्राप्त किए गए।

वह आपका अगला कदम है।

अनकैश्ड मानों को प्रीलोड करें

जल्द ही, आपको एक कैश कुंजी का उपयोग करके एक ऑब्जेक्ट ढूंढना होगा। चीजों को आसान बनाने के लिए, आप कोड को इस तरह बदल सकते हैं:

cache_identifiers = {lawyer_1: 1, lawyer_2: 2, lawyer_3: 3} cache_keys = cache_identifiers.keys uncached_keys = [] cached_keys_with_values = Rails.cache.read_multi(cache_keys) cache_keys.each do |key| uncached_keys << key unless cached_keys_with_values.has_key?(key) end 

तो cache_identifiers अब कैश कुंजी और लाने के लिए ऑब्जेक्ट आईडी दोनों को ट्रैक करता है।

अब, अपनी अनकैश्ड कुंजियों के साथ:

uncached_keys # => [:lawyer_2, :lawyer_3] 

और आपके cache_identifiers हैश के साथ:

cache_identifiers # => {lawyer_1: 1, lawyer_2: 2, lawyer_3: 3} 

आप उन सभी ऑब्जेक्ट्स को एक साथ ला सकते हैं, प्रीलोड कर सकते हैं, और सीरियलाइज़ कर सकते हैं:

uncached_ids = uncached_keys.map { |key| cache_identifiers[key] } uncached_lawyers = Lawyer.where(id: uncached_ids) .includes([:address, :practice_areas, :awards, ...]) .map(&:as_json)) 

तो अब आपके पास क्या है?

  • उन सभी कैश कुंजियों की एक सरणी जिनके लिए आप ऑब्जेक्ट्स चाहते थे शुरू में।
  • कैश में मिले प्रत्येक ऑब्जेक्ट के लिए {key: value} जोड़े का एक हैश।
  • कैश में नहीं मिली कुंजियों की एक सूची।
  • कैश में नहीं मिले सभी मान।

और आपको आगे क्या चाहिए?

  • आपके द्वारा अभी प्राप्त किए गए सभी मानों को कैश करें, ताकि आपको अगली बार इस पूरी प्रक्रिया से न गुजरना पड़े।
  • आपके सभी ऑब्जेक्ट्स की अंतिम सूची, चाहे वे कैश से आए हों या नहीं।

अनकैश्ड मानों को कैश करें

आपके पास दो सूचियां हैं: अनकैश्ड कुंजियों में से एक और अनकैश्ड मानों में से एक। लेकिन उन्हें कैश करने के लिए, यह आसान होगा यदि आपके पास एक सूची [key, value] जोड़े की हो, ताकि आपका value अपने key के बगल में हो। यह मेरे पसंदीदा मेथड्स में से एक, zip का उपयोग करने का एक बहाना है:

[1, 2, 3].zip(["a", "b", "c"]) # => [[1, "a"], [2, "b"], [3, "c"]] 

zip के साथ, आप अपने प्राप्त मानों को आसानी से कैश कर सकते हैं:

uncached_keys.zip(uncached_lawyers).each do |key, value| Rails.cache.write(key, value) end 

अब आपके पास क्या है?

  • उन सभी कैश कुंजियों की एक सरणी जिनके लिए आप ऑब्जेक्ट्स चाहते थे शुरू में।
  • कैश में मिले प्रत्येक ऑब्जेक्ट के लिए {key: value} जोड़े का एक हैश।
  • आपके द्वारा अभी कैश किए गए पूर्व-अनकैश्ड मानों की एक सूची।

और आपको अभी भी क्या चाहिए?

  • आपके सभी ऑब्जेक्ट्स की एक बड़ी सूची, चाहे वे कैश से आए हों या नहीं।

इसे सब एक साथ लाएं

अब, आपके पास कैश कुंजियों की एक क्रमबद्ध सूची है:

cache_keys = cache_identifiers.keys 

कैश से आपके द्वारा प्राप्त ऑब्जेक्ट्स की आपकी सूची:

cached_keys_with_values = Rails.cache.read_multi(cache_keys) 

और आपके द्वारा अभी डेटाबेस से लिए गए ऑब्जेक्ट्स की आपकी सूची:

uncached_ids = uncached_keys.map { |key| cache_identifiers[key] } uncached_lawyers = Lawyer.where(id: uncached_ids) .includes([:address, :practice_areas, :awards, ...]) .map(&:as_json)) 

अब आपको बस सब कुछ एक साथ रखने के लिए एक अंतिम लूप की आवश्यकता है:

results = [] cache_keys.each do |key| results << cache_keys_with_values[key] || uncached_lawyers.shift end 

यानी, प्रत्येक कैश कुंजी के लिए, आप उस कुंजी के लिए कैश में मिले ऑब्जेक्ट को पकड़ते हैं। यदि वह कुंजी मूल रूप से कैश में नहीं थी, तो आप डेटाबेस से निकाले गए अगले ऑब्जेक्ट को पकड़ते हैं।

उसके बाद, आप काम पूरा कर चुके हैं!

यहां पूरी चीज़ कैसी दिखती है:

cache_identifiers = {lawyer_1: 1, lawyer_2: 2, lawyer_3: 3} cache_keys = cache_identifiers.keys uncached_keys = [] # कैश से कैश्ड मान प्राप्त करें cached_keys_with_values = Rails.cache.read_multi(cache_keys) # उन कुंजियों की सूची बनाएं जो कैश में नहीं थीं cache_keys.each do |key| uncached_keys << key unless cached_keys_with_values.has_key?(key) end # सभी अनकैश्ड मानों को बल्क में लाएं uncached_ids = uncached_keys.map { |key| cache_identifiers[key] } uncached_lawyers = Lawyer.where(id: uncached_ids) .includes([:address, :practice_areas, :awards, ...]) .map(&:as_json)) # अनकैश्ड मानों को वापस कैश में लिखें uncached_keys.zip(uncached_lawyers).each do |key, value| Rails.cache.write(key, value) end # कैश्ड और अनकैश्ड मानों से अपना अंतिम परिणाम सेट बनाएं results = [] cache_keys.each do |key| results << cache_keys_with_values[key] || uncached_lawyers.shift end results 

क्या यह इसके लायक था? शायद। यह बहुत सारा कोड है। लेकिन अगर आप बहुत सारे एसोसिएशन वाले ऑब्जेक्ट्स को कैश कर रहे हैं, तो यह आपको दर्जनों या सैकड़ों SQL कॉल बचा सकता है। और यह आपके API प्रतिक्रियाओं से बहुत समय कम कर सकता है।

Avvo में, यह पैटर्न अविश्वसनीय रूप से उपयोगी रहा है: हमारे बहुत सारे JSON APIs इसका उपयोग अविश्वसनीय रूप से तेजी से कैश्ड प्रतिक्रियाएं वापस करने के लिए करते हैं।

यह पैटर्न इतना उपयोगी रहा है कि मैंने इसे bulk_cache_fetcher नामक एक जेम में समाहित किया। तो अगर आप कभी खुद को बड़े, जटिल डेटा मॉडल को कैश करने की कोशिश करते हुए पाते हैं, तो इसे आज़माएं!

  1. एंटरप्राइज सिस्टम में कैश स्थिरता सुनिश्चित करने की 3 सिद्ध रणनीतियां एंटरप्राइज सिस्टम में कैश स्थिरता सुनिश्चित करने की 3 सिद्ध रणनीतियां

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

  1. विंडोज 10 पर क्रोम कुकीज़ और कैश को तेज़ी से कैसे साफ़ करें – तेज़, सुरक्षित और आसान विंडोज 10 पर क्रोम कुकीज़ और कैश को तेज़ी से कैसे साफ़ करें – तेज़, सुरक्षित और आसान

    जब आप वेबसाइट पर जाते हैं, तो यह ब्राउज़िंग जानकारी संग्रहीत करने के लिए कुकीज़ बनाता है, जैसे आपकी साइट प्राथमिकताएं या प्रोफाइल जानकारी, और आपके ब्राउज़र का कैश, जो वेब पेज, इमेज, CSS, ऑडियो, वीडियो और अन्य डाउनलोड की गई सामग्री को संग्रहीत करता है, पेजों को तेजी से लोड करने में मदद कर सकता है, आप

  1. स्टेग्नोग्राफी: छिपे हुए मैलवेयर ट्रांसमिशन का उभरता खतरा स्टेग्नोग्राफी: छिपे हुए मैलवेयर ट्रांसमिशन का उभरता खतरा

    जब हम जीरो-डे खतरों, लोकप्रिय कारनामों, घातक COVID-19 वायरस से लड़ने के लिए तैयार हो रहे हैं। हैकर्स आपकी मशीनों पर मैलवेयर पहुंचाने के लिए नई तकनीकें विकसित कर रहे हैं। 1499 में पेश की गई एक अवधारणा लेकिन प्राचीन काल से अस्तित्व में है नया हथियार। इसे स्टेग्नोग्राफी कहा जाता है यह नई तकनीक डेटा को