PgBouncer: قلّل اتصالات PostgreSQL من 600 لـ 80
مستوى القارئ: متوسط
هتكسب من المقال ده طريقة عملية تقلل ضغط الاتصالات على PostgreSQL قبل ما تزود حجم السيرفر أو تكسر إعدادات التطبيق.
المشكلة باختصار
لو عندك 20 نسخة من API، وكل نسخة فاتحة pool فيه 30 اتصال، أنت وصلت إلى 600 اتصال قبل أول spike حقيقي. PostgreSQL يقدر يتعامل مع اتصالات كثيرة، لكن كل اتصال له تكلفة ذاكرة وجدولة. الطريقة الشائعة الغلط إنك تزود max_connections وخلاص. الطريقة دي بتفشل لما الذاكرة تبدأ تروح لاتصالات نايمة بدل queries شغالة.
الافتراض هنا إن التطبيق عندك web API عادي، أغلب استعلاماته قصيرة، وكل request بيعمل query أو اثنين ثم يرجع الرد. في السيناريو ده PgBouncer في وضع transaction بيبقى مناسب جدًا.
الفكرة بمثال واضح
ركز في مثال مكتب الدعم. عندك 600 عميل يقدروا يفتحوا تذكرة، لكن مش كلهم بيتكلموا مع الموظف في نفس الثانية. بدل ما تعيّن 600 موظف، بتحط طابور منظم و80 موظف فعليين. العملاء ينتظروا أجزاء صغيرة من الثانية، والموظفين يشتغلوا باستمرار بدل ما يفضلوا قاعدين.
PgBouncer بيعمل نفس الفكرة. التطبيق يفتح اتصالات كثيرة مع PgBouncer، لكن PgBouncer يعيد استخدام عدد أقل من اتصالات PostgreSQL الفعلية. في transaction pooling الاتصال بالسيرفر يرجع للـ pool بعد نهاية كل transaction، مش بعد نهاية session التطبيق.
إعداد عملي قابل للنسخ
أفضل بداية: شغّل PgBouncer بجانب التطبيق أو كخدمة صغيرة داخل نفس الشبكة. بعد كده خلّي التطبيق يتصل بـ PgBouncer بدل PostgreSQL مباشرة.
# pgbouncer.ini
[databases]
appdb = host=postgres port=5432 dbname=appdb
[pgbouncer]
listen_addr = 0.0.0.0
listen_port = 6432
auth_type = md5
auth_file = /etc/pgbouncer/userlist.txt
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 80
reserve_pool_size = 20
server_idle_timeout = 60
query_wait_timeout = 5
# جرّب الاتصال عبر PgBouncer بدل 5432
psql "postgres://app_user:secret@pgbouncer:6432/appdb" -c "select now();"
# راقب عدد اتصالات PostgreSQL الفعلية
psql "postgres://admin:secret@postgres:5432/appdb" -c \
"select count(*) from pg_stat_activity where datname = 'appdb';"
لو تستخدم ORM زي Prisma أو SQLAlchemy أو Sequelize، قلل pool الداخلي في كل instance. PgBouncer مش دعوة إن كل نسخة تفتح 100 اتصال. خليها 5 إلى 10 غالبًا، وسيب PgBouncer يدير التجميع المركزي.