के लिए प्री लोड लोड मान मुझे एक आवश्यकता है जहां हम जावा एप्लिकेशन में उपयोग के लिए डेटाबेस से स्थिर डेटा लोड कर रहे हैं। प्रारंभ मेंएक गुवा कैश
- लोड डेटाबेस से सभी स्थैतिक डेटा (एक बार लोड, इस डेटा नहीं बदलेगा)
- लोड नए डेटा डेटाबेस (डेटाबेस में मौजूद डेटा से: किसी भी कैशिंग तंत्र निम्नलिखित कार्यक्षमता होना चाहिए अप नहीं बदलेगा लेकिन नया डेटा जोड़ना संभव है)
सभी डेटा की आलसी लोडिंग एक विकल्प नहीं है क्योंकि एप्लिकेशन को कई भौगोलिक स्थानों पर तैनात किया जाएगा और एक डेटाबेस के साथ संवाद करना होगा। डेटा को आलसी लोड करने से एक विशिष्ट तत्व के लिए पहला अनुरोध बहुत धीमा हो जाएगा जहां एप्लिकेशन डेटाबेस के लिए एक अलग क्षेत्र में है।
मैं सफलता के साथ गुवा में मैपमेकर एपीआई का उपयोग कर रहा हूं लेकिन अब हम नवीनतम रिलीज में अपग्रेड कर रहे हैं और मुझे कैशबिल्डर एपीआई में एक ही कार्यक्षमता नहीं मिल रही है; मुझे स्टार्ट-अप पर सभी डेटा लोड करने का एक साफ तरीका नहीं दिख रहा है।
एक तरीका डेटाबेस से सभी चाबियाँ लोड करना होगा और अलग-अलग कैश के माध्यम से लोड करना होगा। यह काम करेगा लेकिन परिणामस्वरूप डेटाबेस में एन + 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);
}
});
इस कार्यान्वयन कैश सभी प्रासंगिक तत्व के साथ पहले से भरी हुई करने की अनुमति होगी ऑब्जेक्ट्स, अंतर्निहित कस्टमकोनकुरेंट हैशैप को बाहरी दुनिया में गैर-दृश्यमान रखने के दौरान।
गुवा समस्या सूची में सुविधा अनुरोध जोड़ें। –
जोड़ा गया (अंक 775) – Richard
http://code.google.com/p/guava-libraries/issues/detail?id=775 –