2011-10-27 13 views
17

के लिए प्री लोड लोड मान मुझे एक आवश्यकता है जहां हम जावा एप्लिकेशन में उपयोग के लिए डेटाबेस से स्थिर डेटा लोड कर रहे हैं। प्रारंभ मेंएक गुवा कैश

  • लोड डेटाबेस से सभी स्थैतिक डेटा (एक बार लोड, इस डेटा नहीं बदलेगा)
  • लोड नए डेटा डेटाबेस (डेटाबेस में मौजूद डेटा से: किसी भी कैशिंग तंत्र निम्नलिखित कार्यक्षमता होना चाहिए अप नहीं बदलेगा लेकिन नया डेटा जोड़ना संभव है)

सभी डेटा की आलसी लोडिंग एक विकल्प नहीं है क्योंकि एप्लिकेशन को कई भौगोलिक स्थानों पर तैनात किया जाएगा और एक डेटाबेस के साथ संवाद करना होगा। डेटा को आलसी लोड करने से एक विशिष्ट तत्व के लिए पहला अनुरोध बहुत धीमा हो जाएगा जहां एप्लिकेशन डेटाबेस के लिए एक अलग क्षेत्र में है।

मैं सफलता के साथ गुवा में मैपमेकर एपीआई का उपयोग कर रहा हूं लेकिन अब हम नवीनतम रिलीज में अपग्रेड कर रहे हैं और मुझे कैशबिल्डर एपीआई में एक ही कार्यक्षमता नहीं मिल रही है; मुझे स्टार्ट-अप पर सभी डेटा लोड करने का एक साफ तरीका नहीं दिख रहा है।

एक तरीका डेटाबेस से सभी चाबियाँ लोड करना होगा और अलग-अलग कैश के माध्यम से लोड करना होगा। यह काम करेगा लेकिन परिणामस्वरूप डेटाबेस में एन + 1 कॉल होगा, जो कि मैं काफी कुशल समाधान नहीं ढूंढ रहा हूं।

public void loadData(){ 
    List<String> keys = getAllKeys(); 
    for(String s : keys) 
     cache.get(s); 
} 

या अन्य समाधान एक ConcurrentHashMap कार्यान्वयन का उपयोग करें और धागे और लापता प्रविष्टियों अपने आप के सभी संभाल करने है? मैं ऐसा करने के लिए उत्सुक नहीं हूं क्योंकि मैपमेकर और कैशबिल्डर एपीआई अतिरिक्त परीक्षण प्रदान किए बिना कुंजी-आधारित थ्रेड लॉकिंग प्रदान करते हैं। मुझे भी यकीन है कि मैपमेकर/कैशबिल्डर कार्यान्वयन में कुछ क्षमताएं होंगी जिन्हें मैं नहीं जानता/जांच करने के लिए समय नहीं मिला है।

public Element get(String key){ 
    Lock lock = getObjectLock(key); 
    lock.lock(); 
    try{ 
     Element ret = map.get(key) 
     if(ret == null){ 
      ret = getElement(key); // database call 
      map.put(key, e); 
     } 
     return ret; 
    }finally { 
     lock.unlock(); 
    } 
} 

क्या कोई मेरी दो आवश्यकताओं के बेहतर समाधान के बारे में सोच सकता है?


फ़ीचर अनुरोध

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

CacheBuilder.newBuilder().populate(new CachePopulator<String, Element>(){ 

    @Override 
    public Map<String, Element> populate() throws Exception { 
     return getAllElements(); 
    } 

}).build(new CacheLoader<String, Element>(){ 

    @Override 
    public Element load(String key) throws Exception {  
     return getElement(key); 
    } 

}); 

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

+0

गुवा समस्या सूची में सुविधा अनुरोध जोड़ें। –

+1

जोड़ा गया (अंक 775) – Richard

+1

http://code.google.com/p/guava-libraries/issues/detail?id=775 –

उत्तर

3

मैं डीबी से सभी स्थिर डेटा लोड करता हूं, और इसे cache.asMap().put(key, value) ([गुवा 10.0.1 का उपयोग करके कैश में स्टोर करता है) कैश.एएसएपी() दृश्य] [1]) पर लिखने के संचालन की अनुमति देता है।

बेशक

, इस स्थिर डेटा बेदखल हो सकता हो, अगर आपके कैश प्रविष्टियों को बेदखल करने के लिए कॉन्फ़िगर है ...

CachePopulator विचार दिलचस्प है।

+1

यह काम करेगा, लेकिन मुझे गुवा 10.0.0 का उपयोग करने के लिए मजबूर किया गया है, जो इसका उपयोग करता है कंप्यूटिंग कैश $ CacheAsMap कार्यान्वयन जो किसी भी संशोधित विधियों को बुलाया जाता है, तो एक असमर्थितऑपरेशन अपवाद को फेंकता है। आदर्श रूप से मैं अपग्रेड करूँगा लेकिन यह – Richard

+3

पल में एक विकल्प नहीं है, ठीक है, 10.0.1 एक छोटी बग फिक्स रिलीज़ थी जिसका लक्ष्य कैश.एएसएपी()। Put() को फिर से अनुमति देना था। यदि आप ऐसा छोटा अपग्रेड नहीं कर सकते हैं, तो मुझे लगता है कि आप अभी के लिए टोस्ट हैं ... –

+2

आपके आशावाद के लिए धन्यवाद :) – Richard

6

अल्पकालिक में मैं केवल Cache.asMap().putAll(Map<K, V>) का उपयोग करूंगा।

एक बार गुवा 11.0 जारी होने के बाद आप Cache.getAll(Iterable<K>) का उपयोग कर सकते हैं, जो सभी अनुपस्थित तत्वों के लिए एक ही थोक अनुरोध जारी करेगा।

+10

कैश.getAll (Iterable ) अनुपस्थित तत्वों के लिए एकल थोक अनुरोध जारी नहीं करता है। एपीआई के अनुसार, यह आपूर्ति की गई सभी चाबियों के लिए एक सिंगल कॉल जारी करेगा, जब तक कि ओवरड्रीन न हो। इस पर चर्चा के लिए कृपया http://code.google.com/p/guava-libraries/issues/detail?can=2&q=775&colspec=ID%20Type%20Status%20Milestone%20Summary&id=775 देखें – Richard

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