معالجة الاستعلامات الكبيرة في مهام سير العمل التفاعلية

يتمثل أحد التحديات المتعلقة بسير عمل البيانات التفاعلية في معالجة الاستعلامات الكبيرة. يتضمن ذلك الاستعلامات التي تنشئ عددا كبيرا جدا من صفوف الإخراج، أو تجلب العديد من الأقسام الخارجية، أو تحسب على مجموعات بيانات كبيرة للغاية. يمكن أن تكون هذه الاستعلامات بطيئة للغاية، وتشبع موارد الحوسبة، وتجعل من الصعب على الآخرين مشاركة نفس الحساب.

Query Watchdog هي عملية تمنع الاستعلامات من احتكار موارد الحوسبة عن طريق فحص الأسباب الأكثر شيوعا للاستعلامات الكبيرة وإنهاء الاستعلامات التي تمرر حدا. توضح هذه المقالة كيفية تمكين وتكوين Query Watchdog.

هام

يتم تمكين Query Watchdog لجميع الحسابات لجميع الأغراض التي تم إنشاؤها باستخدام واجهة المستخدم.

مثال على استعلام تعطيلي

يقوم محلل بإجراء بعض الاستعلامات المخصصة في مستودع بيانات في الوقت المناسب. يستخدم المحلل حساب تحجيم تلقائي مشترك يسهل على العديد من المستخدمين استخدام حساب واحد في نفس الوقت. لنفترض أن هناك جدولين يحتوي كل منهما على مليون صف.

import org.apache.spark.sql.functions._
spark.conf.set("spark.sql.shuffle.partitions", 10)

spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_x")
spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_y")

يمكن إدارة أحجام الجداول هذه في Apache Spark. ومع ذلك، تتضمن كل منها عمودا join_key بسلسلة فارغة في كل صف. يمكن أن يحدث هذا إذا لم تكن البيانات نظيفة تماما أو إذا كان هناك انحراف كبير في البيانات حيث تكون بعض المفاتيح أكثر انتشارا من غيرها. مفاتيح الصلة الفارغة هذه أكثر انتشارا بكثير من أي قيمة أخرى.

في التعليمات البرمجية التالية، ينضم المحلل إلى هذين الجدولين على مفاتيحه، ما ينتج عنه إخراج تريليون نتيجة، ويتم إنتاج كل هذه النتائج على منفذ واحد (المنفذ الذي يحصل على " " المفتاح):

SELECT
  id, count(id)
FROM
  (SELECT
    x.id
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key)
GROUP BY id

يبدو أن هذا الاستعلام قيد التشغيل. ولكن دون معرفة البيانات، يرى المحلل أن هناك "فقط" مهمة واحدة متبقية على مدار تنفيذ المهمة. لا ينتهي الاستعلام أبدا، مما يترك المحلل محبطا ومشوشا حول سبب عدم عمله.

في هذه الحالة هناك مفتاح انضمام واحد فقط إشكالية. في أحيان أخرى قد يكون هناك الكثير.

تمكين وتكوين Query Watchdog

لتمكين وتكوين Query Watchdog، يلزم اتخاذ الخطوات التالية.

  • تمكين Watchdog باستخدام spark.databricks.queryWatchdog.enabled.
  • تكوين وقت تشغيل المهمة باستخدام spark.databricks.queryWatchdog.minTimeSecs.
  • عرض الإخراج باستخدام spark.databricks.queryWatchdog.minOutputRows.
  • تكوين نسبة الإخراج باستخدام spark.databricks.queryWatchdog.outputRatioThreshold.

لمنع استعلام من إنشاء عدد كبير جدا من صفوف الإخراج لعدد صفوف الإدخال، يمكنك تمكين Query Watchdog وتكوين الحد الأقصى لعدد صفوف الإخراج كمضاعف لعدد صفوف الإدخال. في هذا المثال نستخدم نسبة 1000 (الافتراضي).

spark.conf.set("spark.databricks.queryWatchdog.enabled", true)
spark.conf.set("spark.databricks.queryWatchdog.outputRatioThreshold", 1000L)

يعلن التكوين الأخير أن أي مهمة معينة يجب ألا تنتج أكثر من 1000 مرة عدد صفوف الإدخال.

تلميح

نسبة الإخراج قابلة للتخصيص تماما. نوصي بالبدء بخفض ورؤية الحد المناسب لك ولفريقك. يعد النطاق من 1,000 إلى 10,000 نقطة بداية جيدة.

لا يمنع Query Watchdog المستخدمين من احتكار موارد الحوسبة للوظائف التي لن تكتمل أبدا، بل يوفر أيضا الوقت عن طريق الفشل السريع لاستعلام لم يكن ليكتمل أبدا. على سبيل المثال، سيفشل الاستعلام التالي بعد عدة دقائق لأنه يتجاوز النسبة.

SELECT
  z.id
  join_key,
  sum(z.id),
  count(z.id)
FROM
  (SELECT
    x.id,
    y.join_key
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key) z
GROUP BY join_key, z.id

إليك ما قد تراه:

مربع مراقبة الاستعلام

عادة ما يكون كافيا لتمكين Query Watchdog وتعيين نسبة حد الإخراج/الإدخال، ولكن لديك أيضا خيار تعيين خاصيتين إضافيتين: spark.databricks.queryWatchdog.minTimeSecs و spark.databricks.queryWatchdog.minOutputRows. تحدد هذه الخصائص الحد الأدنى من الوقت الذي يجب تشغيل مهمة معينة في استعلام قبل إلغائها والحد الأدنى لعدد صفوف الإخراج لمهمة في هذا الاستعلام.

على سبيل المثال، يمكنك تعيين minTimeSecs إلى قيمة أعلى إذا كنت تريد منحها فرصة لإنتاج عدد كبير من الصفوف لكل مهمة. وبالمثل، يمكنك تعيين spark.databricks.queryWatchdog.minOutputRows إلى عشرة ملايين إذا كنت تريد إيقاف استعلام فقط بعد أن تنتج مهمة في هذا الاستعلام عشرة ملايين صف. أي شيء أقل وينجح الاستعلام، حتى إذا تم تجاوز نسبة الإخراج/الإدخال.

spark.conf.set("spark.databricks.queryWatchdog.minTimeSecs", 10L)
spark.conf.set("spark.databricks.queryWatchdog.minOutputRows", 100000L)

تلميح

إذا قمت بتكوين Query Watchdog في دفتر ملاحظات، فلن يستمر التكوين عبر عمليات إعادة تشغيل الحساب. إذا كنت ترغب في تكوين Query Watchdog لجميع مستخدمي الحساب، نوصي باستخدام تكوين حساب.

الكشف عن الاستعلام على مجموعة بيانات كبيرة للغاية

قد يقوم استعلام كبير آخر نموذجي بفحص كمية كبيرة من البيانات من جداول/مجموعات بيانات كبيرة. قد تستمر عملية الفحص لفترة طويلة وتشبع موارد الحوسبة (حتى قراءة بيانات التعريف لجدول Hive كبير قد يستغرق قدرا كبيرا من الوقت). يمكنك تعيين maxHivePartitions لمنع جلب العديد من الأقسام من جدول Apache Hive كبير. وبالمثل، يمكنك أيضا تعيين maxQueryTasks للحد من الاستعلامات على مجموعة بيانات كبيرة للغاية.

spark.conf.set("spark.databricks.queryWatchdog.maxHivePartitions", 20000)
spark.conf.set("spark.databricks.queryWatchdog.maxQueryTasks", 20000)

متى يجب تمكين Query Watchdog؟

يجب تمكين Query Watchdog لحساب التحليلات المخصصة حيث يشارك محللو SQL وعلماء البيانات حسابا معينا ويحتاج المسؤول إلى التأكد من أن الاستعلامات "تعمل بشكل جيد" مع بعضها البعض.

متى يجب تعطيل Query Watchdog؟

بشكل عام، لا ننصح بإلغاء الاستعلامات المستخدمة في سيناريو ETL بفارغ الصبر لأنه لا يوجد عادة إنسان في الحلقة لتصحيح الخطأ. نوصي بتعطيل Query Watchdog لجميع حوسبة التحليلات المخصصة باستثناء المخصصة.