2010-08-01 15 views
8

हम एक डेटा संचालित ASP.NET वेबसाइट जो डेटा कैशिंग के लिए मानक पैटर्न (MSDN से यहाँ अनुकूलित) प्रयोग हो रहा है है:क्या कोई एएसपीनेट डेटा कैश कैश प्रविष्टियों की पृष्ठभूमि आबादी का समर्थन करता है?

public DataTable GetData() 
{ 
    string key = "DataTable"; 
    object item = Cache[key] as DataTable; 
    if((item == null) 
    { 
     item = GetDataFromSQL(); 
     Cache.Insert(key, item, null, DateTime.Now.AddSeconds(300), TimeSpan.Zero; 
    } 
    return (DataTable)item; 
} 

इस के साथ दिक्कत यह है कि GetDataFromSQL() करने के लिए कॉल महंगा है और साइट का उपयोग काफी अधिक है। तो हर पांच मिनट, जब कैश गिरता है, साइट बहुत चिपचिपा हो जाती है, जबकि नए अनुरोधों को पुनर्प्राप्त करने के लिए बहुत से अनुरोध प्रतीक्षा कर रहे हैं।

हम वास्तव में क्या करना चाहते हैं पुराने डेटा के लिए चालू रहना है जबकि पृष्ठभूमि में समय-समय पर डेटा को फिर से लोड किया जाता है। (तथ्य यह है कि कोई व्यक्ति छह मिनट का डेटा देख सकता है, यह एक बड़ा मुद्दा नहीं है - डेटा समय संवेदनशील नहीं है)। यह ऐसा कुछ है जिसे मैं स्वयं लिख सकता हूं, लेकिन यह जानना उपयोगी होगा कि क्या कोई वैकल्पिक कैशिंग इंजन (मुझे वेग, memcache जैसे नाम पता हैं) इस तरह के परिदृश्य का समर्थन करते हैं। या क्या मुझे मानक एएसपी.नेट डेटा कैश के साथ कुछ स्पष्ट चाल याद आ रही है?

+0

अपने GetDataFromSQL कॉल को प्रोफ़ाइल करना और यह पता लगाना उपयोगी हो सकता है कि इसमें से कौन सा भाग * धीमा है। यह अत्यधिक संभावना है कि यह पारिवारिक सिद्धांत का पालन करता है (यानी आपकी मंदी का 80% कोड के 20% के कारण होता है)। इसके बाद आप अपने प्रयासों को उस 10% या 20% कोड पर केंद्रित कर सकते हैं जो मंदी के बहुमत का कारण बन रहा है। –

+0

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

+0

इन विचारों के लिए धन्यवाद। हालांकि: ए) सभी प्रकार के पृष्ठभूमि कारण हैं जिसका मतलब है कि इस पल के लिए कॉल महंगे रहेंगे और बी) मुझे लगता है कि कॉलिंग की कीमत पर ध्यान दिए बिना पृष्ठभूमि-लोडिंग पैटर्न वास्तव में इन परिस्थितियों में सबसे अच्छा है। – Yellowfog

उत्तर

7

आपको CacheItemUpdateCallback प्रतिनिधि का उपयोग करने में सक्षम होना चाहिए जो 6 वां पैरामीटर है जो एएसपी का उपयोग करके Insert के लिए चौथा अधिभार है।नेट कैश:

Cache.Insert(key, value, dependancy, absoluteExpiration, 
    slidingExpiration, onUpdateCallback); 

निम्नलिखित काम करना चाहिए:

Cache.Insert(key, item, null, DateTime.Now.AddSeconds(300), 
    Cache.NoSlidingExpiration, itemUpdateCallback); 

private void itemUpdateCallback(string key, CacheItemUpdateReason reason, 
    out object value, out CacheDependency dependency, out DateTime expiriation, 
    out TimeSpan slidingExpiration) 
{ 
    // do your SQL call here and store it in 'value' 
    expiriation = DateTime.Now.AddSeconds(300); 
    value = FunctionToGetYourData(); 
} 

MSDN से:

एक वस्तु कैश में समाप्त हो रहा है, ASP.NET साथ CacheItemUpdateCallback प्रणाली को बुलाती है कैश आइटम की कुंजी और कारण आपको अपडेट करना चाहते हैंआइटम। इस विधि के शेष पैरामीटर पैरामीटर हैं। आप कैश किए गए आइटम को रीफ्रेश करते समय नई कैश किए गए आइटम और वैकल्पिक समाप्ति और निर्भरता मान पर उपयोग करते हैं।

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

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

कॉलबैक विधि एक अपवाद फेंकता है, तो ASP.NET अपवाद को दबा और कैश की गई मूल्य निकाल देता है।

मैंने इसका परीक्षण नहीं किया है, इसलिए आपको इसे थोड़ा सा टिंकर करना पड़ सकता है, लेकिन आपको यह पूरा करने का प्रयास करना चाहिए कि आप क्या करने की कोशिश कर रहे हैं।

+1

+1।निश्चित रूप से 'पुराने डेटा को चालू रखने के लिए ओपी की आवश्यकता को हल करता है जबकि पृष्ठभूमि में समय-समय पर नया डेटा पुनः लोड किया जाता है'। महान समाधान! –

+0

मैं हमेशा यह मानता हूं कि ऑब्जेक्ट की समयसीमा समाप्त होने के बाद यह कॉल किया गया था ... कौन कभी सोचा होगा कि दस्तावेज़ीकरण पढ़ना आसान होगा? अच्छा काम। – Yellowfog

+0

एक चेतावनी। यदि आपका FunctionToGetYourData() लंबे समय से चल रहा है, तो आप रीफिल की अवधि के लिए कैश को रोक देंगे। इसका अर्थ यह है कि कोड गैर-समाप्त होने वाली प्रविष्टियों को प्राप्त कर सकता है, लेकिन कॉलबैक रिटर्न तक कोई नई प्रविष्टियां कैश नहीं की जा सकती हैं (शायद अन्य पृष्ठ अनुरोधों के जवाब में)। यह वास्तव में बुरा लग सकता है। – IDisposable

0

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

ऐसा करने से आपको अपनी GetDataFromSQL विधि को एक अलग प्रक्रिया में अलग करने की अनुमति मिल जाएगी, एक विंडोज सेवा कहें, जो हर पांच मिनट में चलती है, जो आपकी 'चिपचिपा' साइट को कम कर देगी।


या ...

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

(btw, आपका इरादा साफ है जब आप कैश में वस्तुओं डाल रहे हैं बनाने के लिए शीर्ष टिप - कैश एक NoSlidingExpiration (और एक NoAbsoluteExpiration) निरंतर उपलब्ध है कि आपके Timespan.Zero की तुलना में अधिक पठनीय है है)

+0

इसके लिए धन्यवाद, लेकिन मुझे नहीं लगता कि इससे मदद मिलती है। थ्रेड-सुरक्षित अपडेट के लिए किसी ऑब्जेक्ट को लॉक करना एक चुनौती नहीं है। और मैं SqlCacheDependency का उपयोग नहीं करना चाहता क्योंकि मैं सेवा ब्रोकर चालू नहीं करना चाहता (इसके अलावा इसका उपयोग विशेष एप्लिकेशन के लिए उपयुक्त नहीं है)। – Yellowfog

0

पहले , उस डेटाटेबल होग की बजाय आपको वास्तव में एक दुबला वर्ग (जिसे पीओसीओ भी कहा जाता है) में जिस तारीख की आवश्यकता है उसे रखें।

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

जिस प्रकार का डेटा और समय/बजट एसक्यूएल ओर पुनर्गठन करने से आप संभवत: केवल बातें है कि LastWrite युवा अपने अद्यतन विंडो लाने सकता है पर निर्भर करता है। आपको 2-चरणीय अपडेट की आवश्यकता होगी (हैश-रखे गए ऑब्जेक्ट से नई ऑब्जेक्ट में डालने की ज़रूरत है - हैश में सामान सख्ती से केवल किसी भी उपयोग के लिए पढ़ा जाता है या नरक टूट जाएगा)।

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

+0

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

संबंधित मुद्दे