PgBouncer işlem düzeyinde havuzlama için SQLAlchemy'de bağlantı havuzu oluşturma en iyi nasıl kullanılır?


15

İşlem düzeyinde havuzlama kullanarak PgBouncer'ın arkasındaki PostgreSQL veritabanını sorgulamak için SQLAlchemy kullanma.

Bu tür bir kurulum için kullanılacak en iyi desen nedir? A kullanarak işlem ConnectionPoolbaşına bir motor almalı mıyım yoksa istek başına bir motor oluşturmalı mıyım ve NullPoolher biri için mi kullanmalıyım ? Kullanmam gereken tamamen farklı bir model var mı?

Çok teşekkürler! Daha fazla bilgi gerekip gerekmediğini bana bildirin, en kısa sürede güncelleyeceğim.

Yanıtlar:


9

PGBouncer ile muhtemelen NullPool'a sadık kalmak istersiniz. Bu durumda, alt süreç sınırı boyunca soket bağlantısı taşınmayacağından, tek bir Motoru alt süreçler arasında paylaşabilirsiniz. Ancak, etkin bir işleme sahip Oturum gibi bir Connection nesnesine başvuran hiçbir şeyi bu sınır üzerinden paylaşamazsınız. Kesinlikle "istek başına motor" yapmak istemezsiniz, bir Motor, ilk gördüğünde belirli bir veritabanı URL'si hakkında çok fazla bilgi toplayan pahalı bir nesnedir.


4

Uygulama Adını Belirleme

Birçok işlemi çalıştırmayı düşünüyorsanız, nereden bağlandıklarını bilmeniz gerekir. PGBouncer bunu görünmez yapacak pg_stat_activity. Bunu, application_nameihtiyacınız olan bilgilerle dikkatlice ayarlayarak çözün :

# 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)

Oturumları Tercih Et

Bir Engine nesnesinden gelen istekler birden fazla bağlantıya yayılabileceğinden ve bekletilebildiğinden Oturumlar'ı kullanın. Postgres'e bağlanmak çok pahalı değil, PGBouncer ile daha da az. NullPoolPostgres'te göreceğiniz tek bağlantılar aslında kullanılan bağlantılar olacak şekilde her zaman kullanırım .

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

Boşta Kalma İşlemlerini Ortadan Kaldırın

Amacınız ölçeklemek için PGBouncer kullanmaksa, işlemlerin açık kalmasını önlemek kaçınılmazdır. Eğer açmanız gerekir Bunu yapmak için autocommit ilgili . Bu SQLAlchemy ile basit değil ... "autocommit" adı verilen bir şeyin ayarlanabileceği üç yer var:

psycopg2 otomatik taahhüdü

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

Güvensiz olduğu varsayıldı çünkü SQLAlchemy'nin altında neler olduğunu bilmesi gerekiyor.

Oturum otomatik taahhüdü

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

Bu, dikkatli ve açık bir teslim gerektirir:

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

Fonksiyon çağırma ve istisna teslim çünkü son derece zordur begin()ve commit()iç içe olamaz:

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

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

Bu modda psycopg2 autocommitgörünür olması False(varsayılan)

Motor otomatik taahhüdü

Motor "AUTOCOMMIT"oluşturulurken Motor yalıtım modunun ayarlanması, mevcut kodda değişiklik yapılmasını gerektirmeyen yeni varsayılan davranış oluşturur.

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

Bu modda psycopg2 autocommit,True

Buradaki en büyük sorun, bir işlemin bir kod bloğunun sarıldığını garanti etmenin tek yolunun ifadeleri elle yaymaktır:

session.execute("BEGIN")
#...
session.execute("COMMIT")
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.