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

रेल संग्रह कैशिंग

हमने पहले AppSignal Academy पर रेल में फ्रैगमेंट कैशिंग को देखा है। यह दृश्यों के छोटे टुकड़ों को कैश करके उनके प्रदर्शन में बहुत सुधार करता है। आंशिक को कैशिंग करते समय, हमें कम लागत पर अपने विचारों में उन्हें कहीं और पुन:उपयोग करने में सक्षम होने का अतिरिक्त लाभ होता है।

यह छोटे संग्रहों के लिए अच्छा काम करता है, लेकिन बड़े संग्रहों पर समस्याएँ शीघ्र ही उत्पन्न हो जाती हैं। इस लेख में, हम देखेंगे कि रेल संग्रह कैशिंग कैसे काम करता है और बड़े संग्रह के प्रतिपादन को गति देने के लिए हम इसका उपयोग कैसे कर सकते हैं।

<ब्लॉकक्वॉट>

👋 और यदि आप इस लेख को पसंद करते हैं, तो हमने रूबी (ऑन रेल्स) के प्रदर्शन के बारे में और भी बहुत कुछ लिखा है, हमारी रूबी प्रदर्शन निगरानी चेकलिस्ट देखें।

संग्रह प्रस्तुत करना

आइए एक छोटे नियंत्रक से शुरू करें जो हमारे ब्लॉग के अनुक्रमणिका पृष्ठ के लिए पिछले 100 पोस्ट लोड करता है।

class PostsController < ApplicationController
  def index
    @posts = Post.all.order(:created_at => :desc).limit(100)
  end
end

इन पोस्ट को दृश्य में प्रस्तुत करने के लिए, हम @posts . पर लूप करते हैं आवृत्ति चर।

<!-- app/views/posts/index.html.erb -->
<h1>Posts</h1>
 
<div class="posts">
  <% @posts.each do |post| %>
    <div class="post">
      <h2><%= post.title %></h2>
      <small><%= post.author %></small>
 
      <div class="body">
        <%= post.body %>
      </div>
    </div>
  <% end %>
</div>

इस पृष्ठ का अनुरोध करने पर, हम देखते हैं कि पोस्ट डेटाबेस से प्राप्त की जा रही हैं और दृश्य प्रस्तुत किया जा रहा है। दृश्य परत में केवल 32 मिलीसेकंड खर्च करने के साथ, यह पृष्ठ बहुत तेज़ है।

Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index.html.erb within layouts/application
  Post Load (1.5ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
  Rendered posts/index.html.erb within layouts/application (19.4ms)
Completed 200 OK in 37ms (Views: 32.4ms | ActiveRecord: 2.7ms)

एक संग्रह को आंशिक रूप से प्रस्तुत करना

इसके बाद, हम post . का उपयोग करना चाहते हैं किसी अन्य दृश्य में तत्व, इसलिए हम पोस्ट HTML को आंशिक में ले जाते हैं।

<!-- app/views/posts/index.html.erb -->
<h1>Posts</h1>
 
<div class="posts">
  <% @posts.each do |post| %>
    <%= render post %>
  <% end %>
</div>
 
<!-- app/views/posts/_post.html.erb -->
<div class="post">
  <h2><%= post.title %></h2>
  <small><%= post.author %></small>
 
  <div class="body">
    <%= post.body %>
  </div>
</div>
Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index.html.erb within layouts/application
  Post Load (1.2ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
...
  Rendered posts/_post.html.erb (0.1ms)
  Rendered posts/_post.html.erb (0.1ms)
  Rendered posts/index.html.erb within layouts/application (205.4ms)
Completed 200 OK in 217ms (Views: 213.8ms | ActiveRecord: 1.7ms)

दृश्य परत पर खर्च किए गए 213 मिलीसेकंड के साथ, आप देख सकते हैं कि रेंडर करने का समय काफी बढ़ गया है। ऐसा इसलिए है क्योंकि प्रत्येक पोस्ट के लिए एक नई फ़ाइल (आंशिक) को लोड, संकलित और प्रस्तुत करने की आवश्यकता होती है। आइए संक्षेप में देखें कि हम फ़्रैगमेंट कैशिंग के साथ रेंडर समय को कैसे बेहतर बना सकते हैं।

फ्रैगमेंट कैशिंग

जैसा कि फ्रैगमेंट कैशिंग लेख में वर्णित है, हम cache . का उपयोग करेंगे render . के आसपास के दृश्य में सहायक बुलाना। इस तरह, हम प्रत्येक पोस्ट के लिए आंशिक के रेंडरिंग को कैश करेंगे।

<!-- app/views/posts/index.html.erb -->
<h1>Posts</h1>
 
<div class="posts">
  <% @posts.each do |post| %>
    <%= cache post do %>
      <%= render post %>
    <% end %>
  <% end %>
</div>
Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index_with_partial_caching.html.erb within layouts/application
  Post Load (1.4ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
...
Read fragment views/posts/index.1ms)
  Rendered posts/_post.html.erb (0.1ms)
Write fragment views/posts/index.1ms)
Read fragment views/posts/index.5ms)
  Rendered posts/_post.html.erb (0.1ms)
Write fragment views/posts/index.1ms)
  Rendered posts/index.html.erb within layouts/application (274.5ms)
Completed 200 OK in 286ms (Views: 281.4ms | ActiveRecord: 2.4ms)

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

Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index.html.erb within layouts/application
  Post Load (2.2ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
...
Read fragment views/posts/index.1ms)
Read fragment views/posts/index.1ms)
  Rendered posts/index.html.erb within layouts/application (63.8ms)
Completed 200 OK in 78ms (Views: 75.5ms | ActiveRecord: 2.2ms)

बाद के अनुरोधों में, हम देखते हैं कि दृश्य में बिताया गया समय काफी कम है - 286 मिलीसेकंड से 78 मिलीसेकंड तक। फिर भी, यह अभी भी हमारे मूल कोड की तुलना में बहुत धीमा है - यह लगभग दोगुना धीमा है।

नोट:यदि आप अपने लॉग्स में "रीड/राइट फ्रैगमेंट" लाइन नहीं देख रहे हैं, तो अपने डेवलपमेंट एनवायरनमेंट में फ्रैगमेंट कैश लॉगिंग को सक्षम करना सुनिश्चित करें, जो कि false पर सेट है। रेल 5.1 और इसके बाद के संस्करण पर डिफ़ॉल्ट रूप से:

# config/environments/development.rb
config.action_controller.enable_fragment_cache_logging = true

संग्रह कैशिंग

रेल 5 में, संग्रह कैशिंग को तेज करने के लिए बहुत काम किया गया था। इन सुधारों का लाभ उठाने के लिए, हमें अपना व्यू कोड बदलना होगा। cache को कॉल करने के बजाय अपने आप को सहायक, हम रेल को एक ही समय में एक संपूर्ण संग्रह प्रस्तुत करने और उसे कैश करने के लिए कह सकते हैं।

<!-- app/views/posts/index.html.erb -->
<h1>Posts</h1>
 
<div class="posts">
  <%= render partial: :post, collection: @posts, cached: true %>
</div>

नोट करें render @collection, cached: true इस कैशिंग गति सुधार के लिए शॉर्टहैंड काम नहीं करेगा।

Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index.html.erb within layouts/application
  Post Load (1.4ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
  Rendered collection of posts/_post.html.erb [0 / 100 cache hits] (28.2ms)
  Rendered posts/index.html.erb within layouts/application (46.6ms)
Completed 200 OK in 64ms (Views: 59.9ms | ActiveRecord: 2.0ms)

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

Started GET "/posts"
Processing by PostsController#index as HTML
  Rendering posts/index.html.erb within layouts/application
  Post Load (1.3ms)  SELECT  "posts".* FROM "posts" ORDER BY "posts"."created_at" DESC LIMIT ?  [["LIMIT", 100]]
  ↳ app/views/posts/index.html.erb:4
  Rendered collection of posts/_post.html.erb [100 / 100 cache hits] (19.2ms)
  Rendered posts/index.html.erb within layouts/application (26.5ms)
Completed 200 OK in 37ms (Views: 35.7ms | ActiveRecord: 1.3ms)

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

इस कैशिंग सहायक का एक अतिरिक्त लाभ संग्रह का सारांशित लॉगिंग है। पहले अनुरोध में, कोई भी कैश कुंजी नहीं मिली [0 / 100 cache hits] , लेकिन दूसरे अनुरोध में, वे सभी पाए गए [100 / 100 cache hits]

डेटाबेस में कुछ ऑब्जेक्ट्स को अपडेट करने के बाद, हम यह भी देख सकते हैं कि कितनी कुंजियाँ पुरानी थीं।

Rendered collection of posts/_post.html.erb [88 / 100 cache hits] (13.4ms)

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

रेल में संग्रह कैशिंग के बारे में कोई प्रश्न हैं? कृपया हमें @AppSignal पर बताने में संकोच न करें! यदि आपके पास लेख के संबंध में कोई टिप्पणी है या यदि आपके पास कोई विषय है जिसे आप हमें कवर करना चाहते हैं, तो कृपया हमसे संपर्क करें।


  1. रेल के साथ हॉटवायर का उपयोग करना

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

  1. एडब्ल्यूएस लैम्ब्डा के लिए रेल की तैनाती

    सर्वर रहित कंप्यूटिंग एक क्लाउड प्रदाता को सर्वर के प्रबंधन और प्रावधान के काम को उतारने में मदद करती है और तेजी से अधिकांश प्रौद्योगिकी टीमों के लिए एक चीज बन रही है। AWS लैम्ब्डा एक प्रकार की सर्वर रहित तकनीक है जिसका उपयोग कई तकनीकी टीमों द्वारा किया जाता है। AWS लैम्ब्डा NodeJS, Java, Python और

  1. रेल के साथ कोणीय का उपयोग करना 5

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