۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

حل بهینه سازی پرس و جو در Presto

با ترکیب یادگیری ماشین و اجرای پرس و جو تطبیقی، بهینه سازی پرس و جو در Presto می تواند در استفاده مکرر هوشمندتر و کارآمدتر شود.

با ترکیب یادگیری ماشین و اجرای پرس و جو تطبیقی، بهینه سازی پرس و جو در Presto می تواند در استفاده مکرر هوشمندتر و کارآمدتر شود.

“SQL در مورد همه چیز” برچسب مرتبط با Presto است، موتور جستجویی که در ابتدا توسط فیس بوک به سرعت توسعه یافت. تجزیه و تحلیل حجم عظیمی از داده ها – به ویژه داده هایی که در قالب ها و منابع متعدد پراکنده شده اند. از زمان انتشار آن به عنوان یک پروژه منبع باز در سال ۲۰۱۳، Presto به طور گسترده در صدها شرکت مورد استفاده قرار گرفته است. امروز، یک جامعه قوی در سراسر جهان به توسعه مداوم آن کمک می کند.

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

اقتصاد ابری الاستیک تغییر تکتونیکی در این صنعت است که اکنون به شرکت‌ها اجازه می‌دهد فقط برای منابعی که استفاده می‌کنند پول پرداخت کنند. آن‌ها می‌توانند از سرویس‌های ذخیره‌سازی داده کم‌هزینه ارائه‌شده در فضای ابری، مانند Amazon S3 استفاده کنند و به‌صورت پویا، اسب‌های کاری پردازش داده را در قالب سرورهای مجازی که تقریباً با اندازه حجم کاری متفاوت مطابقت دارند، ارائه دهند.

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

در حالی که معماری فدرال Presto در توانایی پردازش داده ها در محل بسیار سودمند است، پیچیدگی قابل توجهی در ایجاد یک برنامه اجرای بهینه برای یک پرس و جو ایجاد می کند. ادامه این مقاله توضیح خواهد داد که چرا ایجاد یک طرح اجرای کوئری بهینه یک مشکل سخت برای Presto است و دیدگاهی در مورد راه پیش رو بیان می کند.

تکامل بهینه ساز پرس و جو

ابتدا، اجازه دهید یک قدم به عقب برگردم و مشکل عمومی و برخی از راه حل هایی را که در چند دهه گذشته توسعه داده شده اند، شرح دهم. بهینه سازهای پرس و جو مسئول تبدیل SQL، بیان شده به صورت توضیحی، به دنباله ای کارآمد از عملیات هستند که ممکن است توسط موتور بر روی داده های اساسی انجام شود. به این ترتیب، بهینه سازهای پرس و جو جزء حیاتی پایگاه های داده هستند.

ورودی بهینه ساز پرس و جو یک “طرح منطقی” است که خود نتیجه تجزیه ورودی SQL و تبدیل آن به مجموعه سطح بالایی از عملیات مورد نیاز برای اجرای پرس و جو است. سپس بهینه ساز بر روی تبدیل طرح منطقی به یک استراتژی اجرایی کارآمد بسته به اپراتورهای موجود در موتور جستجو و ویژگی های طرح داده کار می کند.

آینده انبار داده عملیاتی

برای یک پرس و جو معمولی SQL، یک طرح منطقی وجود دارد اما استراتژی های زیادی برای پیاده سازی و اجرای آن طرح منطقی برای تولید نتایج مورد نظر وجود دارد. بهینه ساز مسئول انتخاب “بهترین” طرح اجرایی در بین این نامزدها است. در واقع، مجموعه کاندیداهای بالقوه (فضای جستجو) که بهینه‌ساز باید از میان آنها سرک کند، آنقدر زیاد است که شناسایی طرح پرس و جو بهینه در میان آنها یک “مسئله سخت NP” است. این روش دیگری برای گفتن این است که رایانه ها نمی توانند این مشکل را در هر بازه زمانی معقولی حل کنند.

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

اجازه دهید با استفاده از یک مثال عینی سعی کنیم بفهمیم این به چه شکل است. مثال زیر که از مجموعه ای از پرس و جوهای موردی انتخاب شده است، بخشی از معیار پشتیبانی تصمیم گیری رایج، TPC-H است. TPC-H Q3، درخواست اولویت حمل و نقل، عبارتی است که ۱۰ سفارش ارسال نشده را با بالاترین ارزش بازیابی می کند.

SELECT
       l_orderkey,
       SUM(l_extendedprice * ( 1 - l_discount )) AS revenue,
       o_orderdate,
       o_shippriority
FROM  
       customer,
       orders,
       lineitem
WHERE 
       c_mktsegment = 'AUTOMOBILE'
       AND c_custkey = o_custkey
       AND l_orderkey = o_orderkey
       AND o_orderdate < DATE '1995-03-01'
       AND l_shipdate > DATE '1995-03-01'
GROUP  BY l_orderkey,
          o_orderdate,
          o_shippriority
ORDER  BY
         revenue DESC,
          o_orderdate;

این پرس و جو یک اتصال سه طرفه بین جداول داده مشتری، سفارشات و lineitem انجام می دهد (کلیدهای پیوستن custkey< /code> و orderkey) و با اعمال مجموعه‌ای از فیلترها (c_mktsegment، o_orderdate، l_shipdate). سپس پرس و جو یک SUM را با گروه بندی بر روی هر ترکیب مجزا از l_orderkey، o_orderdate و o_shippriority و سفارشات محاسبه می کند. نتیجه با ترتیب نزولی ستون محاسبه شده (درآمد) و orderdate تنظیم می شود.

رویکرد ساده لوحانه

رویکرد ساده‌لوحانه برای بهینه‌سازی این پرس‌وجو، یک اتصال متقاطع کامل را در سه جدول انجام می‌دهد (یک محصول دکارتی)، تمام چند تاپلی را که فیلترهای موجود در عبارت WHERE را برآورده نمی‌کنند، از این مجموعه حذف می‌کند. ، سپس با شناسایی هر ترکیب منحصر به فرد l_orderkey، o_orderdate و o_shippriority تجمیع را انجام دهید و SUM(l_extendedprice * ( 1 - l_discount ))، و در نهایت نتیجه تنظیم شده را در o_orderdate سفارش دهید. این توالی از عملیات، در حالی که تضمین شده برای تولید نتایج دقیق است، حتی برای یک مجموعه داده با اندازه متوسط ​​در اکثر سخت افزارها کار نخواهد کرد. محصول دکارتی یک مجموعه نتایج میانی عظیم تولید می کند که فراتر از محدودیت های حافظه اصلی اکثر سرورها است. همچنین خواندن تمام داده‌ها از دیسک برای هر سه جدول ناکارآمد است، در حالی که پرس و جو فقط به چند تاپل خاص علاقه‌مند است که محدودیت‌های توصیف شده در محمولات را برآورده می‌کند.

بهینه ساز مبتنی بر قانون (RBO)

این چارچوب برخی از مشکلات در رویکرد ساده لوحانه را کاهش می دهد. برای نشان دادن، می‌تواند طرحی ایجاد کند که در آن محمول‌ها در حالی که داده‌ها برای هر جدول خوانده می‌شوند، اعمال شوند. بنابراین، در حالی که تاپل ها برای جدول مشتری انجام می شود، تنها رکوردهایی که با c_mktsegment = 'AUTOMOBILE' مطابقت دارند، محقق می شوند. به همین ترتیب، فقط رکوردهای رضایت بخش o_orderdate < DATE '1995-03-01' برای سفارشات جدول و سوابق رضایت بخش l_shipdate > DATE '1995-03-01' برای جدول lineitem از دیسک خوانده می شود. این قبلاً اندازه نتیجه میانی را با چندین مرتبه بزرگ کاهش می دهد.

RBO همچنین هرگز یک محصول دکارتی از هر سه جدول را برای نتیجه میانی در این مورد پیشنهاد نمی‌کند. در عوض ابتدا یک اتصال بین دو جدول انجام می دهد، به عنوان مثال. مشتری و سفارش‌ها، و فقط تاپل‌هایی را که با گزاره c_custkey = o_custkey مطابقت دارند حفظ می‌کنند و سپس یک اتصال دیگر بین این مجموعه نتایج میانی و جدول lineitem.

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

برای مثال، هنگام پیوستن به مشتری با سفارش‌ها، یک جدول هش بر روی customer.c_custkey و سپس برای سوابق موجود در < ساخته می‌شود. code>orders، فقط رکوردهایی که orders.o_custkey در جدول هش وجود دارد خوانده می شوند. جدول هش از ورودی کوچکتر به اتصال ساخته می شود، زیرا شانس بیشتری برای جا افتادن در حافظه دارد و فقط تاپل هایی را که برای هر اتصال لازم است، مادی می کند. (فشار دادن تجمیع به زیر اتصال یکی دیگر از تکنیک های بهینه سازی پیشرفته است، اما خارج از حوصله این مقاله است.)

بهینه ساز مبتنی بر هزینه (CBO)

گام بعدی در تکامل بهینه سازهای پرس و جو ظهور بهینه سازی مبتنی بر هزینه بود. اگر برخی از ویژگی‌های داده‌های جداول مانند حداقل و حداکثر مقادیر ستون‌ها، تعداد مقادیر متمایز در ستون‌ها، تعداد null، هیستوگرام‌هایی که توزیع داده‌های ستون‌ها را نشان می‌دهند و غیره می‌دانستند، می‌توانند تأثیر زیادی داشته باشند. در برخی از انتخاب هایی که بهینه ساز انجام می دهد. اجازه دهید این را با پرس و جوی معیار TPC-H Q3 که در بالا مورد بحث قرار گرفت، بررسی کنیم.

CBO از نقطه ثابتی که RBO به آن رسیده است ادامه می یابد. برای بهبود RBO، تعیین اندازه ورودی‌های اتصالات به منظور تصمیم‌گیری از کدام ورودی برای ساخت جدول هش مفید خواهد بود. اگر این اتصال بین دو جدول در کلیدهای اتصال بود، بدون گزاره اضافی، RBO معمولاً از تعداد ردیف جداول آگاهی دارد و می تواند ورودی هش را به درستی انتخاب کند. با این حال، در بیشتر موارد، محمولات اضافی وجود دارد که اندازه ورودی اتصال را تعیین می کند.

به عنوان مثال، در جستار Q3 customer.c_mktsegment = 'AUTOMOBILE' در customer و orders.o_orderdate < DATE '01-03-1995 وجود دارد « در سفارش‌ها. CBO به موتور متکی است تا گزینش‌های این محمولات را در جداول ارائه دهد و سپس از آنها برای تخمین اندازه ورودی‌های اتصال استفاده می‌کند. بنابراین، حتی اگر ممکن است جدول مشتری از جدول orders کوچکتر باشد، پس از اعمال فیلترها، تعداد رکوردهایی که از orders وارد پیوست می شوند. جدول /code> ممکن است در واقع کمتر باشد. یک CBO همچنین می‌تواند کاردینالیته تخمینی عملیات خاصی مانند پیوستن یا تجمیع را از طریق طرح منتشر کند و از آنها برای انتخاب هوشمندانه در بخش‌های دیگر طرح پرس و جو استفاده کند.

بهینه سازی پرس و جو در پایگاه های داده Presto در مقابل سنتی

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

دقیق و به روز نگه داشتن آمار دریاچه داده ها مستلزم تعهد زیادی از منابع است و حفظ آن بسیار دشوار است - همانطور که بسیاری از شرکت ها کشف کرده اند. علاوه بر این، به عنوان یک موتور فدراسیون داده، Presto، اغلب به طور همزمان، با چندین ذخیره‌گاه داده که ویژگی‌های بسیار متفاوتی دارند، رابط کاربری دارد. این منابع داده می‌توانند از یک سیستم فایل ساده (HDFS) تا سیستم‌های جریان مداوم داده (Pinot، Druid) تا سیستم‌های پایگاه داده بالغ (Postgres، MySQL) را شامل شود. و تعداد بیشتری از این رابط‌ها اغلب اضافه می‌شوند.

ایجاد یک مدل هزینه یکپارچه که همه این منابع داده را پوشش می‌دهد و بهینه‌ساز را قادر می‌سازد تا به طور کمی در مورد مبادله هزینه‌های دسترسی در این منابع استدلال کند، یک مشکل فوق‌العاده سخت است. فقدان آمار قابل اعتماد و فقدان یک مدل هزینه یکپارچه باعث شده است که شرکت های بزرگ به طور کامل بهینه سازی مبتنی بر هزینه در Presto را نادیده بگیرند، حتی اگر جامعه پشتیبانی محدودی از برخی ویژگی های CBO مانند سفارش مجدد پیوستن داشته باشد.

یک طرح بهینه سازی پرس و جو هوشمندتر برای Presto

به نظر من به جای صرف تلاش برای بازآفرینی آنچه برای RDBMS های سنتی کار می کرد، یعنی بازسازی دقیق یک مدل هزینه فدرال برای Presto، کشف رویکردهای جایگزین برای حل این مشکل سودمندتر خواهد بود. رویکردهای قدیمی برای بهینه‌سازی پرس و جو معمولاً مشکل را در یک زمینه ثابت در نظر می‌گیرند - به عنوان مثال، بهینه‌ساز به‌طور مستقل کار می‌کند تا یک طرح بهینه ارائه کند که سپس به زمان‌بندی یا موتور اجرایی DBMS واگذار می‌شود.

اجرای پرس و جو تطبیقی ​​الگویی است که تمایز معماری بین برنامه ریزی پرس و جو و اجرای پرس و جو را حذف می کند. این چارچوبی است که در آن طرح اجرا تطبیقی ​​است: می‌تواند داده‌های در حال پردازش را نظارت کند و بسته به ویژگی‌های داده‌ای که از طریق اپراتورهای طرح جریان می‌یابد تغییر شکل دهد.

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