مقیاسپذیری بدون مهاجرت! درسهایی از تیم دیتابیس Figma

خیلی از ما وقتی با محدودیتهای عملکردی یا مقیاسپذیری در دیتابیس مواجه میشویم، اولین فکری که به ذهنمان میرسد، مهاجرت به یک تکنولوژی دیگر است:
«شاید وقتشه بریم سمت NoSQL»، یا «بیایید CockroachDB رو تست کنیم»، یا «با BigQuery دردسر نداریم!»
اما همیشه این راهحلها بهترین نیستند. گاهی، استفادهی هوشمندانهتر از همان ابزارهای فعلی، هم هزینهی کمتری دارد، هم ریسک پایینتری، و هم بازدهی بیشتر.
📚 تیم دیتابیس Figma دقیقاً همین تصمیم را گرفتند و به جای مهاجرت از PostgreSQL، در طی ۹ ماه، زیرساختی طراحی کردند که تقریباً به مقیاسپذیری بینهایت رسید — بدون تغییر ابزار، بدون بازنویسی اپلیکیشن، و بدون ورود به تکنولوژیهای ناشناخته.
📚 بیایید با هم نگاهی بیندازیم به سفر ۹ ماههی تیم فنی Figma برای مقیاسپذیر کردن PostgreSQL که بدون ترک ابزارهای آشنا، راهی برای تقریباً بینهایت شدن باز کردند
منبع : https://www.figma.com/blog/how-figmas-databases-team-lived-to-tell-the-scale/
🔹 مرحله اول: Vertical Partitioning
فیگما در ابتدا جداول بزرگ و پرترافیک مثل فایلها، کامنتها و سازمانها را بر اساس حوزهی عملکردیشان جدا کرد و آنها را روی دیتابیسهای مستقل قرار داد.
این کار باعث شد بدون دست زدن به اپلیکیشن، فشار روی CPU و IOPS کاهش یابد و امکان اسکیل مستقل هر بخش فراهم شود.
🎯 نتیجه؟ کاهش چشمگیر بار سیستم و سادهتر شدن مسیر مهاجرت به شاردینگ افقی.
🔹 مرحله دوم: اندازهگیری ظرفیت واقعی سیستم
قبل از هرگونه طراحی پیچیده، تیم فیگما با دقت تمام دادهها را اندازهگیری و تحلیل کردند.
سوالهایی مثل:
کدام جدولها بزرگتر از حد معمول هستند؟
نرخ نوشتن و خواندن روی کدام بخشها بیشتر است؟
محدودیتهای CPU و IOPS دقیقاً کجا دیده میشود؟
Bottleneckهای واقعی چه هستند و کدام بخشها صرفاً «حدس» هستند؟
این مرحله به تیم کمک کرد تا تمرکزش را روی مناطقی با بیشترین فشار عملیاتی بگذارد و بداند دقیقاً کدام بخشها نیاز به شاردینگ واقعی دارند.
با کمک متریکهای دقیق مثل حجم جداول، نرخ نوشتن، میزان CPU مصرفی و IOPS، تیم توانست نقاط گلوگاه را شناسایی کند. جداولی که خیلی بزرگ یا پرترافیک بودند، در لیست اولویت قرار گرفتند.
🔹 مرحله سوم: Horizontal Sharding
اینجا جادو شروع شد! 👇
✅ شاردینگ منطقی قبل از فیزیکی
تیم ابتدا شاردینگ منطقی را با استفاده از Views روی جداول اعمال کرد:
با این روش، سیستم طوری رفتار میکرد که انگار دیتابیس فیزیکیاش شارد شده — بدون اینکه دادهها واقعاً جابجا شوند.
✅ طراحی DBProxy برای مدیریت شاردها
برای هدایت کوئریها به شارد مناسب، یک سرویس Go به نام DBProxy ساختند. این سرویس بین اپلیکیشن و PGBouncer قرار گرفت و شامل اجزای زیر بود:
🔍 Query Parser: تبدیل SQL به AST
🧠 Logical Planner: استخراج shard_id از AST
📦 Physical Planner: ترجمه کوئری به سمت دیتابیس فیزیکی مناسب
⛓️ Load shedding، observability و پشتیبانی از transactionها
✅ مدیریت “scatter-gather” هوشمند
اگر کوئری شامل shard key بود، فقط روی یک شارد اجرا میشد.
اما در صورت نبود کلید شارد، DBProxy کوئری را به همهی شاردها پخش میکرد (scatter) و نتایج را جمع میکرد (gather). برای جلوگیری از پیچیدگی، فقط subset محدودی از SQL را پشتیبانی کردند (مثلاً فقط joinهایی که روی shard key و در یک colo بودند).
✅ آنالیز real-world queries
برای انتخاب بهترین subset، از ترافیک واقعی production یک «shadow planner» ساختند و کوئریها را در Snowflake تحلیل کردند. نتیجه؟ طراحی یک زبان SQL سفارشی برای شاردینگ که ۹۰٪ استفادهها را پوشش میداد.
🔹 مرحله چهارم: شاردینگ فیزیکی
بعد از اطمینان از عملکرد صحیح شاردینگ منطقی، تیم به سراغ تقسیم فیزیکی دادهها رفت. دادهها به N دیتابیس جدید منتقل شدند، و ترافیک به صورت real-time از طریق DBProxy به شاردهای فیزیکی هدایت شد.
همهی این مراحل با feature flag و قابلیت rollback فوری انجام شد.
🎯 نتایج کلیدی:
– بدون مهاجرت به دیتابیس جدید به مقیاسپذیری نزدیک به بینهایت آنهم با پستگرس رسیدند.
– از ابزارهای آشنا مثل PostgreSQL و RDS استفاده کردند.
– سیستم query engine سفارشی ساختند که هم سریع بود و هم قابل مدیریت.
– عملکرد و پایداری حفظ شد، حتی در هنگام failover به شاردهای جدید.
💡 درس بزرگ این سفر؟
درسی که از Figma میگیریم این است که:
گاهی باید قبل از «تغییر ابزار»، «طراحی را تغییر دهی».
اگر شما هم با PostgreSQL یا هر دیتابیس دیگری کار میکنید، شاید پاسخ چالش مقیاسپذیری در خلاقیت معماری نهفته باشد، نه در مهاجرت.
با درک بهتر از نیاز واقعی، تحلیل دقیق ترافیک، و استفادهی هوشمندانه از ابزارها، میشود سیستمهایی ساخت که هم مقیاسپذیر باشند و هم پایدار — بدون ترک ابزارهای فعلی.
مقیاسپذیری همیشه در تعویض تکنولوژی نیست. گاهی فقط باید عمیقتر بفهمی و مهندسیتر عمل کنی!