PgBouncer लेन-देन-पूलिंग के लिए SQLAlchemy में कनेक्शन पूलिंग का सबसे अच्छा उपयोग कैसे करें?


15

लेनदेन-स्तर पूलिंग का उपयोग करके PgBouncer के पीछे PostgreSQL डेटाबेस को क्वेरी करने के लिए SQLAlchemy का उपयोग करना।

इस तरह के सेट अप के लिए उपयोग करने के लिए सबसे अच्छा पैटर्न क्या है? क्या मुझे एक का उपयोग करके एक-इंजन-प्रति-प्रक्रिया होनी चाहिए?ConnectionPool , या मुझे प्रति-एक इंजन बनाना चाहिए, और NullPoolउनमें से प्रत्येक के लिए उपयोग करना चाहिए? क्या पूरी तरह से एक अलग पैटर्न है जिसका मुझे उपयोग करना चाहिए?

बहुत बहुत धन्यवाद! यदि मुझे अधिक जानकारी की आवश्यकता है तो मुझे बताएं और मैं ASAP को अपडेट करूंगा।

जवाबों:


9

PGBouncer के साथ, आप शायद NullPool के साथ रहना चाहते हैं। उस स्थिति में आप सबप्रोसेस में एक एकल इंजन साझा करने में सक्षम हो सकते हैं क्योंकि कोई भी सॉकेट कनेक्शन उपप्रकार सीमा से अधिक नहीं होगा। लेकिन आप इस सीमा पर, एक सक्रिय लेनदेन के साथ एक सत्र की तरह, एक कनेक्शन ऑब्जेक्ट के संदर्भ में कुछ भी साझा नहीं कर सकते। आप निश्चित रूप से "इंजन-प्रति-अनुरोध" नहीं करना चाहेंगे, हालांकि, एक इंजन एक महंगी वस्तु है जो किसी विशेष डेटाबेस URL के बारे में बहुत सारी जानकारी जमा करता है जो पहली बार इसे देखता है।


4

एप्लिकेशन नाम सेट करें

यदि आप कई प्रक्रियाओं को चलाने की अपेक्षा करते हैं, तो आपको यह जानना होगा कि वे कहां से जुड़ रहे हैं। PGBouncer इस को अदृश्य बना देगा pg_stat_activityapplication_nameआपको जिन जानकारियों की आवश्यकता होगी, उन्हें सावधानीपूर्वक सेट करके इसे हल करें :

# Sets the application name for this connection in the form of
#   application-name:user@host
prog = os.path.basename(sys.argv[0]) or 'desjob'
username = pwd.getpwuid (os.getuid ()).pw_name
hostname = socket.gethostname().split(".")[0
args.setdefault('connect_args', {'application_name': "%s:%s@%s" %
    (prog, username, hostname)})
args.setdefault('isolation_level', "AUTOCOMMIT")
engine = create_engine(url, **args)

सत्रों को प्राथमिकता दें

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

from sqlalchemy.pool import Pool, NullPool
engine = create_engine(uri, poolclass=NullPool)

निष्क्रिय लेनदेन को हटा दें

यदि आपका इरादा PGBouncer को पैमाने पर उपयोग करना है तो यह जरूरी है कि आप लेन-देन को खुला छोड़ देने से बचें। ऐसा करने के लिए आप चालू करने की आवश्यकता autocommit पर । SQLAlchemy के साथ यह सरल नहीं है ... तीन जगह हैं जहां "ऑटोकॉमिट" नामक कुछ सेट किया जा सकता है:

psycopg2 autocommit

conn = psycopg2.connect(uri)
conn.autocommit = True

असुरक्षित असुरक्षित माना जाता है क्योंकि SQLAlchemy को यह जानने की जरूरत है कि नीचे क्या हो रहा है।

सत्र ऑटोकॉमिट

Session = sessionmaker(bind=engine, autocommit=True)
session = Session()

इसके लिए सावधान, स्पष्ट रूप से सौंपने की आवश्यकता है:

session.begin()
session.execute(...)
session.rollback()

समारोह बुला और अपवाद सौंपने बेहद मुश्किल है क्योंकि है begin()और commit()नेस्टेड नहीं किया जा सकता:

def A():
  session.begin()
  ...
  session.rollback()

def B():
  session.begin()
  try:
      A() # error, already open

इस मोड में psycopg2 autocommitप्रतीत होता है False(डिफ़ॉल्ट)

इंजन ऑटोकॉमिट

इंजन को "AUTOCOMMIT"बनाते समय इंजन अलगाव मोड सेट करना नए डिफ़ॉल्ट व्यवहार को स्थापित करता है जिसे मौजूदा कोड में बदलाव की आवश्यकता नहीं हो सकती है।

engine = create_engine(uri, isolation_level="AUTOCOMMIT")

इस मोड में psycopg2 autocommit प्रतीत होता हैTrue

यहां प्रमुख समस्या यह है कि कोड के एक ब्लॉक को लेन-देन में लिपटे जाने की गारंटी देने का एकमात्र तरीका मैन्युअल रूप से बयानों का उत्सर्जन करना है:

session.execute("BEGIN")
#...
session.execute("COMMIT")
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.