اگر امروز برای مدیریت جریان دادههای سریع از Redis یا Kafka استفاده میکنید، شاید زمان آن رسیده است که دوباره به Postgres نگاه کنید. یک سرور تکگره پستگرس اکنون میتواند ۶۰,۰۰۰ запись در ثانیه (stream writes) را با تأخیری در حد چند میلیثانیه پردازش کند.
طبق گزارش DBOS، این دستاورد با دور زدن قفل اعلانهای داخلی پایگاهداده بهدست آمده است. این یافته، باور رایج در صنعت را که سیستم LISTEN/NOTIFY پستگرس بهطور ذاتی برای جریانهای حجیم مقیاسناپذیر است، به چالش میکشد؛ شهرتی که تا حد زیادی از یک پست وبلاگی محبوب نشأت گرفته بود که ادعا میکرد این قابلیت هرگز مقیاس نمیپذیرد.
برای سالها، خرد جمعی در میان مهندسان بکاند این بود که از LISTEN/NOTIFY برای رویدادهای با فرکانس بالا اجتناب کنند. اکثر توسعهدهندگان از «قفل سراسری» (Global Lock) میترسیدند؛ مکانیزمی که تراکنشها را سریالسازی کرده و توان عملیاتی (Throughput) را بهشدت کاهش میدهد. برای مدیریت دادههای لحظهای، مانند جریان توکنهای مدلهای زبانی بزرگ (LLM)، تیمها اغلب به روش Polling (پرسوجوی مداوم) روی دیتابیس روی میآوردند. همانطور که در تحلیلهای قبلی ما دربارهی زیرساختهای دادهای اشاره کردیم، این روش یا باعث تأخیر شدید میشود (اگر بازه زمانی طولانی باشد) یا CPU را با درخواستهای توخالی و بیهوده اشباع میکند (اگر بازه زمانی خیلی کوتاه باشد).
معماری استریمهای مبتنی بر پستگرس
ساختار پایه این استریمها ساده است: یک جدول اختصاصی برای استریمها ساخته میشود و هر تکه از داده (مثلاً یک توکن مجزا از پاسخ یک مدل LLM) بهعنوان یک ردیف جدید در این جدول ثبت میگردد. عملیات نوشتن در این استریم، شامل درجهای استاندارد (Standard Inserts) در این جدول است.
چالش اصلی در خواندن این تکههاست. چون خوانندهها دقیقاً نمیدانند توکن بعدی چه زمانی میرسد، باید یا بهطور مداوم پرسوجو (Poll) کنند یا منتظر بمانند. قابلیت LISTEN/NOTIFY راهی فراهم میکند تا خوانندهها در حالت مسدود (Block) قرار گیرند و منتظر اعلان نویسنده بمانند. این امر مانع از هدر رفت منابع توسط خوانندهها در اثر Polling مداوم میشود و تضمین میکند که آنها بلافاصله پس از رسیدن یک تکه جدید، بیدار شده و واکنش نشان دهند.
گلوگاه قفل سراسری
به نقل از گزارش DBOS، فروپاشی عملکرد به این دلیل رخ میدهد که پستگرس تضمین میکند اعلانها دقیقاً به همان ترتیبی که تراکنشها تایید (Commit) میشوند، ارسال شوند. برای اجرای این تضمین، سیستم تمام اعلانهای خروجی را در یک صف داخلی سراسری ذخیره میکند. از آنجایی که ترتیب تایید تا زمانی که تراکنش واقعاً در حال تکمیل نباشد تعریف نمیشود، پستگرس از یک قفل انحصاری سراسری (Global Exclusive Lock) برای سریالسازی این فرآیند استفاده میکند.
این قفل در لحظه شروع تایید تراکنش گرفته میشود و تا زمانی که تراکنش بهطور کامل تایید نشود و محتویات آن با دستور fsync() روی دیسک نوشته نشود، آزاد نمیگردد. چون این قفل انحصاری است، پایگاهداده نمیتواند از بهینهسازیهای «تایید گروهی» (Group Commit) برای پردازش چندین تراکنش بهصورت همزمان در یک عملیات fsync واحد استفاده کند.
در پیادهسازی اولیه که توسط DBOS آزمایش شد، یک Trigger (تریگر) روی جدول استریمها فعال بود تا برای هر write (نوشتن) یک اعلان ارسال کند. این معماری منجر به یک گلوگاه شدید شد:
- سقف توان عملیاتی: سیستم نمیتوانست بیش از ۲,۹۰۰ запись در ثانیه را تحمل کند.
- مصرف نامرئی منابع: این گلوگاه بدون اینکه CPU، رم یا IOPS بهطور چشمگیر مصرف شوند، رخ میداد.
- سریالسازی: هر запись استریم مجبور بود قفل سراسری را بگیرد و آن را برای کل مدت زمان تخلیه دادهها روی دیسک نگه دارد.

محدودیتهای وصلههای فعلی
بحثهای آنلاین زیادی درباره یک Patch (وصله) برای پستگرس وجود داشت که قصد داشت این مشکلات را حل کند. این وصله قرار است در نسخه ۱۹ پستگرس منتشر شود. با این حال، طبق تحلیل DBOS، این تغییرات نه قفل سراسری را حذف میکنند و نه گلوگاه توان عملیاتی مشاهده شده توسط DBOS را حل میکنند. در عوض، این وصله تنها یک مورد خاص و محدودتر را بهینه میکند: زمانی که تعداد کانالهای اعلان بسیار زیاد است و هر شنونده (Listener) فقط منتظر یک کانال خاص است.
راهکار بافری کردن (Buffering)
برای شکستن این گلوگاه، DBOS استراتژیای را پیاده کرد که عملیات «نوشتن داده» را از «ارسال اعلان» جدا (Decouple) میکند. بینش کلیدی این است که اعلان صرفاً یک «پینگ» است که به خواننده میگوید جدول را چک کند؛ در حالی که خودِ جدول همچنان تنها منبع حقیقت (Source of Truth) باقی میماند. از آنجایی که اعلانها نیازی به ترتیب جهانی یا ماندگاری (Durability) مطلق ندارند، میتوان آنها را به شکل متفاوتی مدیریت کرد:
- بافری کردن در حافظه: اعلانها بهجای ارسال فوری توسط تریگر برای هر ردیف، در یک بافر حافظه ذخیره میشوند.
- تخلیه دستهای (Batch Flushing): این بافر بهطور دورهای در قالب یک تراکنش دستهای واحد تخلیه میشود.
- کاهش قفل: قفل انحصاری سراسری بهجای آنکه برای هر تکتکِ نوشتنهای استریم گرفته شود، تنها یکبار در زمان تخلیه دستهای فعال میشود.
این روش اجازه میدهد تا نوشتنهای جداگانه استریم بهسرعت پیش بروند و از تمام بهینهسازیهای پستگرس مانند Group Commit برای دستیابی به توان عملیاتی بالا بهره ببرند، در حالی که تخلیه بافر در پسزمینه انجام میشود.

قابلیت اطمینان و نتایج
بافری کردن یک ریسک خاص را ایجاد میکند: اگر پردازشی در حالی که اعلانها هنوز در بافر هستند کرش کند، آن اعلانها هرگز تحویل داده نمیشوند. برای حل این مشکل، DBOS یک مکانیزم Polling با فرکانس پایین بهعنوان پشتیبان (Fallback) اضافه کرد. خوانندهها عمدتاً منتظر اعلانها میمانند، اما بهصورت دورهای دیتابیس را چک میکنند تا ببینند آیا استریمی نوشته شده که اعلان مربوطه به آن ارسال نشده باشد.

در هنگام بنچمارک، این رویکرد بهینه شده یک افزایش خیرهکننده ۲۰ برابری در توان عملیاتی ایجاد کرد. سیستم به ۶۰,۰۰۰ запись در ثانیه رسید، در حالی که تأخیر (Latency) بین ۱۵ تا ۱۰۰ میلیثانیه حفظ شد. نکته حیاتی این است که در این حالت، CPU پستگرس بهطور کامل مورد استفاده قرار گرفت؛ به این معنی که دیتابیس بالاخره بهجای توقف بهدلیل رقابت بر سر قفل (Lock Contention)، توسط کارهای واقعی اشباع شد.

این تحول نشان میدهد که برای اکثر کاربردهای Pub/Sub، اگر از قبل از پستگرس استفاده میکنید، دیگر نیازی به خوشههای مجزای Redis یا Kafka ندارید. با نگاه به اعلانها بهعنوان «راهنما» (Hint) بهجای «لاگهای ماندگار»، میتوانید استک فنی سادهتری داشته باشید بدون اینکه عملکرد را فدا کنید. این رویکرد با دیدگاهی همسو است که پستگرس میتواند جایگزین چندین پایگاهداده تخصصی در پشتههای نرمافزاری شود تا پیچیدگیهای عملیاتی کاهش یابد.
برای توسعهدهندگانی که رابطهای هوش مصنوعی (AI Interfaces) در زمان واقعی میسازند، این به معنای آن است که پستگرس اکنون میتواند جریانهای سریع توکن مورد نیاز برای چتهای تعاملی در مقیاس بالا را مدیریت کند. این امر دیتابیس را از یک لایه ذخیرهسازی غیرفعال به یک موتور استریمینگ فعال با تأخیر کم تبدیل میکند و به ویژه در سناریوهایی که مدلهای زبانی بزرگ نیاز به بهینهسازی هزینه و سرعت استنتاج توکنها دارند، نقش حیاتی ایفا میکند.
اگر یک محیط پستگرس با توان عملیاتی بالا مدیریت میکنید، میتوانید کد کامل بنچمارک را در مخزن گیتهاب DBOS به آدرس github.com/dbos-inc/dbos-postgres-benchmark بیابید تا این محدودیتها را روی سختافزار خود تست کنید.
گام بعدی شما
- اگر از Postgres برای استریم استفاده میکنید، کد بنچمارک را در مخزن گیتهاب DBOS تست کنید.
- استراتژی «اعلان بهعنوان اشاره» (Hint) را بهجای «اعلان بهعنوان لاگ» در معماری خود پیاده کنید.
- بررسی کنید آیا حذف Redis از استک فنی شما، پیچیدگی سیستم را بدون افت عملکرد کاهش میدهد؟
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو