در معماریهای مدرن مبتنی بر رویداد، یکپارچگی و ردیابی دادهها حیاتی هستند. پایگاههای داده رابطهای سنتی اغلب در برابر حجم بالای نوشتن و انعطافپذیری طرحواره مورد نیاز برای منبعسازی رویدادها با مشکل مواجه میشوند. خوشبختانه، PostgreSQL ترکیبی قدرتمند از ویژگیها را ارائه میدهد—بهطور خاص نوع داده JSONB و رمزگشایی منطقی (Logical Decoding)—که به مهندسان اجازه میدهد ردپاهای حسابرسی تغییرناپذیر و فقط-افزودنی با عملکرد و انعطافپذیری استثنایی بسازند.
این پست بررسی میکند که چگونه میتوان از این ابزارها برای ایجاد یک سیستم حسابرسی مقاوم استفاده کرد که هر تغییر وضعیت را بدون قفل کردن پایگاه داده یا قربانی کردن عملکرد ثبت میکند.
مشکل اصلی: حسابرسی در منبعسازی رویداد
منبعسازی رویداد حکم میکند که وضعیت یک برنامه از دنبالهای از رویدادها مشتق میشود. برای رعایت الزامات انطباق و عیبیابی، باید اطمینان حاصل کنیم که این رویدادها تغییرناپذیر هستند. یک بار که رویدادی نوشته شد، نمیتوان آن را تغییر یا حذف کرد. این الگوی «فقط-افزودنی» برای ستونهای JSONB ایدهآل است که میتوانند دادههای پیچیده و بدون ساختار را بهطور کارآمد درون یک چارچوب رابطهای ذخیره کنند.
با این حال، صرفاً ذخیره JSON در یک جدول کافی نیست. ما به مکانیزمی نیاز داریم که این نوشتنها را بهطور قابل اعتماد ثبت کند، احتمالاً برای مصرفکنندگان پاییندستی مانند انبارهای داده یا داشبوردهای بلادرنگ، بدون تأثیر بر تأخیر تراکنش اصلی.
طرحبندی برای رویدادهای تغییرناپذیر
اول، بیایید طرحی را تعریف کنیم که تغییرناپذیری را اعمال کند. ما از یک محدودیت یکتا روی شناسه رویداد و زمانبرچسب برای جلوگیری از تکرار استفاده میکنیم و تریگرهای بهروزرسانی را حذف میکنیم تا اطمینان حاصل کنیم که رکورد واقعاً فقط-افزودنی است.
CREATE TABLE event_store (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
aggregate_id UUID NOT NULL,
event_type VARCHAR(50) NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- اختیاری: شاخص برای پرسوجو بر اساس تاریخچه مجموعه
CREATE INDEX idx_event_store_aggregate
ON event_store (aggregate_id, created_at);
با تبدیل payload به نوع JSONB، ما توانایی پرسوجوی فیلدهای خاص درون رویداد را بدون بازسازی کامل بایتاستریم کسب میکنیم که برای عیبیابی یا فیلتر کردن لاگهای حسابرسی حیاتی است.
استفاده از بازنویسی منطقی برای جداسازی
در حالی که ذخیره رویدادها گام اول است، اشتراکگذاری این داده با سیستمهای دیگر جایی است که بازنویسی منطقی درخشش میکند. برخلاف بازنویسی فیزیکی که کل پایگاه داده را کپی میکند، بازنویسی منطقی به شما اجازه میدهد به جداول خاصی مشترکالمنفع شوید و تغییرات را در قالبی خوانا (اغلب JSON یا پروتکل بافرها) جریان دهید.
برای فعالسازی این ویژگی، باید postgresql.conf خود را پیکربندی کنید:
wal_level = logical
max_replication_slots = 10
max_wal_senders = 10
پس از فعالسازی، میتوانید یک انتشار ایجاد کنید که رویدادها را به مصرفکنندگان پاییندستی جریان دهد:
PUBLICATION event_pub FOR TABLE event_store;
مزایای این رویکرد
- عملکرد: مصرفکنندگان پاییندستی بهطور ناهمگام از WAL (لاگ پیشنوشت) میخوانند. این بار اضافی کمی به مسیر نوشتن اصلی اضافه میکند.
- تحمل خطا: اگر مصرفکننده از کار بیفتد، میتواند WAL را از آخرین موقعیت مصرفشده بازیابی کند، که اطمینان حاصل میکند هیچ رویدادی از دست نمیرود.
- جداسازی: شما میتوانید چندین مصرفکننده (مثلاً نمایهساز Elasticsearch، تولیدکننده Kafka، بارگذار انبار داده) داشته باشید بدون اینکه بر یکدیگر تأثیر بگذارند.
پیادهسازی عملی: خواندن WAL
توسعهدهندگان میتوانند از کتابخانههایی مانند pgoutput در جاوا/گو یا psycopg2 با پلاگینهای رمزگشایی منطقی در پایتون برای مصرف این جریانها استفاده کنند. دادهها در قالبی میرسند که مستقیماً با طرح شما مطابقت دارد، که بازسازی آن را ساده میکند.
برای مثال، یک مصرفکننده ممکن است پیامی مانند این دریافت کند:
{
"operation": "INSERT",
"table": "event_store",
"tuple": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"aggregate_id": "b2c1e9f0-...",
"event_type": "OrderPlaced",
"payload": {"item": "Widget", "qty": 1},
"created_at": "2023-10-27T10:00:00Z"
}
}
نتیجهگیری
ترکیب انعطافپذیری JSONB PostgreSQL با بازنویسی منطقی، پایهای آزمونپسداده برای ردپاهای حسابرسی تغییرناپذیر در سیستمهای منبعسازی رویداد فراهم میکند. این به شما اجازه میدهد یکسازگی قوی را در دادههای اصلی خود حفظ کنید و همزمان تغییرات را به راحتی به سیستمهای ثانویه جریان دهید. این معماری مقیاسپذیر، مقاوم است و از اکوسیستم بالغ PostgreSQL برای مدیریت پیچیدگیهای مهندسی داده مدرن بهره میبرد.
با پیادهسازی طرح شروع کنید، سپس یک اسلات بازنویسی منطقی را برای تغذیه اولین مصرفکننده خود ادغام کنید. نتیجه سیستمی است که هم از نظر نگهداری آسان و هم از نظر مقاومت برای مدیریت الزامات حسابرسی در مقیاس تولید، قوی است.