چگونه یک کلستر دیتابیس PostgreSQL پرسرعت و Redundant بسازیم؟

راه‌اندازی یک کلستر دیتابیس PostgreSQL پرسرعت و Redundant، چالش اصلی بسیاری از تیمهای توسعه و زیرساخت است که به دنبال حذف نقطه شکست واحد و تضمین پایداری سرویس در شرایط بحرانی هستند. در این مقاله، بدون پرداختن به حاشیه، دقیقاً یاد میگیرید که چگونه با ترکیب Replication، مدیریت خودکار Failover و سخت‌افزار مناسب، یک معماری مقاوم و سریع برای دیتابیس PostgreSQL خود بسازید. از انتخاب توپولوژی درست تا بهینه‌سازی پارامترهای performance و انتخاب VPS مناسب را پوشش می‌دهیم.

تجربه عملی نشان می‌دهد که بسیاری از خطاهای تولید، ناشی از پیکربندی نادرست replication یا نبود مکانیزم خودکار برای تشخیص خرابی است. در ادامه، یک نقشه راه دقیق و قابل اجرا ارائه می‌شود که در محیط‌های واقعی تست شده است.

اهمیت معماری Redundant در PostgreSQL

در یک دیتابیس PostgreSQL تکی، هرگونه خرابی دیسک، قطعی شبکه یا crash نرم‌افزاری به معنی از دست رفتن سرویس و احتمالاً داده است. معماری Redundant با توزیع داده روی چند نود، Uptime را به شدت افزایش می‌دهد و امکان بازیابی سریع را فراهم می‌کند. اما redundancy به تنهایی کافی نیست؛ سرعت replication و تأخیر بین نودها نیز باید در سطح قابل قبولی باشد تا کاربران متوجه هیچ کندی نشوند.

برای رسیدن به یک کلستر پرسرعت، باید دو عامل اصلی را همزمان مدیریت کنید: اول، همگام‌سازی داده‌ها با کمترین latency؛ دوم، انتخاب سخت‌افزاری که I/O و throughput شبکه بالایی داشته باشد. در غیر این صورت، نود standby همیشه عقب می‌ماند و در زمان failover با داده‌های قدیمی مواجه می‌شوید.

انتخاب توپولوژی مناسب برای کلستر PostgreSQL

پیش از هر اقدامی، باید تصمیم بگیرید از کدام روش replication استفاده کنید. PostgreSQL به صورت بومی دو روش اصلی ارائه می‌دهد: Streaming Replication و Logical Replication. در کنار آن، ابزارهایی مانند Patroni و repmgr برای مدیریت خودکار کلستر بسیار رایج هستند.

Streaming Replication

این روش مبتنی بر ارسال WAL (Write-Ahead Log) از نود primary به standby ها است. Streaming Replication می‌تواند به صورت asynchronous یا synchronous پیکربندی شود. در حالت همگام، primary تا زمانی که standby تأیید ذخیره داده را ارسال نکند، تراکنش را commit نمی‌کند؛ این کار احتمال از دست رفتن داده را تقریباً صفر می‌کند اما latency را افزایش می‌دهد. در حالت ناهمگام، کارایی بالاتر است ولی ممکن است در لحظه failover چند تراکنش از دست برود.

Logical Replication

برخلاف streaming که فیزیکی است و کل دیتابیس را کپی می‌کند، Logical Replication امکان انتخاب جداول خاص یا حتی تغییر ساختار داده را فراهم می‌کند. برای سناریوهای نیازمند جداسازی دیتابیس‌های مختلف یا ارتقاء بدون downtime بسیار مفید است، اما سربار CPU بالاتری دارد و برای کلسترهای ساده شاید بیش از حد پیچیده باشد.

Patroni و etcd

Patroni یک راه‌کار محبوب برای مدیریت خودکار failover و انتخاب primary در PostgreSQL است. این ابزار با استفاده از یک distributed consensus store مانند etcd یا Consul، سلامت نودها را مانیتور کرده و در صورت از کار افتادن primary، به طور خودکار یکی از standby ها را ارتقا می‌دهد. این روش در مقایسه با repmgr، انعطاف‌پذیری و پایداری بیشتری در محیط‌های production دارد.

مقایسه راهکارهای کلاسترینگ

ویژگیStreaming ReplicationLogical ReplicationPatroni + etcd
نوع replicationفیزیکی، کل دیتابیسمنطقی، انتخابیترکیبی با مدیریت خودکار
Failover خودکارخیرخیربله
پیچیدگی پیاده‌سازیکممتوسطزیاد
تأخیر دادهبسیار کم (WAL)بیشتر از streamingبستگی به حالت sync/async دارد
مناسب برایکلسترهای ساده HAسناریوهای خاص و ارتقاءمحیط‌های production حساس

پیش‌نیازهای سخت‌افزاری و شبکه‌ای

برای داشتن یک کلستر PostgreSQL پرسرعت، سه مؤلفه حیاتی هستند: دیسک NVMe با تأخیر پایین، حافظه RAM کافی برای نگه‌داشتن shared buffers و اتصال شبکه پرسرعت بین نودها. اگر از VPS استفاده می‌کنید، حتماً مدل‌های مبتنی بر KVM با دیسک NVMe را انتخاب کنید؛ مجازی‌سازی‌های غیر KVM معمولاً I/O ناپایداری دارند که replication را مختل می‌کند.

  • حداقل ۴ هسته CPU اختصاصی برای نودهای primary و standby
  • حداقل ۸ گیگابایت RAM برای دیتابیس‌های متوسط؛ افزایش بر اساس حجم داده
  • دیسک NVMe با IOPS حداقل ۱۰ هزار برای بار تراکنشی بالا
  • شبکه داخلی با پهنای باند حداقل ۱ گیگابیت و latency زیر ۵ میلی‌ثانیه بین نودها
  • فضای کافی برای نگه‌داری WAL ها و backup ها

راه‌اندازی کلستر دیتابیس PostgreSQL پرسرعت و Redundant با Patroni

در این بخش، گام‌های عملی برای استقرار یک کلستر سه نودی با Patroni و etcd را مرور می‌کنیم. فرض بر این است که هر نود دارای سیستم‌عامل Ubuntu 22.04 و دسترسی root است.

نصب PostgreSQL و Patroni

ابتدا PostgreSQL را نصب کرده و سپس Patroni را از مخزن رسمی اضافه کنید:

پیکربندی etcd

etcd را روی هر سه نود نصب کنید یا از یک سرویس مدیریت‌شده استفاده کنید. فایل پیکربندی etcd را طوری تنظیم کنید که نودها همدیگر را پیدا کنند:

سرویس etcd را استارت کرده و وضعیت cluster را بررسی کنید.

تنظیم فایل پیکربندی Patroni

برای هر نود یک فایل YAML مشابه زیر بسازید و آدرس‌ها را متناسب با نود تغییر دهید:

پس از استارت Patroni، یک نود به عنوان primary انتخاب می‌شود و بقیه به عنوان standby به آن متصل می‌شوند.

تست Failover

برای اطمینان از عملکرد redundancy، به صورت دستی سرویس PostgreSQL را روی نود primary متوقف کنید:

Patroni باید در کمتر از ۳۰ ثانیه یکی از standby ها را به primary ارتقا دهد و اپلیکیشن شما با استفاده از VIP یا HAProxy به دیتابیس جدید متصل شود.

بهینه‌سازی Performance در کلستر

سرعت یک کلستر تنها به replication بستگی ندارد؛ تنظیمات داخلی PostgreSQL نیز نقش تعیین‌کننده‌ای دارد. پارامترهای زیر را بر اساس حجم RAM و نوع Workload تنظیم کنید:

  • shared_buffers: حدود ۲۵٪ از RAM کل
  • effective_cache_size: حدود ۵۰ تا ۷۵٪ از RAM
  • work_mem: برای تراکنش‌های پیچیده، ۱۶ تا ۶۴ مگابایت
  • maintenance_work_mem: برای عملیات VACUUM و index، حداقل ۵۱۲ مگابایت
  • wal_buffers: مقدار ۶۴ مگابایت برای محیط‌های پرتراکنش مناسب است
  • checkpoint_timeout: افزایش به ۱۵ دقیقه برای کاهش I/O ناگهانی
  • max_wal_size: مقدار ۴ تا ۸ گیگابایت برای جلوگیری از checkpoint های مکرر

برای replication پرسرعت، همیشه از حالت synchronous_commit = remote_apply استفاده نکنید مگر آنکه به تضمین کامل durability نیاز داشته باشید. گزینه remote_write یا حتی async با tolerate کمی ریسک، throughput را به شدت بهبود می‌دهد.

نقش زیرساخت ابری و VPS در پایداری کلستر

اگر نمی‌خواهید سرورهای فیزیکی را مدیریت کنید، انتخاب VPS مناسب حیاتی است. هنگام خرید VPS برای کلستر PostgreSQL، به موارد زیر دقت کنید:

  • مجازی‌سازی KVM که ایزوله‌سازی کامل منابع را فراهم می‌کند
  • دیسک NVMe به جای SSD سنتی؛ تأخیر write را تا ۱۰ برابر کاهش می‌دهد
  • شبکه داخلی پرسرعت بین نودها در همان دیتاسنتر
  • امکان snapshot گیری روزانه برای بازیابی سریع
  • IP ثابت و پهنای باند نامحدود برای replication پیوسته

یک VPS ایده‌آل برای نود primary باید حداقل ۸ گیگابایت RAM و ۴ vCPU با دیسک NVMe داشته باشد. نودهای standby می‌توانند کمی ضعیف‌تر باشند اما هرگز نباید از نظر I/O خیلی عقب‌تر باشند، وگرنه replication lag ایجاد می‌شود.

نتیجه‌گیری

ساخت یک کلستر دیتابیس PostgreSQL پرسرعت و Redundant مستلزم ترکیب هوشمندانه سه عنصر است: معماری replication مناسب، ابزار مدیریت خودکار failover مانند Patroni، و زیرساخت سخت‌افزاری با دیسک NVMe و شبکه پایدار. با پیروی از گام‌های این مقاله، می‌توانید یک محیط production با Uptime بالای ۹۹.۹٪ ایجاد کنید که در برابر خرابی‌های ناگهانی مقاوم است و در عین حال پاسخگویی سریعی به اپلیکیشن‌ها ارائه می‌دهد.

همیشه به یاد داشته باشید که redundancy به تنهایی کافی نیست؛ باید به‌طور مداوم lag replication، سلامت دیسک‌ها و تست‌های failover را مانیتور کنید تا در لحظه بحران، کلستر شما واقعاً کار کند.

سوالات متداول

تفاوت بین replication همگام و ناهمگام در PostgreSQL چیست؟

در حالت همگام، primary منتظر تأیید standby برای commit شدن تراکنش می‌ماند و بنابراین هیچ داده‌ای از دست نمی‌رود. در حالت ناهمگام، primary بدون انتظار commit می‌کند که سرعت بالاتری دارد اما در failover ممکن است چند تراکنش آخر از بین بروند.

آیا می‌توان از Patroni بدون etcd استفاده کرد؟

بله، Patroni از چندین DCS پشتیبانی می‌کند: etcd، Consul، ZooKeeper و حتی Kubernetes API. اما etcd به دلیل سبک بودن و همگرایی سریع، پرکاربردترین انتخاب است.

حداقل تعداد نود برای یک کلستر PostgreSQL چقدر است؟

برای داشتن redundancy و جلوگیری از Split-Brain، حداقل ۳ نود توصیه می‌شود: یک primary و دو standby. با ۲ نود، خطر از دست رفتن quorum در etcd وجود دارد و failover خودکار ممکن است ناپایدار شود.

چگونه می‌توان از مشکل Split-Brain جلوگیری کرد؟

با استفاده از یک DCS قابل اعتماد مانند etcd با تعداد فرد نود (۳ یا ۵)، تنظیم صحیح quorum و فعال کردن pg_rewind در Patroni. این کار تضمین می‌کند که در هر لحظه فقط یک primary در کلستر وجود داشته باشد.

چه میزان RAM برای یک نود PostgreSQL با ترافیک بالا مناسب است؟

بسته به حجم دیتابیس و تعداد اتصالات، حداقل ۱۶ گیگابایت برای ترافیک متوسط توصیه می‌شود. برای دیتابیس‌های بزرگتر از ۵۰۰ گیگابایت، ۳۲ تا ۶۴ گیگابایت RAM و دیسک NVMe با IOPS بالا ضروری است تا shared buffers و کش سیستم‌عامل به خوبی عمل کنند.