مهندسی داده
810 subscribers
112 photos
7 videos
24 files
320 links
BigData.ir کانال رسمی وب سایت
مطالبی راجع به مهندسی داده و طراحی زیرساخت‌های پردازش دیتا و ابزارهای مدرن دیتا
ارتباط با ادمین: @smbanaei
گروه تخصصی مهندسی داده 👇
https://t.iss.one/bigdata_ir_discussions2
کانال یوتیوب 👇
https://www.youtube.com/@irbigdata
Download Telegram
نگاهی به OpenFGA؛ سیستم مجوزدهی گراف‌محور الهام‌گرفته از Google Zanzibar

در یکی از پروژه‌های اخیر مشاوره، در حال راه‌اندازی و تست زیرساخت یک Lakehouse با استفاده از LakeKeeper بودم — یک کاتالوگ سرور سبک برای Iceberg.

برای احراز هویت و کنترل دسترسی، این سیستم از ترکیب Keycloak و OpenFGA استفاده می‌کند.

کتابخانه #Keycloak را قبلاً می‌شناختم، اما #OpenFGA برایم جدید بود و کنجکاوم کرد. این پست خلاصه‌ای از بررسی اولیه‌ام درباره‌ی این ابزار مدرن مجوزدهی است.

🧠 نقطه‌ی آغاز: Google Zanzibar


در سال ۲۰۱۹، گوگل مقاله‌ای منتشر کرد با عنوان:

“Zanzibar: Google’s Consistent, Global Authorization System”

این مقاله مدل جدیدی برای مدیریت مجوزهای دسترسی در سیستم‌های بزرگ معرفی کرد؛ مدلی که بر پایه‌ی روابط گرافی میان کاربران، گروه‌ها و منابع طراحی شده بود. این مدل، به نام #ReBAC (Relationship-Based Access Control) شناخته می‌شود.

کتابخانه OpenFGA یکی از معروف‌ترین پیاده‌سازی‌های متن‌باز بر اساس این مدل است.


🔄 مدل ReBAC در برابر RBAC و ABAC

در سیستم‌های سنتی، ما با دو مدل رایج کار می‌کردیم:

مدل #RBAC می‌پرسد: «چه کسی هستید؟» (مثلاً: مدیر / کاربر)

مدل #ABAC می‌پرسد: «چه ویژگی‌هایی - Attribute -دارید؟» (مثلاً: دپارتمان = منابع انسانی)

اما در دنیای واقعی، سناریوهای پیچیده‌تری وجود دارد:

«کاربری می‌تواند گزارش پروژه را ببیند، اگر عضو تیم فنی باشد، پروژه به او تخصیص داده شده باشد، و حساب او تعلیق نشده باشد.»


در این‌جا مدل ReBAC وارد می‌شود:

"چه رابطه‌ای با منبع دارید؟"



🔄کتابخانه OpenFGA چیست؟

پروژه OpenFGA یکی از پیاده‌سازی‌های متن‌باز، سریع و قابل‌اتکای مدل #ReBAC است که با زبان #Go توسعه یافته است.

این ابزار که توسط تیم Auth0 و Okta توسعه یافته، به شما امکان می‌دهد:

- دسترسی‌ها را در قالب گرافی از روابط بین کاربران، گروه‌ها و منابع مدل کنید

- منطق مجوزدهی را از کد جدا نگه دارید و از طریق API فراخوانی کنید

- با ابزارهای احراز هویت مانند Keycloak یا OIDC ادغام کنید

- شرط‌های پیچیده را اعمال کنید (مثلاً: دسترسی فقط اگر حساب کاربر فعال باشد)

چه پروژه‌ها و شرکت‌هایی از این مدل استفاده می‌کنند؟

- نتفلیکس از پروژه‌ی مشابهی به نام SpiceDB (محصول AuthZed) استفاده کرده و آن را توسعه داده تا ویژگی‌های ABAC را نیز پشتیبانی کند.

- شرکت Airbnb سیستم داخلی خود به نام Himeji را بر پایه همین ایده ساخته است.

- پروژه OpenObserve یک کتابخانه مدیریت observability است که OpenFGA را مستقیماً به‌کار گرفته.

- پروژه Backstage (Spotify) امکان اتصال به OpenFGA از طریق پلاگین‌های متن‌باز را دارد.

- و ...


🔄 آیا فقط OpenFGA؟ نه الزاماً!

مقاله Google Zanzibar الهام‌بخش چندین پروژه متن‌باز دیگر نیز شده است که می‌توانید به‌جای OpenFGA از آن‌ها استفاده کنید.

مثلاً: Permify یک سیستم متن‌باز برای مجوزدهی ریزدانه (Fine-Grained Authorization) که کاملاً از مدل #Zanzibar پیروی می‌کند.

همچنین می‌توان به Ory Keto و SpiceDB نیز اشاره کرد که در زمینه مشابه فعال‌اند.

📌 جمع‌بندی

اگر در حال طراحی یک زیرساخت داده‌محور، داشبورد چندمستأجری، پلتفرم SaaS یا سامانه‌ی مشارکتی هستید، و مدل #RBAC دیگر جواب نیازهایتان را نمی‌دهد، حتماً نگاهی به #OpenFGA و سایر پروژه‌های مبتنی بر #ReBAC داشته باشید: به عنوان یک روش قابل اطمینان برای مدیریت دسترسی در مقیاس بالا و مناسب کاربردهای پیچیده مجوزدهی.
👍3
کدام زبان: Rust یا Go؟ نگاهی دوباره از دل تجربه‌ی واقعی

چند وقت پیش مطلبی نوشتم با عنوان «آینده‌ی Rust در مهندسی داده» و یک مطلب دیگر در خصوص مهاجرت بخشی از کدهای #GO در دیسکورد به Rust. هنوز هم به آن حرف‌ها باور دارم:

بخش زیادی از ابزارهای آینده‌ی این حوزه یا با #Rust بازنویسی می‌شوند یا به شکل native با آن توسعه می‌یابند — دلیلش هم مشخص است: سرعت بالا، کنترل دقیق حافظه، و ویژگی‌هایی مثل «zero-cost abstractions»


اما بعد از چند ماه کار عملی با هر دو زبان، دیدگاهم واقع‌گرایانه‌تر شده است. Rust قدرت بالایی دارد، اما پیچیدگی توسعه و زمان بالای یادگیری، آن را برای همه‌ی پروژه‌ها مناسب نمی‌کند. Go در مقابل ساده، سریع، و برای توسعه‌ی روزمره بسیار کارآمد است.

🎯 یکی از تجربه‌های مهم برایم، پروژه‌ای بود که در آن یک تیم، یک سرویس واقعی را با سه زبان Rust، Go و Node.js پیاده‌سازی و در شرایط واقعی با ترافیک زنده تست کرد. تجربه‌ای که در زیر نتایج آنرا با هم مرور می‌کنیم. (لینک: https://freedium.cfd/https://medium.com/@kanishks772/we-didnt-benchmark-it-we-went-to-war-with-it-go-vs-rust-vs-node-at-1m-users-60565cd59b1f)

📌سرویسی که ساختند، شامل احراز هویت، پیام‌رسانی بلادرنگ، و آپلود فایل بود — چیزی شبیه به ستون فقرات یک اپلیکیشن پیام‌رسان. پیاده‌سازی اولیه با Node.js بود، اما دیگر جواب نمی‌داد: نشت حافظه، جهش‌های CPU، و زمان پاسخ‌هایی که باعث rage-quit کاربران می‌شد.

📚به‌جای فرضیه‌سازی، تیم دست‌به‌کار شد: همان سرویس را با Go و Rust هم نوشت و ترافیک را به‌طور مساوی بین هر سه تقسیم کرد. نتیجه چه شد؟

«Rust عملاً از نظر عملکرد، رقبا را پشت سر گذاشت.» اما آنچه این تیم یاد گرفت، چیزی بود که اغلب در بنچمارک‌ها دیده نمی‌شود:

عملکرد بالا، بدون بهره‌وری، کافی نیست.

⚠️توسعه با Rust 40٪ زمان بیشتری می‌برد. اشکال‌زدایی درگیر borrow checker می‌شد و اضافه‌کردن یک فیچر ساده، به جنگ با سیستم Typing منتهی می‌گردید.

در مقابل، Go سرعت توسعه‌ی بالایی داشت، کتابخانه استاندارد کافی و کاربردی، و راه‌اندازی ساده. هرچند کمی از Rust کندتر بود، اما برای تیم، توسعه با Go سه برابر سریع‌تر از Rust و دو برابر سریع‌تر از Node بود.


در نهایت، این تیم از هر سه زبان استفاده کرد:

🔹 Node.js برای ابزارهای مدیریتی و پروتوتایپ‌های سریع

🔹 #Go برای سرویس‌های اصلی و عمومی

🔹 #Rust برای بخش‌هایی که واقعاً performance-critical بودند


درس‌هایی از میدان نبرد

واقعیت از بنچمارک قوی‌تر است. کدی که در تولید اجرا شود، تفاوت‌ها را نشان می‌دهد، نه کدهایی که فقط در محیط‌های تست اجرا شده‌اند.

تجربه‌ی تیم از زبان مهم‌تر است. زبانی که تیم در آن مهارت دارد، اغلب از زبان بهتری که تیم با آن غریبه است، نتیجه‌ی بهتری می‌دهد.

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

چندزبانی بودن (polyglot) مزیت است، نه نقطه‌ضعف. گاهی بهترین راه این است که یک زبان را همه‌جا استفاده نکنیم. هر ابزار برای کاری ساخته شده.


💡 نتیجه‌گیری شخصی من


زبان Rust هنوز آینده‌ی ابزارهای مهندسی داده است — مخصوصاً در سطح زیرساخت. اما در بسیاری از پروژه‌های کاربردی، از سرویس‌های داخلی گرفته تا microserviceهای API، Go انتخابی‌ست منطقی‌تر و واقع‌گرایانه‌تر.

ما همه مثل Discord نیستیم. منابع، مقیاس و اولویت‌های تیم‌ها متفاوت‌اند.

اما مهم‌تر از انتخاب بین Rust یا Go، این است که انتخاب‌مان با چشمان باز باشد — از دل تجربه، نه فقط از روی بنچمارک‌ها یا توییت‌های ترند شده.
👍6
چرا بسیاری از تیم‌ها ORM را کنار می‌گذارند و سراغ SQL خام می‌روند؟

اخیرا در مدیوم با تعداد زیادی از مقاله‌ها مواجه می‌شوم که یک پیام مشترک دارند:

🔁 «ما #ORM را کنار گذاشتیم و به #SQL خام مهاجرت کردیم — و دیگر برنمی‌گردیم.»


نکته جالب اینجاست که این تصمیم‌ها معمولاً از سر عشق به SQL گرفته نشده‌اند، بلکه از دل دردسرهای #ORM زاده شده‌اند.

در چند مقاله‌ی اخیر که مطالعه کردم، تیم‌های مختلفی با تکنولوژی‌های مختلف (از #Java + #Postgres گرفته تا #Go + #SQLAlchemy) تجربه‌ی مهاجرت از ORM را به اشتراک گذاشته‌اند — نه فقط برای بهبود سرعت، بلکه برای بازگشت به شفافیت، کنترل و عقلانیت.


⚠️مشکل کجا بود؟ چرا ORM جوابگو نبود؟

اگرچه ORM در شروع پروژه‌ها خیلی مفید است (خصوصاً برای CRUDهای سریع و MVPها)، اما با رشد سیستم، مشکلاتی کم‌کم خود را نشان می‌دهند:

🧨معضل N+1 Query

کوئری‌هایی که ساده به نظر می‌رسند، در باطن ده‌ها یا صدها درخواست اضافه تولید می‌کنند.

🌀 کدهای پیچیده اما غیرشفاف

برای کوئری‌های پیچیده‌تر مثل Window Function، CTE یا Join چندجدولی، باید به انواع annotationها، chainهای مبهم، یا زبان‌های خاص ORM (مثل JPQL) متوسل شد — که در نهایت باز هم می‌رسیم به نوشتن SQL، فقط با دردسر بیشتر.

🔍 ضعف در دیباگ و پروفایلینگ

در ORM، به‌سختی می‌شود فهمید دقیقاً چه کوئری‌ای به دیتابیس رفته. این یعنی دیباگِ کندی‌ها تقریباً کورکورانه است.

💡 ناسازگاری با مدل واقعی داده‌ها

دیتابیس با row و index و join کار می‌کند؛ ORM با کلاس و رابطه شی‌گرایانه. این تطبیق، به‌ویژه در سیستم‌های پیچیده، منجر به کدهایی می‌شود که بیشتر شبیه «جنگیدن با ORM» هستند.


🎯چرا SQL خام یک تفاوت واقعی ایجاد کرد؟

بعد از مهاجرت، همه تیم‌ها روی این دستاوردها تأکید داشتند:

کنترل کامل

می‌دانیم چه کوئری نوشته‌ایم، چه زمانی اجرا می‌شود، و چگونه می‌توان آن را بهینه کرد.

شفافیت

کوئری واضح است، بدون «جادوی مخفی». این یعنی همه تیم — از جونیور تا لید — متوجه می‌شود چه اتفاقی می‌افتد.

هماهنگی بیشتر با منطق دامنه

به‌جای تعریف business logic در repository و annotation، همه‌چیز در لایه‌های مشخص خدماتی و use-case محور قرار می‌گیرد.

استفاده کامل از قدرت دیتابیس

ویژگی‌هایی مثل Window Function، CTE، JSONB و Partial Index که در ORM اغلب یا پشتیبانی نمی‌شوند یا با پیچیدگی زیاد ممکن‌اند، در SQL خام به‌راحتی قابل استفاده‌اند.

📌نگهداری و مقیاس‌پذیری چطور مدیریت شد؟

برای جلوگیری از بی‌نظمی، تیم‌ها:

- کوئری‌ها را در فایل‌های جدا و نسخه‌دار نگه داشتند

- از template و query loaderهای سبک استفاده کردند

- روی هر کوئری تست (یا حداقل EXPLAIN) نوشتند

- قواعد ساده ولی سخت‌گیرانه‌ای برای امنیت (مثل پارامترگذاری) اعمال کردند

در نتیجه، برخلاف تصور اولیه، نگهداشت SQL خام هم قابل مدیریت و حتی لذت‌بخش شد.

💡کی باید ORM را کنار گذاشت؟

تجربه‌ی مشترک تیم‌ها نشان می‌دهد:

برای پروژه‌های کوچک، MVPها یا پنل‌های ادمین، ORM عالی است.

اما در پروژه‌های داده‌محور، با ترافیک بالا، کوئری‌های پیچیده و نیاز به کنترل عملکرد، ORM به‌جای کمک، تبدیل به مانع می‌شود.


📚 جمع‌بندی

بسیاری از ما با ORMها بزرگ شده‌ایم اما آیا هنوز ORM بهترین ابزار ماست؟ یا فقط آسان‌ترین است؟

در دنیایی که عملکرد، شفافیت و کنترل ارزش بیشتری از سرعت اولیه دارند، شاید وقت آن است که دوباره به SQL خام یا ترکیب آن با ORm فکر کنیم — این بار با بلوغ بیشتر و ابزارهای بهتر.
👍51
آیا ردیس همچنان پادشاه حافظه‌هاست ؟ 👑

در دنیای فناوری، حتی محبوب‌ترین ابزارها هم برای ادامه مسیر به رقیب نیاز دارند. همان‌طور که در حوزه پردازش جریان، ظهور #Redpanda و #AutoMQ باعث شد سطح انتظارات از شرکت Confluent و حتی بنیاد آپاچی برای گسترش امکانات #Kafka بالا برود، حالا نوبت #Redis است که با چالش‌های تازه روبه‌رو شود.

ردیس سال‌هاست به‌عنوان یک پایگاه داده درون‌حافظه‌ای (In-Memory) سریع ⚡️، ساده و بی‌دردسر شناخته می‌شود. بسیاری از ما اولین تجربه کار با Cache، Session Storage یا حتی Pub/Sub را با همین ابزار داشته‌ایم. اما همین موفقیت و سادگی باعث شد که کمتر به سراغ گزینه‌های دیگر برویم… تا وقتی که یک مشکل واقعی سر راه‌مان سبز شود.

مشکل اول: استفاده ناکامل از CPU 🖥

ردیس ذاتاً تک‌ریسمانی است؛ یعنی هر چقدر هم CPU چند هسته‌ای داشته باشیم، در نهایت یک هسته درگیر پردازش می‌شود و بقیه بلااستفاده می‌مانند. وقتی حجم درخواست‌ها بالا برود، صف‌ها طولانی و تأخیرها بیشتر می‌شوند.

اینجاست که #KeyDB وارد میدان شد 💪. این ابزار در واقع نسخه‌ای از Redis است که یاد گرفته از چند هسته CPU هم‌زمان استفاده کند. بدون تغییر در کد یا کتابخانه‌ها، می‌توانید با #KeyDB سرعتی چند برابر تجربه کنید.

مشکل دوم: هزینه بالای RAM 💸

هر کس #Redis را در مقیاس بزرگ استفاده کرده باشد، با مشکل مصرف زیاد حافظه آشناست. بخش زیادی از این مصرف به خاطر تکه‌تکه شدن و هدر رفتن فضای RAM است.

دیتابیس #Dragonfly دقیقاً برای حل همین مشکل ساخته شده 🐉. با معماری متفاوت و بسته‌بندی بهینه داده‌ها، می‌تواند تا یک‌سوم مصرف حافظه را کاهش دهد و همچنان سرعت بالایی ارائه کند. برای پروژه‌هایی با داده‌های کوچک اما بسیار زیاد – مثل ذخیره‌سازی میلیون‌ها سشن کاربر – #Dragonfly یک صرفه‌جویی واقعی در هزینه‌هاست.

مشکل سوم: تغییر لایسنس Redis 📜

تغییر لایسنس #Redis باعث شد بخشی از جامعه متن‌باز احساس کند آینده این پروژه دیگر کاملاً شفاف نیست. نتیجه این نگرانی، تولد #Valkey بود؛ یک فورک متن‌باز که با همان API و پروتکل Redis کار می‌کند اما بدون محدودیت‌های جدید لایسنس.

#Valkey از نظر فنی تفاوت بزرگی با Redis ندارد، اما برای کسانی که به دلایل حقوقی یا سیاست‌های سازمانی نمی‌توانند Redis را استفاده کنند، یک انتخاب امن و بی‌دردسر است.

مشکل چهارم: نیاز به توزیع‌شدگی واقعی 🌍

اگرچه Redis Cluster امکان مقیاس‌پذیری افقی را فراهم می‌کند، اما راه‌اندازی و نگهداری آن همیشه ساده نیست. #Hazelcast از روز اول برای توزیع‌شدگی طراحی شده و مدیریت داده بین چندین نود را به‌صورت خودکار انجام می‌دهد. این ویژگی آن را برای سیستم‌های بزرگ با نیاز واقعی به Cache توزیع‌شده جذاب می‌کند.(البته با پرداخت هزینه)


کدام را انتخاب کنیم؟ 🎯

اگر مشکل کارایی ندارید → #Redis بهترین انتخاب است.

📌اگر گلوگاه CPU دارید و می‌خواهید با کمترین تغییر سرعت بگیرید → #KeyDB را انتخاب کنید.

📌اگر هزینه RAM سنگین شده → #Dragonfly می‌تواند نجات‌بخش باشد.

📌اگر لایسنس برایتان مسئله است → #Valkey جایگزین امنی است.

📌اگر از ابتدا به یک Cache توزیع‌شده و سازمانی نیاز دارید → #Hazelcast را در نظر بگیرید.


در کنار همه این گزینه‌ها، #Kvrocks هم حرف‌های زیادی برای گفتن دارد. این دیتابیس که با #C++ و #Go ساخته شده، از RocksDB به‌عنوان موتور ذخیره‌سازی استفاده می‌کند؛ یعنی به جای اینکه همه چیز را فقط در حافظه RAM نگه دارد مثل #Redis، می‌تواند داده‌های بزرگ را روی دیسک ذخیره و مدیریت کند 📀. این کار باعث می‌شود ظرفیت خیلی بیشتری با هزینه کمتر داشته باشید، بدون اینکه از مزیت سرعت زیاد و سازگاری کامل با پروتکل Redis دست بکشید. 🚀
رقابت تازه شروع شده است 🚀. #Redis هنوز پادشاه دنیای پایگاه داده‌های درون‌حافظه‌ای است، اما حالا باید برای حفظ جایگاهش بیشتر تلاش کند. برای ما مهندسان نرم‌افزار، این یعنی گزینه‌های بیشتر، آزادی انتخاب بالاتر و آینده‌ای پر از نوآوری.
👍6