پرش به محتوای اصلی
پرش به محتوای مقاله

بنچمارک‌های جدید: پردازش ۱ میلیارد ردیف داده در چند ثانیه با DuckDB

·۲۱ شهریور ۱۴۰۵۱۳ دقیقه مطالعه
تحلیل
پانداها باید منقرض شوند: نماد نجات‌یافته‌ای که ارزش حفاظت ندارد
پانداها باید منقرض شوند: نماد نجات‌یافته‌ای که ارزش حفاظت ندارد
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

معرفی مفهوم «داده‌های میان‌مقیاس» و اثبات این موضوع که بیش از ۹۰٪ بارهای کاری تحلیلی سازمان‌ها با ابزارهای تک‌ماشینه مدرن (به‌جای سیستم‌های توزیع‌شده) قابل مدیریت هستند.

پردازش یک میلیارد ردیف داده در ۵ ثانیه روی یک ماشین معمولی اکنون ممکن است و نیاز به مهاجرت به خوشه‌های توزیع‌شده و هزینه‌بر را برای اکثر کاربران به چالش می‌کشد. پالارز (Polars) و داک‌دی‌بی (DuckDB) به جایگزین‌های اصلی کتابخانه قدیمی پانداز (Pandas) تبدیل شده‌اند؛ به‌ویژه برای حجم داده‌هایی که اکنون «داده‌های میان‌مقیاس» (Medium Data) نامیده می‌شوند.

برای سال‌ها، توسعه‌دهندگان پایتون مسیری پیش‌بینی‌پذیر داشتند: شروع با اکسل، انتقال به پانداز برای داده‌های در مقیاس گیگابایت و سپس برخورد با «دیواره عملکرد» (Performance Cliff). پانداز تا محدوده ۱۰ گیگابایت خوب عمل می‌کند، اما پس از آن کاربر با مشکل حافظه، محاسبات کند یا رابط کاربری پیچیده و قدیمی (Baroque API) مواجه می‌شود. در این نقطه، تنها راه حل شناخته‌شده، مهاجرت به ابزارهای «داده‌های بزرگ» (Big Data) مانند آپاچی اسپارک (Apache Spark)، دیتابریکس (Databricks)، اسنو‌فلیک (Snowflake) یا داسک (Dask) بود. این انتقال اغلب پیچیدگی معماری و هزینه‌های هنگفتی ایجاد می‌کند، پیش از آنکه حجم کاری واقعاً چنین هزینه‌ای را توجیه کند.

بر اساس تحلیل وب‌سایت eddie.codes، شکاف بزرگی بین «دیواره پانداز» و نیاز واقعی به سیستم‌های توزیع‌شده وجود دارد. این شکاف دقیقاً در محدوده ۱۰۰ گیگابایت رخ می‌دهد. اکثر کاربران با «داده‌های بزرگ» سر و کار ندارند، بلکه با «داده‌های میان‌مقیاس» مواجه‌اند که به‌طور بهینه روی یک ماشین قدرتمند تک‌گره (Single Machine) قابل مدیریت است.

واقعیت داده‌های بزرگ

برای اثبات این ادعا، نویسنده به مقاله‌ای از سال ۲۰۲۴ توسط آمازون با عنوان «چرا TPC کافی نیست: تحلیلی از ناوگان Amazon Redshift» اشاره می‌کند. هدف این مطالعه مقایسه داده‌های تله‌متری پایگاه‌داده توزیع‌شده Redshift (که متعلق به خود آمازون است) با بنچمارک‌های استاندارد صنعت دیتابیس بود. با تحلیل آمارهای ناوگان در مورد زمان اجرای پرس‌وجوها و اندازه جداول، این مطالعه الگوهای شگفت‌انگیزی در نحوه مدیریت داده‌ها توسط کاربران واقعی صنعت مشاهده کرد:

  • ۹۴.۶۸٪ از جداول در ناوگان Redshift کمتر از ۱۰۰ گیگابایت داده دارند.
  • ۸۶.۹٪ از پرس‌وجوها روی داده‌هایی با حجم ۸۰ گیگابایت یا کمتر اجرا می‌شوند.

پاندای غول‌پیکر در حال خوردن بامبو در جنگل بامبو

پاندا باید منقرض شود: چرا حفاظت از گونه‌های نمادین منابع را هدر می‌دهد

این نتایج بر اساس محاسبات دقیقی است. برای رسیدن به عدد ۱۰۰ گیگابایت، نویسنده ردیف‌ها را تا حد ۱۰ به توان ۸ جمع کرده (که ۹۴.۶۸٪ ردیف‌ها را شامل می‌شود) و میانگین اندازه هر ردیف را ۱ کیلوبایت فرض کرده است. حتی اگر این فرض بیش از حد خوش‌بینانه باشد و اندازه ردیف‌ها ۱۰ کیلوبایت باشد، اندازه جدول همچنان ۱ ترابایت خواهد بود که برای یک ماشین مدرن قابل مدیریت است. برای محاسبه حد ۸۰ گیگابایتی پرس‌وجوها، نویسنده اشاره کرد که ۸۶.۹٪ از پرس‌وجوها در کمتر از یک ثانیه اجرا می‌شوند. با فرض یک خوشه Redshift شامل ۱۰ ماشین که داده‌ها را با سرعت ۸ گیگابایت بر ثانیه از S3 می‌مکد، محاسبه به این صورت است: ۱۰ ماشین * ۸ گیگابایت * ۱ ثانیه = ۸۰ گیگابایت. البته نویسنده اذعان می‌کند که فرض ۸ گیگابایت بر ثانیه بر اساس یک بنچمارک قدیمی است.

جردن تیگانی از MotherDuck نیز بررسی‌های عمیقی روی این مجموعه داده انجام داده است، هرچند نویسنده اشاره می‌کند که مقداری تردید لازم است، زیرا MotherDuck یک کسب‌وکار SaaS است که خدمات میزبانی DuckDB را می‌فروشد.

این اعداد نشان می‌دهند که اکثریت قریب به اتفاق بارهای کاری تحلیلی در سازمان‌ها، نیازی به خوشه توزیع‌شده ندارند و صرفاً به موتور پردازشی کارآمدتری نسبت به پانداز نیاز دارند.

رویارویی در میدان عملکرد

برای تست این موضوع، یک «چالش یک میلیارد ردیفی» برای محاسبه مقدار مینیمم، میانگین و ماکسیمم یک فایل CSV حاوی داده‌های ایستگاه‌های هواشناسی اجرا شد. سریع‌ترین پیاده‌سازی پذیرفته شده با زبان جاوا برای این چالش، ۱.۵ ثانیه روی یک سرور Bare Metal مدل Hetzner AX161 (با ۳۲ هسته، ۱۲۸ گیگابایت رم و سیستم‌عامل Debian 12) زمان برد.

در تست‌های انجام شده روی یک نمونه AWS m7a.8xlarge با سیستم‌عامل Debian 12 (که از نظر تعداد هسته و رم با چالش اصلی مطابقت دارد، هرچند نبود سخت‌افزار Bare Metal ممکن است بر تکرارپذیری اثر بگذارد)، تفاوت کارایی تکان‌دهنده بود:

  • پانداز: ۴ دقیقه و ۲۸ ثانیه زمان برد و اوج مصرف حافظه آن به ۳۸.۱۲ گیگابایت رسید.
  • پالارز: کار را در ۵.۰۴ ثانیه و با مصرف ۱۸.۰۲ گیگابایت حافظه به پایان رساند.
  • داک‌دی‌بی: در ۵.۱۹ ثانیه عملیات را تمام کرد و تنها از ۱.۹۳ گیگابایت حافظه استفاده کرد.

پانداها باید منقرض شوند: حیواناتی با هزینه نگهداری بالا و توانایی تولیدمثل پایین

عملکرد با ابزاری اندازه‌گیری شد که هر ۵۰ میلی‌ثانیه معیارهای CPU و حافظه را از طریق psutil پایش می‌کرد و مفسرهای پایتون جدیدی را ایجاد می‌کرد. هر کتابخانه ابتدا دو بار برای گرم شدن (warmup) اجرا و سپس ۳۰ بار تکرار شد. برای این تست‌ها، مرحله سریال‌سازی خروجی (که در چالش اصلی بود) حذف شد تا تمرکز روی محاسبات باشد، هرچند تمام پیاده‌سازی‌ها از نظر قابلیت سریال‌سازی تست شدند.

وقتی همین تست روی یک لپ‌تاپ با مشخصات پایین‌تر (Framework 13، پردازنده Intel i5-1135G7، ۸ هسته و ۱۶ گیگابایت رم) اجرا شد، شکاف عمیق‌تر شد. پانداز به شدت کند شد و بیش از ۱۲ دقیقه زمان برد و به شدت به Swap دیسک (۲۱.۰۲ گیگابایت) متکی شد. در مقابل، پالارز و داک‌دی‌بی زیر ۵۰ ثانیه کار را تمام کردند و داک‌دی‌بی با مصرف خیره‌کننده ۵۴۶ مگابایت حافظه، بسیار سبک باقی ماند.

تفاوت‌های تکنولوژیک

پانداز به‌صورت مشتاق (Eager) و ترتیبی عمل می‌کند. در چالش یک میلیارد ردیفی، پانداز ابتدا کل مجموعه داده را می‌خواند، آن را گروه‌بندی می‌کند و سپس تجمیع را انجام می‌دهد. این یعنی کل داده‌ها قبل از هر عملیاتی در حافظه بارگذاری می‌شوند و دلیل کرش کردن پانداز در داده‌های حجیم همین است.

پالارز که با زبان Rust نوشته شده، از مدل ارزیابی تنبل (Lazy Evaluation) استفاده می‌کند. پالارز به‌جای اجرای فوری دستورات، با scan_csv داده‌ها را تکه‌تکه می‌خواند و یک گراف بهینه از پرس‌وجو می‌سازد. فراخوانی متد .collect(new_streaming=True) است که خط لوله را اجرا می‌کند. این رویکرد اجازه می‌دهد پالارز:

  • بهینه‌سازی‌های پایگاه‌داده را به کار بگیرد: از ۴۰ سال تحقیق در حوزه دیتابیس برای موازی‌سازی کارها روی رشته‌های مختلف (Threads) استفاده می‌کند.
  • فیلترهای پیش‌رونده (Predicate Pushdown) را اعمال کند: ردیف‌ها را قبل از اینکه تجمیع رخ دهد فیلتر می‌کند، برخلاف پانداز که ابتدا همه ردیف‌ها را بارگذاری می‌کند.
  • نقشه‌های اجرا را بصری کند: کاربران می‌توانند با فراخوانی .explain(streaming=True) یا .explain(streaming=True, optimized=False) نقشه‌های بهینه و غیربهینه پرس‌وجو را مشاهده کنند.

داک‌دی‌بی در واقع یک پایگاه‌داده تحلیلی درون‌حافظه‌ای است؛ چیزی شبیه به «SQLite برای تحلیل داده‌ها». این ابزار یک رابط SQL بومی فراهم می‌کند که می‌تواند مستقیماً روی اشیاء پایتون یا فایل‌های Parquet پرس‌وجو کند. برای مثال، می‌تواند جدولی از یک شیء پایتونی df بسازد و یک دستور استاندارد SQL شامل SELECT با توابع GROUP BY و AVG اجرا کند. داک‌دی‌بی نیز مانند پالارز از اجرای تنبل، چندرشته‌ای و تکه‌تکه استفاده می‌کند. همچنین اجازه می‌دهد کاربران نقشه پرس‌وجو را از طریق .explain() ببینند که مراحلی مانند TABLE_SCAN ،HASH_GROUP_BY و PROJECTION را نشان می‌دهد. در یک پروفایل اجرا، اسکن یک میلیارد ردیف ۳۱۶.۳۸ ثانیه و گروه‌بندی هش (Hash Group By) ۱۲۱.۰۱ ثانیه زمان برد.

یکپارچگی از طریق آپاچی ارو

تغییر ابزار به معنای بازنویسی کامل کد نیست. آپاچی ارو (Apache Arrow) — یک فرمت ستونی درون‌حافظه که توسط وس مک‌کینی (بنیان‌گذار پانداز) ساخته شده — به‌عنوان پل ارتباطی عمل می‌کند. از نسخه ۲.۰ پانداز (آوریل ۲۰۲۳)، پالارز و داک‌دی‌بی همگی از Arrow به‌طور بومی پشتیبانی می‌کنند.

این یعنی شما می‌توانید دیتافریم‌ها را بدون کپی کردن حافظه بین این سه کتابخانه جابه‌جا کنید. تنها نکته این است که پانداز به‌طور پیش‌فرض از Arrow استفاده نمی‌کند و باید هنگام ساخت دیتافریم، dtype_backend="pyarrow" را مشخص کنید. این موضوع هزینه مهاجرت بین فریم‌ورک‌ها را تقریباً به صفر می‌رساند.

کاربرد واقعی: داده‌های تاکسی نیویورک

در تستی با ۳ گیگابایت فایل Parquet مربوط به تاکسی‌های نیویورک (سفرهای ۲۰۰۹ تا کنون) برای تحلیل اینکه آیا پرداخت‌های نقدی در دوران پاندمی (۲۰۱۹-۲۰۲۲) کمتر شده است یا خیر، چهار گردش‌کار مقایسه شدند. این تحلیل شامل فیلتر کردن تاریخ‌ها بین ۲۰۱۹-۰۱-۰۱ و ۲۰۲۳-۰۱-۰۱ و گروه‌بندی بر اساس سال و ماه بود. پیاده‌سازی پانداز نیاز به حلقه‌های دستی روی فایل‌ها و استفاده از pd.concat داشت، در حالی که داک‌دی‌بی می‌توانست مستقیماً با استفاده از الگوی '{folder}/*.parquet' روی پوشه پرس‌وجو کند:

۱. پانداز خالص: ۴۱.۸۸ ثانیه، ۱۴.۵۲ گیگابایت رم.
۲. خواندن با داک‌دی‌بی $
ightarrow$ محاسبه با پانداز
: ۲۸.۳۹ ثانیه، ۱۴.۷۹ گیگابایت رم.
۳. خواندن با پانداز $
ightarrow$ محاسبه با داک‌دی‌بی
: ۲۹.۲۵ ثانیه، ۱۲.۳۹ گیگابایت رم.
۴. داک‌دی‌بی خالص: ۲۱.۷۰ ثانیه، ۲۱۶.۷۶ مگابایت رم.

پاندا باید منقرض شود: چرا حفاظت از گونه‌های نمادین، منابع را از تنوع زیستی واقعی دور می‌کند

این تست تایید می‌کند که گلوگاه اصلی اغلب خودِ موتور پانداز است. حتی وقتی پانداز فقط برای محاسبات نهایی استفاده می‌شود، فرآیند به طور قابل توجهی کندتر و پرمصرف‌تر از یک خط لوله خالص داک‌دی‌بی است. داک‌دی‌بی می‌تواند تمام هسته‌های CPU ماشین را به طور کامل به کار بگیرد در حالی که مصرف حافظه آن بسیار ناچیز است.

حکم نهایی برای توسعه‌دهندگان

تردید منطقی است. برخی ممکن است هزینه تغییر ابزار را در صورتی که عمیقاً در اکوسیستم پانداز ادغام شده‌اند زیاد بدانند، و پانداز نیز در حال بهبود است، هرچند به کندی. با این حال، مزایای داک‌دی‌بی و پالارز فراتر از سرعت خالص است:

  • چندرشته‌ای بدون دردسر: آن‌ها به‌طور خودکار از تمام هسته‌های CPU استفاده می‌کنند بدون اینکه نیاز به مدیریت دستی رشته‌ها باشد. شما هزینه آن هسته‌ها را پرداخته‌اید، پس از آن‌ها استفاده کنید!
  • مدیریت بهینه حافظه و استریمینگ: پردازش تکه‌تکه (Chunk-wise) ردپای رم را به شدت کاهش می‌دهد.
  • انتقال هوشمند به دیسک (Spill-to-Disk): وقتی عملیات‌ها از ظرفیت رم فراتر می‌روند، این ابزارها نتایج میانی را بهینه‌تر از Swap سیستم‌عامل روی دیسک می‌نویسند.
  • رابط‌های کاربری بهتر: هر دو رابط‌های کم‌گیج‌کننده‌تری دارند؛ داک‌دی‌بی به‌طور خاص از SQL استفاده می‌کند که مهارتی بسیار قابل انتقال است.

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

گام بعدی شما

  • اگر دیتافریم‌های شما در پانداز بیش از ۱۰ گیگابایت است، ابتدا نصب Polars را امتحان کنید و متدهای scan_csv را جایگزین read_csv کنید.
  • برای تحلیل‌های سریع روی فایل‌های Parquet بدون راه‌اندازی دیتابیس، از DuckDB و دستورات SQL مستقیم استفاده کنید.
  • برای انتقال بدون هزینه حافظه بین این ابزارها، در پانداز از dtype_backend="pyarrow" استفاده کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره تراشه‌های Blackwell و تاثیر آن بر پردازش داده‌های محلی مراجعه کنید.

چرا این موضوع مهم است؟

این تغییر پارادایم باعث می‌شود شرکت‌ها به‌جای سرمایه‌گذاری روی خوشه‌های گران‌قیمت Spark، روی سخت‌افزارهای تک‌ماشینه قدرتمند‌تر سرمایه‌گذاری کنند. این موضوع هزینه استنتاج و تحلیل داده‌ها را برای استارتاپ‌ها به‌شدت کاهش می‌دهد.

تأثیر برای ایران

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

·نگاه ما
تحریریه دات‌هوش

پذیرش کورکورانه سیستم‌های توزیع‌شده (Distributed Systems) به عنوان تنها راه حل برای کندی پانداز، یکی از رایج‌ترین اشتباهات معماری در تیم‌های داده است. این داده‌ها نشان می‌دهند که «بهینه‌سازی تک‌ماشینه» با استفاده از زبان‌هایی مثل Rust و مدل‌های Lazy Evaluation، می‌تواند تا ۹۰٪ از هزینه‌های زیرساختی را حذف کند. در واقع، ما شاهد بازگشت به سمت پردازش متمرکز اما بهینه هستیم.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.