2011-09-18 14 views
8

मैं रेडिस पक्ष पर बहुत मेमोरी कुशल तरीके से कुछ डेटा (वास्तव में एक बहुत बड़ी स्ट्रिंग) एन्कोड करने की कोशिश कर रहा हूं। Redis डॉक्स के अनुसार, यह दावा किया जाता है कि "उपयोग हैश जब संभव हो", और यह दो कॉन्फ़िगरेशन पैरामीटर वाणी:रेडिस मेमोरी ऑप्टिमाइज़ेशन

  • "हैश अधिकतम-zipmap-प्रविष्टियों" है, जो अगर मैं अच्छी तरह से समझ में यह दर्शाता है कि कैसे अधिकांश हैश कुंजी पर कई कुंजियां होनी चाहिए (क्या मैं सही हूँ?)।

  • "हैश-मैक्स-ज़िपमैप-वैल्यू", जो मूल्य के लिए अधिकतम लंबाई दर्शाता है। क्या यह क्षेत्र या मूल्य को संदर्भित करता है, वास्तव में? और लंबाई बाइट्स, अक्षर, या क्या है?

मेरे सोचा स्ट्रिंग ऐसी मात्रा है कि ऊपर मानकों के साथ अच्छी तरह से खेलेंगे में (जो किसी भी तरह की लंबाई तय किया है) अलग हो गए, और उन्हें मूल्यों के रूप में स्टोर करने के लिए है। क्षेत्रों के लिए एक सुसंगत डिकोडिंग सुनिश्चित करने के लिए सिर्फ अनुक्रम संख्या होना चाहिए, ..

संपादित: मैं बड़े पैमाने पर बेंचमार्क है और यह कि एक हैश में स्ट्रिंग एन्कोडिंग एक ~ 50% बेहतर स्मृति की खपत पैदावार लगता है।

import redis, random, sys 

def new_db(): 
    db = redis.Redis(host='localhost', port=6666, db=0) 
    db.flushall() 
    return db 

def db_info(db): 
    return " used memory %s " % db.info()["used_memory_human"] 

def random_string(_len): 
    letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" 
    return "".join([letters[random.randint(0,len(letters)-1)] for i in range(_len) ]) 

def chunk(astr, size): 
    while len(astr) > size: 
     yield astr[:size] 
     astr = astr[size:] 
    if len(astr): 
     yield astr 

def encode_as_dict(astr, size): 
    dod={} 
    cnt = 0 
    for i in chunk(astr,size): 
     dod[cnt] = i 
     cnt+=1 
    return dod 


db=new_db() 
r = random_string(1000000) 
print "size of string in bytes ", sys.getsizeof(r) 
print "default Redis memory consumption", db_info(db) 
dict_chunk = 10000 

print "*"*100 
print "BENCHMARKING \n" 

db=new_db() 
db.set("akey", r) 
print "as string " , db_info(db) 
print "*"*100 

db=new_db() 
db.hmset("akey", encode_as_dict(r,dict_chunk)) 
print "as dict and stored at value" , db_info(db) 
print "*"*100 

और मेरे मशीन पर परिणाम (32 बिट Redis उदाहरण):

size of string in bytes 1000024 
default Redis memory consumption used memory 534.52K 
****************************************************************************************** 
BENCHMARKING 

as string used memory 2.98M 
****************************************************************************************** 
as dict and stored at value used memory 1.49M 

अगर वहाँ स्ट्रिंग स्टोर करने के लिए एक अधिक कुशल तरीका है मैं पूछ रहा हूँ

यहाँ मेरी बेंच मार्किंग स्क्रिप्ट है मेरे द्वारा वर्णित पैरामीटर के साथ खेलकर एक हैश के रूप में। तो सबसे पहले, मुझे अवगत होना चाहिए कि उनका क्या मतलब है .. फिर मैं फिर से बेंचमार्क करूँगा और देख सकता हूं कि क्या अधिक लाभ है ..

EDIT2: क्या मैं मूर्ख हूं? बेंचमार्किंग सही है, लेकिन यह एक बड़ी स्ट्रिंग के लिए पुष्टि की गई है। यदि मैं कई बड़े तारों के लिए दोहराता हूं, तो उन्हें बड़े तारों के रूप में संग्रहित करना निश्चित विजेता है .. मुझे लगता है कि मुझे एक स्ट्रिंग के लिए उन परिणामों को प्राप्त करने का कारण रेडिस आंतरिक में है ..

+0

यदि आप क्रिप्टोग्राफ़िक हैश के बारे में बात कर रहे हैं, तो किसी भी दिए गए हैश को अलग-अलग तारों की असीमित संख्या के रूप में, उन्हें डीकोड करना असंभव है। – agf

+0

क्रिप्टोग्राफिक हैश? मैं केवल एक लाल स्ट्रिंग हैश में कुशलतापूर्वक एक बड़ी स्ट्रिंग को स्टोर करने की कोशिश कर रहा हूं, इसे एआई चंक्स में विभाजित करके, जहां लेन (एआई) <"हैश-मैक्स-ज़िपमैप-वैल्यू"। फिर मैं chunk_sequence_number का उपयोग करके इसे पुनर्स्थापित कर सकता हूं, जो वह क्षेत्र है जो प्रत्येक एआई रखता है। – hymloth

+0

मुझे रेडिस के बारे में कुछ भी पता नहीं है, लेकिन "हैश" और "डीकोड" का अर्थ अक्सर होता है कि किसी को यह समझ में नहीं आता है कि हैश फ़ंक्शन कैसे काम करता है। मुझे नहीं पता कि यह इस स्थिति पर लागू होता है या नहीं। – agf

उत्तर

6

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

एक बड़ी स्ट्रिंग को संग्रहीत करने पर प्रदर्शन छोटे स्टोर के लिए उतना अच्छा नहीं हो सकता है जितना स्टोर करने के लिए अधिक संगत ब्लॉक ढूंढने की आवश्यकता के कारण, लेकिन वास्तव में कुछ भी प्रभावित करने की संभावना नहीं है।

4

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

आप निश्चित रूप से इसे देखने के लिए बेंचमार्क कर सकते हैं।

1

Redis Memory Usage आलेख को देखने का प्रयास करें जहां आप विभिन्न डेटा प्रकारों और उनकी स्मृति खपत की अच्छी तुलना पा सकते हैं।

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