دیتابیس قلب تپندهٔ هر سیستم نرمافزاری است؛ وقتی دیتابیس از کار بیفتد، عملاً همهچیز متوقف میشود. با این حال، بسیاری از پروژهها سالها با یک نمونهٔ تکنود PostgreSQL کار میکنند تا روزی که یک خرابی سختافزاری یا یک خطای انسانی، سرویس را ساعتها از دسترس خارج کند.
PostgreSQL — قدرتمندترین دیتابیس متنباز رابطای — در نسخهٔ ۱۷.۲ امکانات کاملی برای ساخت کلاستر با دسترسپذیری بالا (High Availability) ارائه میدهد: ریپلیکیشن استریمینگ، فیلاوور خودکار با ابزارهایی مثل Patroni، ریپلیکای خواندن و بازیابی در نقطهٔ زمانی. در این مقاله یاد میگیریم که یک کلاستر PostgreSQL با دسترسپذیری بالا چطور کار میکند و چه چیزی را باید از آن انتظار داشته باشیم.
دیتابیس تکنمونهای چه کمبودهایی دارد؟
- نقطهٔ شکست واحد (SPOF) — اگر سرور، دیسک یا شبکهٔ آن از کار بیفتد، دیتابیس و همهٔ سرویسهای وابسته از دسترس خارج میشوند
- توقف برای نگهداری — ارتقاء نسخه، تغییر پیکربندی، نصب پچ امنیتی یا ریبوت یعنی توقف کامل سرویس
- بدون مقیاسپذیری خواندن — همهٔ کوئریها، حتی سنگینترینها، به یک سرور وارد میشوند
- بازیابی آهسته — در بدترین حالت باید از بکاپ برگردید؛ کاری که بسته به حجم داده، ساعتها زمان میبرد
هدف کلاستر با دسترسپذیری بالا، حذف همین محدودیتهاست: چند نسخه از داده نگه میداریم، خرابی را خودکار جبران میکنیم و کارهای نگهداری را بدون توقف انجام میدهیم.
ریپلیکیشن استریمینگ (Streaming Replication)
پایهٔ همهٔ راهحلهای HA در پستگرس، ریپلیکیشن استریمینگ است: دادهها به شکل تغییرات WAL (Write-Ahead Log) از نود اصلی (Primary) به نودهای کپی (Replica یا Standby) ارسال میشود و هر replica به صورت پیوسته آن را اعمال میکند. یک primary میتواند دهها replica داشته باشد.
ریپلیکیشن در دو حالت قابل تنظیم است:
- ناهمگام (Asynchronous) — تاخیر کمتر در نوشتن، اما در صورت خرابی ناگهانی primary، ممکن است کمی از دادهٔ آخرین لحظه از دست برود
- همگام (Synchronous) — تراکنش فقط بعد از نوشتهشدن روی replicaٔ همگام، به کلاینت تایید میشود؛ در فیلاوور حتی یک تراکنش از دست نمیرود، به قیمت تاخیر کمی بیشتر
راهکار استاندارد، ترکیب این دو است: یک replica همگام برای تضمین تحویل داده (صفر از دست رفتن) و چند replica ناهمگام برای ترافیک خواندن.
فیلاوور خودکار (Automatic Failover)
وقتی primary از کار میافتد، یکی از replicaها باید نقش اصلی را بگیرد. انجام این کار به صورت دستی — مخصوصاً ساعت ۳ نیمهشب — هم آهسته است و هم پرخطا؛ به همین دلیل ابزارهای فیلاوور خودکار ساخته شدهاند:
Patroni
محبوبترین مدیر HA برای PostgreSQL. پاترونی وضعیت همهٔ نودها را در یک دیتابیس توزیعشده مثل etcd، Consul یا ZooKeeper ثبت میکند. وقتی primary از کار بیفتد، پاترونی از طریق مکانیزم قفل توزیعشده، مطمئنترین replica (با کاملترین داده) را به Leader تبدیل میکند — معمولاً در چند ثانیه و کاملاً خودکار:
patronictl list
+ Cluster: lexoya-pg -+-----------+---------+-------+-----------+
| Member | Host | Role | State | TL | Lag |
+--------+-----------+----------+--------+----+---------+
| pg-1 | 10.0.0.11 | Leader | running| 1 | 0 |
| pg-2 | 10.0.0.12 | Replica | running| 1 | 0 |
| pg-3 | 10.0.0.13 | Replica | running| 1 | 0 |
+--------+-----------+----------+--------+----+---------+repmgr
جایگزین سبکتر و سادهتر پاترونی که مدیریت replicaها، ارتقاء به primary و فیلاوور را با ابزار خط فرمان repmgr انجام میدهد. برای تیمهایی که به سراغ etcd و قفل توزیعشده نمیخواهند بروند، گزینهٔ خوبی است.
نقش etcd و Consul
ابزارهای HA برای جلوگیری از Split-Brain (دو primary همزمان) به اکثریت (Quorum) متکیاند: فقط نودهایی که بتوانند با اکثریت دیکشنری توزیعشده ارتباط برقرار کنند، اجازهٔ گرفتن نقش Leader را دارند. به همین دلیل در کلاستر پاترونی، سه نود داده + سه نود etcd ترکیب استاندارد است.
ریپلیکای خواندن (Read Replicas)
در کلاستر HA، ترافیک خواندن را میتوانید بین replicaها توزیع کنید: نوشتنها به primary میروند و کوئریهای سنگین گزارشگیری یا کوئریهای پرمصرف روی replicaها اجرا میشوند. ابزارهای مسیریابی مثل HAProxy، pgpool-II یا pgBouncer این تقسیم بار را مدیریت میکنند.
نکتهٔ مهم: دادهٔ روی replicaها به اندازهٔ primary بهروز نیست (Replication Lag). برای دادههای حساس به تازگی، باید از primary بخوانید یا برنامه را با این تاخیر سازگار کنید.
بازیابی در نقطهٔ زمانی (PITR)
با آرشیو پیوستهٔ WAL، میتوانید دیتابیس را به هر نقطه از زمان برگردانید: مثلاً دقیقاً قبل از یک DELETE اشتباهی یا یک حملهٔ باجافزاری. این قابلیت (Point-in-Time Recovery) یکی از قدرتمندترین مزیتهای پستگرس است و در یک کلاستر HA به صورت استاندارد پیکربندی میشود.
بدون توقف برنامهریزیشده (No Planned Downtime)
در یک کلاستر HA، حتی کارهای نگهداری هم بدون قطعی انجام میشوند: برای ارتقاء نسخهٔ اصلی، ابتدا replicaها را یکییکی ارتقاء میدهید، سپس با Switchover (فیلاوور برنامهریزیشده) نقش primary را جابهجا میکنید و در آخر نود قبلی را ارتقاء میدهید. کاربران در تمام این مدت هیچ وقفهای نمیبینند — همین «بدون downtime برنامهریزیشده» بزرگترین تفاوت یک کلاستر واقعی با یک نمونهٔ تکنود است.
مقایسه راهها: تکنمونه، ریپلیکیشن دستی، کلاستر مدیریتشده
سه مسیر رایج برای راهاندازی PostgreSQL را مقایسه میکنیم:
| ویژگی | تکنمونه (بدون HA) | ریپلیکیشن دستی | کلاستر مدیریتشده (DBaaS) |
|---|---|---|---|
| تحمل خرابی | هیچ — توقف کامل | نسبی — فیلاوور دستی و زمانبر | خودکار در چند ثانیه |
| فیلاوور | ندارد | دستی و پرریسک (ساعتها توقف) | اتوماتیک و قابل اعتماد |
| مقیاسپذیری خواندن | ندارد | بله، با پیکربندی دستی | بله — چند replica با یک کلیک |
| ارتقاء و نگهداری | توقف کامل سرویس | پیچیده و پرریسک | بدون توقف (rolling) |
| PITR | وابسته به بکاپ دستی | وابسته به تنظیمات دستی | معمولاً داخلی |
| پیچیدگی نگهداری | کم | بالا — نیاز به تیم متخصص | صفر — ارائهدهنده مدیریت میکند |
| مناسب برای | پروژهٔ کوچک، دمو، توسعه | تیمهای متخصص دیتابیس | کسبوکارهای حیاتی |
موارد استفاده (Use Cases)
- سامانههای تراکنشی حیاتی — بانک، فروشگاه اینترنتی، بیمه و سامانههای دولتی که توقف حتی چند دقیقهای قابل قبول نیست
- اپلیکیشنهای SaaS با قرارداد SLA — مشتریان شما باید پاسخگویی ۲۴/۷ را تضمین شده ببینند
- بار خواندن بالا — پنلهای مدیریتی و داشبوردهایی که گزارشگیری سنگین را از primary جدا میکنند
- نگهداری بدون توقف — ارتقاء نسخه و پچ امنیتی در ساعات کاری، بدون خالیکردن صف کاربران
- کاهش ریسک خطای انسانی — PITR برای بازگشت به قبل از یک خطای DELETE یا بهروزرسانی اشتباه
چه زمانی کلاستر PostgreSQL انتخاب مناسبی است؟
- توقف دیتابیس برای کسبوکار شما هزینهٔ واقعی دارد (درآمد، اعتبار یا قانون)
- به هدف بازیابی مشخص نیاز دارید — مثلاً RTO چند دقیقه و RPO صفر
- ترافیک خواندنتان بالا رفته و یک سرور دیگر برای خواندن نیاز دارید
- میخواهید ارتقاء و نگهداری را بدون توقف انجام دهید
- به PITR و بازیابی دقیق در برابر خطای انسانی نیاز دارید
کلاستر PostgreSQL برای چه چیزهایی مناسب نیست؟
- پروژههای کوچک و دمو — سه نود به اضافهٔ etcd برای یک اپلیکیشن کمترافیک، هزینه و پیچیدگی بیدلیل است؛ یک نمونه با بکاپ منظم کافی است
- مقیاسپذیری نوشتن — کلاستر HA نوشتن را مقیاس نمیکند؛ همهٔ نوشتنها به یک primary میرود. برای نوشتن توزیعشده باید به سمت شاردینگ بروید
- تیم بدون مهارت عملیاتی — اگر کسی برای نگهداری etcd، پاترونی و فیلاوور ندارید، ساخت HA دستی بدتر از نبودِ آن است؛ گزینهٔ مدیریتشده را در نظر بگیرید
- هزینهٔ سختافزار مهمتر از در دسترسبودن است — چند نود و دیکشنری توزیعشده هزینهٔ واقعی دارند
PostgreSQL در لکسویا
ساخت یک کلاستر HA درست، به انتخاب ابزار، پیکربندی etcd، تنظیم sync replication و مانیتورینگ فیلاوور نیاز دارد — یعنی روزها کار تخصصی. لکسویا این پیچیدگی را به چند کلیک تبدیل کرده است.
لکسویا این دیتابیس را به عنوان سرویس دیتابیس ابری (DBaaS) ارائه میدهد — با چند کلیک نمونهٔ تکنمونهای یا کلاستر با دسترسپذیری بالا راه بیندازید.
نتیجهگیری
PostgreSQL به لطف ریپلیکیشن استریمینگ، ابزارهای بالغی مثل Patroni و قابلیت PITR، یکی از بهترین گزینههای دنیا برای ساخت کلاستر با دسترسپذیری بالا است. با یک کلاستر درست، خرابی سرور چند ثانیه طول میکشد، ارتقاء بدون توقف انجام میشود و ترافیک خواندن بین چند نود تقسیم میشود.
اما HA جایگزین بکاپ نیست و برای همه هم لازم نیست. تصمیم درست این است که بر اساس هزینهٔ توقف برای کسبوکارتان تصمیم بگیرید — و اگر به آن رسیدید، اجرای درست آن (خودتان یا به شکل مدیریتشده) از روز اول آیندهٔ نرمافزار شما را تضمین میکند.