2014-10-28 7 views
14

मैं मास्टर है मास्टर फ़ॉलबैक। वर्तमान में मैं पढ़ रहा हूँ और केवल मास्टर डीबी के लिए लेखन, लेकिन मेरे डैशबोर्ड काफी गहन क्वेरी कर रहे हैं। मैं एक विकल्प है, जहां में मैं डेटाबेसDjango एकाधिक डेटाबेस यदि दास नीचे है

DATABASES = { 
'default_slave': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
'default': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
डैशबोर्ड, रिपोर्ट और विभिन्न अन्य क्षुधा के लिए

निम्नलिखित की तरह परिभाषित कर सकते हैं के लिए खोज रहा था, मुझे क्या करना चाहते हैं:

कोशिश कनेक्शन: default_slave: का उपयोग कर default_slave यदि default

का उपयोग करने योग्य पहुंच योग्य है, तो दास ऊपर है, तो दास डेटाबेस से रिपोर्ट प्राप्त करें, अगर मास्टर डेटाबेस से रिपोर्ट प्राप्त नहीं करते हैं।

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

क्या यह संभव है? मैं पहले से कनेक्शन का परीक्षण और आगे बढ़ने कर सकते हैं?

इस मैं लिखते थे और sync_db मास्टर में, और हमेशा की तरह, दास से पढ़ा करता है, तो गुलाम निर्भर है साथ

raw queries के लिए कुछ समाधान/संकेत की जरूरत है और साथ ही orm queries

रूटर अवधारणा अच्छा लगता है, लेकिन गुलाम लग नहीं रहा पर वापस आने, मैं संभावना पता नहीं है।

अद्यतन

कैसे बहु-डेटाबेस के बारे में जाने के लिए

डेटाबेस

DATABASES = { 
'default_slave': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
'default': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'linux': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'linux_slave': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'mac': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'mac_slave': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'pc': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 
'pc_slave': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'application', 
     'USER': 'root', 
     'PASSWORD': '', 
     'HOST': '', 
     'PORT': '3306', 
    }, 
} 

अब, मैं 1. स्टेटिक डाटा 2 की है।गतिशील डेटा

स्टेटिक डाटा 'डिफ़ॉल्ट' जो 'default_slave'

गतिशील डेटा के लिए करने के लिए दोहराया जा जाएगा में संग्रहित किया जाना है, क्वेरी पहले न्यायाधीश करने जहां गतिशील डेटा झूठ बोल रही हो सकता है की जरूरत है: में 'मैक' या 'पीसी' में या 'लिनक्स' में

कि प्राप्त करने के लिए, मैं एक क्षेत्र 'स्थिर तालिका' में कहा: 'query_on' जो होता है या तो [ 'मैक' या 'linux' या 'पीसी']

अब, क्वेरी सेट का उपयोग करते हुए, मैं बस static = Static.objects.get(pk = 1)
012 लिख रहा हूं dynamic = Dynamic.objects.get(static = static).using(alias=query_on)

यह अच्छी तरह से काम करता है, डेटाबेस के लिए क्वेरी मार्गों इसकी आवश्यकता है निष्पादित करने के लिए, यहाँ मैं न्याय की जरूरत है:

  1. <'query_on'>_slave हैं: उपयोग: <'query_on'>_slave या
  2. कनेक्शन है यदि <'query_on'>_slave: कनेक्शन डाउन है: उपयोग करें: <'query_on'>

इसके बारे में कैसे जाना है ? आवेदन के लिए

अधिक जानकारी:

  1. है एक डेटाबेस: डिफ़ॉल्ट (विन्यास & एनालिटिक्स डेटाबेस): विन्यास डेटा और रिपोर्ट का विश्लेषण डेटा
  2. 20 डेटाबेस रहे हैं बनाए रखने के लिए (कच्चे डेटाबेस): उदाहरण के तौर पर: मैक, लिनक्स, रेल, विंडोज़, पीसी .... (उदाहरण का नाम): कच्चे डेटा को इकट्ठा करने के लिए, जो विश्लेषिकी
  3. प्रत्येक डेटाबेस में एक या एकाधिक गुलाम हैं, नामकरण सम्मेलन होगा हो: default_slave _0, default_slave_1, अन्य डेटाबेस के लिए default_slave_2 और इतनी के रूप में अच्छी तरह से

अब विश्लेषण डेटा पहले 5 मिनट, 30 मिनट, 1 घंटे के प्रति पूछे जाने की आवश्यकता है .... और उस क्वेरी विशिष्ट के लिए बाहर भेजे जाने की आवश्यकता डेटाबेस, क्योंकि प्रत्येक डेटाबेस विश्लेषिकी के लिए आवश्यक विशिष्ट डेटासेट नहीं ले जाएगा।

कि ऐसा करने के लिए, हम ((गुलाम भाग सवाल यह है कि) डिफ़ॉल्ट या उसके दास में से किसी एक)

  • से विन्यास डेटा प्राप्त

    1. करने की जरूरत है एक बार हम विन्यास है, हम आसानी से देखें कि "कच्चे" डेटा
    2. कच्चे डेटा के लिए क्वेरी हो सकता है, और परिणामों को इकट्ठा कर सकता है और विश्लेषण कर सकता है -> इसे "डिफ़ॉल्ट" डेटाबेस में संग्रहीत करें।

    अब सभी 30 (कच्चे) और 1 डिफ़ॉल्ट डेटाबेस को "सिंक" की आवश्यकता होगी, क्योंकि हम सभी नोड्स में एक ही डेटा abse संरचना को बनाए रखते हैं।

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

    इसलिए using की आवश्यकता।मैं कल्पना नहीं कर सकता कि कैसे राउटर यहां मदद करेंगे?

  • उत्तर

    10

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

    अपने db_for_read में() काम करता है, तो आप अपने अनुयायी के लिए कनेक्टिविटी के लिए जाँच कर सकते हैं (FYI करें, मैं the more sensitive master->follower का उपयोग कर डेटाबेस पदानुक्रम का उल्लेख करने के लिए जा रहा हूँ)। यह थोड़ा अधिक ओवरहेड ले सकता है, लेकिन डेटाबेस के लिए ऑटो-फ़ेलओवर होने की लागत है। एक उदाहरण डेटाबेस परिभाषा होगा:

    DATABASES = { 
    'follower': { 
         'ENGINE': 'django.db.backends.mysql', 
         'NAME': 'follower', 
         'USER': 'root', 
         'HOST': '54.34.65.24', 
         'PORT': '3306', 
        }, 
    'default': { 
         'ENGINE': 'django.db.backends.mysql', 
         'NAME': 'application', 
         'USER': 'root', 
         'HOST': '54.34.65.23', 
         'PORT': '3306', 
        }, 
    } 
    

    आप एक त्वरित कोशिश के सिलसिले/this example तरह छोड़कर परीक्षण कर सकते हैं। एक रूटर क्या आप कैसा दिखेगा की जरूरत है कि इस का उपयोग करते हुए:

    from django.conf import settings 
    import socket 
    
    
    def test_connection_to_db(database_name): 
        try: 
         db_definition = getattr(settings, 'DATABASES')[database_name] 
         s = socket.create_connection((db_definition['HOST'], db_definition['PORT']), 5) 
         s.close() 
         return True 
        except (AttributeError, socket.timeout) as e: 
         return False 
    
    
    class FailoverRouter(object): 
        """A router that defaults reads to the follower but provides a failover back to the default""" 
    
        def db_for_read(self, model, **hints): 
         if test_connection_to_db('follower'): 
          return 'follower' 
         return 'default' 
    
        def db_for_write(self, model, **hints): 
         "Point all writes to the default db" 
         return 'default' 
    
        def allow_syncdb(self, db, model): 
         "Make sure only the default db allows syncdb" 
         return db == 'default' 
    

    यह अभी भी मास्टर में syncdb होगा की तरह आप चाहते हैं। इसके अलावा, आप (जैसे केवल कुछ मॉडल है कि अपनी रिपोर्ट के लिए क्वेरी कर रहे हैं के लिए डाटाबेस अनुयायी लेने।

    मैं नहीं जानता कि क्या भूमि के ऊपर इस test_connection() हर पढ़ने के लिए कारण होगा दोनों db_for_read() और db_for_write() और अधिक जटिल के लिए तर्क कर सकता है, के बाद से है कि MySQL सर्वर और समय समाप्ति पर निर्भर करेगा। शायद एक बेहतर वास्तुकला memcached का उपयोग कर इन रिपोर्टों को कैश करने के लिए, या सिर्फ बाहर मुद्दों गुलाम कभी नीचे जा के साथ अपने डेटाबेस परिभाषाओं सेटिंग में पहले काम करते हैं और अद्यतन करें।

    +0

    धन्यवाद है। यही कारण है कि चाहिए करने के काम करते हैं। मुझे क्या करना योजना बना रहा हूँ, है 'का उपयोग करना (उर्फ = defualt_slave)' यदि कनेक्शन काम करता है, शांत नहीं है, '= default' (_slave साथ विभाजन) का उपयोग कर। कि एक quic होगा के पकाना – Joddy

    +0

    कृपया प्रश्न में अद्यतन की जांच करें। मैं अभी तक समस्या को हल करने में सक्षम नहीं हूं, राउटर का उपयोग करके 'क्वेरी सेट' का उपयोग करने पर 'समझ नहीं आता है'। @krimkus – Joddy

    +0

    इसके बजाय '' query_on' using' संपत्ति को पास करने का, रूटर में है कि मूल्य को देख, जब नहीं आप क्वेरीसमूह बनाने का प्रयास करें। इस तरह, आप राउटर को अभी भी तय कर सकते हैं कि डीबी का उपयोग कैसे किया जाए। – krimkus

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