2012-12-24 50 views
19

मैं अपने रीस्टफुल एपीआई (रूबी में लिखे गए) में जीईटी अनुरोधों के लिए सामने या पहली परत बनाने के लिए सबसे अच्छा तरीका सोच रहा हूं।जीईटी कॉल के रीस्टफुल एपीआई परिणामों को कैश करने का सबसे अच्छा तरीका

प्रत्येक अनुरोध को कैश नहीं किया जा सकता है, क्योंकि कुछ जीईटी अनुरोधों के लिए एपीआई को अनुरोध करने वाले उपयोगकर्ता/आवेदन को सत्यापित करना होगा। इसका मतलब है कि मुझे कॉन्फ़िगर करने की आवश्यकता है कि कौन सा अनुरोध कैश करने योग्य है और प्रत्येक कैश्ड उत्तर कितना समय मान्य है। कुछ मामलों के लिए मुझे बहुत कम समय समाप्ति समय की आवश्यकता है 15 और नीचे। और मुझे एपीआई एप्लिकेशन द्वारा कैश प्रविष्टियों की अवधि समाप्त होने में सक्षम होना चाहिए, भले ही समाप्ति तिथि अभी तक न पहुंच जाए।

मैं पहले से ही कई संभव समाधान, मेरे दो सबसे अच्छे विचार के बारे में सोचा:

  • अपने आप से एपीआई (यहां तक ​​कि इससे पहले कि मार्ग), कैश तर्क के

    पहली परत (मेरे हाथ में सभी विन्यास विकल्प हैं करने के लिए) , जवाब और समाप्ति तिथि

  • एक वेबसर्वर प्रॉक्सी (उच्च विन्यास), शायद विद्रूप की तरह कुछ memcached करने के लिए जमा हो जाती है, लेकिन मैं इस से पहले तरह के मामले के लिए एक प्रॉक्सी इस्तेमाल कभी नहीं किया है और मैं पूरी तरह से यह

के बारे में यकीन नहीं है

मैंने वार्निश जैसे कैश समाधान के बारे में भी सोचा, मैंने "सामान्य" वेब अनुप्रयोगों के लिए वार्निश का उपयोग किया और यह प्रभावशाली है लेकिन कॉन्फ़िगरेशन एक तरह का विशेष है। लेकिन अगर यह सबसे तेज़ समाधान है तो मैं इसका इस्तेमाल करूंगा।

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

अगर किसी के पास इस विषय के बारे में पढ़ने के लिए कोई संकेत या अच्छा स्रोत है, तो मुझे बताएं।

उत्तर

3

memcached एक अच्छा विकल्प है, और मैंने देखा है कि आपने इसे पहले से ही एक संभावित विकल्प के रूप में वर्णित किया है। इसके अलावा रेडिस को इस स्तर पर एक और विकल्प के रूप में बहुत प्रशंसा की जा रही है।

फ़ाइल स्तर और/या मॉड्यूल आधार द्वारा फ़ाइल पर कैश करने के लिए अधिक बारीक दृष्टिकोण के संदर्भ में, एप्लिकेशन संग्रहण पर, स्थानीय संग्रहण हमेशा सामान्य वस्तुओं के लिए एक विकल्प होता है जो उपयोगकर्ता बार-बार अनुरोध कर सकता है, यहां तक ​​कि सरल सत्र में प्रतिक्रिया ऑब्जेक्ट्स को छोड़कर, ताकि पुन: उपयोग किया जा सके बनाम बनाम एक और http आराम कॉल और कोडिंग उचित रूप से किया जा सके।

अब लोग वार्निश बनाम स्क्विड के बारे में बहस करते हैं और दोनों अपने पेशेवरों और विपक्ष के बारे में बहस करते हैं, इसलिए मैं इस बात पर टिप्पणी नहीं कर सकता कि कौन सा बेहतर है लेकिन कई लोग कहते हैं कि एक ट्यूनेड अपाचे सर्वर के साथ वार्निश बहुत अच्छा है गतिशील वेबसाइटें।

3

चूंकि आरईएसटी एक HTTP चीज है, तो यह हो सकता है कि कैशिंग अनुरोधों का सबसे अच्छा तरीका HTTP कैशिंग का उपयोग करना है।

अपने प्रतिक्रियाओं पर ईटैग का उपयोग करने के लिए, '304 संशोधित' के साथ जवाब देने के अनुरोध में ईटीएजी की जांच करना और रैट :: कैश को कैश डेटा की सेवा करने के लिए देखें यदि ईटैग समान हैं। यह कैश-नियंत्रण 'सार्वजनिक' सामग्री के लिए बहुत अच्छा काम करता है।

रैक :: कैश को इसकी स्टोरेज आवश्यकताओं के लिए मेमकैच का उपयोग करने के लिए सबसे अच्छा कॉन्फ़िगर किया गया है।

मैं दिलचस्प तरीका है कि रैक के बारे में एक ब्लॉग पोस्ट पिछले हफ्ते लिखा :: कैश ETags का उपयोग करता है का पता लगाने और नए ग्राहकों को कैश की गई सामग्री वापस करने के लिए: http://blog.craz8.com/articles/2012/12/19/rack-cache-and-etags-for-even-faster-rails

यहां तक ​​कि अगर आप रेल उपयोग नहीं कर रहे, रैक मिडलवेयर उपकरण इस सामान के लिए काफी अच्छे हैं।

+0

और थोड़ा रैक के बारे में धन्यवाद, मैं तुम्हें पोस्ट पढ़ :: कैश। यह दिलचस्प है और मैं एक नजदीक देखो होगा। – maddin2code

+0

आपके ब्लॉक पर मैंने देखा कि आप वार्निश का भी उपयोग कर रहे हैं, मुझे लगता है कि यूआरआई और "ईटाग" संग्रहीत परिणाम से मेल खाते हुए वार्निश कैश किए गए परिणाम को वापस कर देगा, है ना? – maddin2code

+0

मैंने कभी भी वार्निश का स्पष्ट रूप से उपयोग नहीं किया है, लेकिन ऐसा लगता है कि हेरोकू अब कैशिंग सामग्री के लिए अपने सीडर स्टैक में वार्निश का उपयोग कर रहा है। सभी ETag सामानों को अभी भी –

5

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

उपयोगकर्ताओं में लॉग इन किए गए अच्छे सौदे के साथ यह एक पूर्ण पृष्ठ कैश के पीछे कुछ प्रकार के मॉडल कैश होने के लिए बहुत फायदेमंद होगा क्योंकि कई मॉडल अभी भी साझा किए गए हैं, भले ही कुछ नहीं हैं (एक अच्छी ओओपी संरचना में)।

फिर एक पूर्ण पृष्ठ कैश के लिए आप वेब सर्वर से सभी अनुरोधों को और विशेष रूप से अगले चरण (आपके मामले में रूबी) में गतिशील प्रसंस्करण से दूर रखने के लिए सबसे अच्छे हैं। एक सामान्य वेब सर्वर से पूर्ण पृष्ठों को कैश करने का सबसे तेज़ तरीका हमेशा वेब सर्वर के सामने एक कैशिंग प्रॉक्सी होता है।

वार्निश मेरी राय में अच्छा और आसान है, लेकिन कुछ वास्तव में स्क्विड पसंद करते हैं।

+0

सत्र की जानकारी कुकी में संग्रहीत की जाती है, अगर कॉल किए गए विधि को इसकी आवश्यकता होती है तो मैं उन्हें सर्वर की तरफ देखता हूं। यदि यह अभी भी एक शानदार तरीका नहीं है, तो मुझे आश्चर्य होगा, लेकिन मुझे बताओ। – maddin2code

+0

ठीक है, मुझे इस विषय के बारे में अच्छी चर्चा मिली [लिंक] (http://stackoverflow.com/questions/319530/restful- प्रमाणीकरण) – maddin2code

2

रेडिस कैश सबसे अच्छा विकल्प है।

यह खुला स्रोत है। उन्नत कुंजी-मूल्य कैश और स्टोर।

0

मैं redis सफलतापूर्वक मेरी बाकी ध्यान में रखते हुए इस तरह से उपयोग किया है:

from django.conf import settings 
import hashlib 
import json 
from redis import StrictRedis 
from django.utils.encoding import force_bytes 

def get_redis(): 
    #get redis connection from RQ config in settings 
    rc = settings.RQ_QUEUES['default'] 
    cache = StrictRedis(host=rc['HOST'], port=rc['PORT'], db=rc['DB']) 
    return cache 



class EventList(ListAPIView): 
    queryset = Event.objects.all() 
    serializer_class = EventSerializer 
    renderer_classes = (JSONRenderer,) 


    def get(self, request, format=None): 
     if IsAdminUser not in self.permission_classes: # dont cache requests from admins 


      # make a key that represents the request results you want to cache 
      # your requirements may vary 
      key = get_key_from_request() 

      # I find it useful to hash the key, when query parms are added 
      # I also preface event cache key with a string, so I can clear the cache 
      # when events are changed 
      key = "todaysevents" + hashlib.md5(force_bytes(key)).hexdigest()   

      # I dont want any cache issues (such as not being able to connect to redis) 
      # to affect my end users, so I protect this section 
      try: 
       cache = get_redis() 
       data = cache.get(key) 
       if not data: 
        # not cached, so perform standard REST functions for this view 
        queryset = self.filter_queryset(self.get_queryset()) 
        serializer = self.get_serializer(queryset, many=True) 
        data = serializer.data 

        # cache the data as a string 
        cache.set(key, json.dumps(data)) 

        # manage the expiration of the cache 
        expire = 60 * 60 * 2 
        cache.expire(key, expire) 
       else: 
        # this is the place where you save all the time 
        # just return the cached data 
        data = json.loads(data) 

       return Response(data) 
      except Exception as e: 
       logger.exception("Error accessing event cache\n %s" % (e)) 

     # for Admins or exceptions, BAU 
     return super(EventList, self).get(request, format) 

मेरी इवेंट मॉडल अद्यतन में, मैं किसी भी घटना कैश साफ़ करें। यह शायद ही कभी किया जाता है (केवल व्यवस्थापक ईवेंट बनाने, और नहीं है कि अक्सर), तो मैं हमेशा स्पष्ट सभी घटना कैश

class Event(models.Model): 

... 

    def clear_cache(self): 
     try: 
      cache = get_redis() 
      eventkey = "todaysevents" 
      for key in cache.scan_iter("%s*" % eventkey): 
       cache.delete(key) 
     except Exception as e: 
      pass 


    def save(self, *args, **kwargs): 
     self.clear_cache() 
     return super(Event, self).save(*args, **kwargs)