Database connection pooling: কেন লাগে ও আকার কত

Connection ব্যয়বহুল, আর database সীমিত সংখ্যক অনুমতি দেয়। Pool অল্প কয়েকটি পুনর্ব্যবহার করে। আকার ঠিক করা ও ফাঁদ এড়ানো শিখুন।

অনেক request-এর ভাগ করা অল্প কয়েকটি connection

Database connection খোলা ব্যয়বহুল: TCP handshake, TLS, authentication এবং server-পক্ষের প্রস্তুতি। PostgreSQL-এ প্রতিটি connection একটি server process ও কয়েক MB memory-ও নেয়। প্রতি request-এ একটি খোলা ধীর ও অপচয়ী।

Pool কী করে

Connection pool একবার নির্দিষ্ট সংখ্যক connection খুলে রাখে এবং request-দের ধার দেয়। Request একটি নেয়, query চালায়, ফেরত দেয়। অন্যরা সাথে সাথে পুনর্ব্যবহার করে।

  • দ্রুত request (প্রস্তুতির খরচ নেই)।
  • Connection-এর সীমা, যাতে database ডুবে না যায়।
  • সব connection ব্যস্ত থাকলে database ভাঙার বদলে request অল্প সময় queue-তে অপেক্ষা করে।

কঠিন সীমা

Database-এর সর্বোচ্চ সীমা (max_connections) আছে। ২০টি app server প্রত্যেকে ৫০টি connection খুললে আপনি ১,০০০ চাইছেন, আর database প্রত্যাখ্যান করে বা হামাগুড়ি দেয়। সব instance-এর pool আকার যোগ করে সীমার সাথে মেলান।

Pool কত বড় হবে?

মানুষ যা ভাবে তার চেয়ে ছোট। Database কেবল ততগুলো query সত্যিই সমান্তরালে চালাতে পারে, যতগুলো CPU core ও disk ক্ষমতা আছে। এর বেশি connection কেবল নিজেদের মধ্যে লড়ে এবং contention বাড়ায়। প্রচলিত শুরুর আন্দাজ (HikariCP ডকুমেন্টেশন থেকে): database server-এ প্রায় (২ x CPU core) + disk সংখ্যা, সব app instance মিলিয়ে ভাগ করে। তারপর মাপুন।

খুব ছোট pool-এর লক্ষণ: request connection-এর জন্য অপেক্ষা করছে। খুব বড়: database CPU পূর্ণ এবং সবার latency বাড়ছে।

বাইরের pooler: PgBouncer

অনেক app instance প্রত্যেকে কয়েকটি connection চাইলে PgBouncer-এর মতো বাইরের pooler PostgreSQL-এর সামনে বসে হাজারো client connection-কে অল্প কয়েকটি আসল connection-এ মিশিয়ে দেয়। Mode:

  • Session: client পুরো session-এ একটি server connection ধরে রাখে।
  • Transaction: connection শুধু transaction-এর সময় ধার দেওয়া হয়। সবচেয়ে দক্ষ, কিন্তু temporary table, advisory lock ও কিছু prepared-statement setup-এর মতো session বৈশিষ্ট্যে যত্ন লাগে।
  • Statement: প্রতি statement-এ; সীমিত।

Serverless ও স্বল্পস্থায়ী process

Serverless function একসাথে শত শত instance চালু করতে পারে, প্রত্যেকে নিজের connection খুলে database দ্রুত নিঃশেষ করে। Pooler বা database proxy, অথবা serverless-এর জন্য বানানো driver ব্যবহার করুন।

সাধারণ bug

  • Connection leak: কোড connection নেয় কিন্তু ফেরত দেয় না (error পথে release বাদ পড়ে)। Pool ধীরে ধীরে খালি হয়ে অ্যাপ ঝুলে যায়। সবসময় finally-তে release করুন বা library-র helper ব্যবহার করুন।
  • ধীর বাইরের API-র অপেক্ষার সময় connection ধরে রাখা। আগে ফেরত দিন।
  • Timeout না থাকা: connection নেওয়া, query এবং idle connection-এর জন্য timeout দিন।
  • দীর্ঘ transaction যা অনেকক্ষণ connection ধরে রাখে।

Monitoring

Active, idle ও অপেক্ষমাণ connection, pool অপেক্ষার সময়, এবং database-এর নিজস্ব connection সংখ্যা দেখুন।

মূল কথা: সবসময় pool করুন, database-এর ক্ষমতা অনুযায়ী pool ছোট রাখুন, অনেক client-এ PgBouncer নিন, এবং connection leak বা মজুদ করবেন না।


Backend ও Database সিরিজ, পর্ব ২ (performance ও operations): 3 নম্বর (মোট 6)। আগের লেখা: N+1 query সমস্যা ও সমাধান.

আরও পড়ুন

Recursion ও backtracking সহজ উদাহরণে

Recursion সমস্যার ছোট কপি সমাধান করে সমাধান করে। অনেক interview সমস্যায় ব্যবহৃত চিন্তার ধাপ ও backtracking টেমপ্লেট শিখুন।

Interview ও DSA•৩ মিনিটে পড়া