أفضل الممارسات: Delta Lake

توضح هذه المقالة أفضل الممارسات عند استخدام Delta Lake.

توصي Databricks باستخدام التحسين التنبؤي. راجع التحسين التنبؤي ل Delta Lake.

عند حذف جدول وإعادة إنشائه في نفس الموقع، يجب عليك دائما استخدام عبارة CREATE OR REPLACE TABLE . راجع إسقاط جدول Delta أو استبداله.

استخدام التجميع السائل لتخطي البيانات المحسنة

توصي Databricks باستخدام التجميع السائل بدلا من التقسيم أو ترتيب Z أو استراتيجيات أخرى لتنظيم البيانات لتحسين تخطيط البيانات لتخطي البيانات. راجع استخدام التجميع السائل لجداول Delta.

ملفات مضغوطة

يعمل OPTIMIZE التحسين التنبؤي تلقائيا والأوامر VACUUM على الجداول المدارة في كتالوج Unity. راجع التحسين التنبؤي ل Delta Lake.

توصي Databricks بتشغيل الأمر OPTIMIZE بشكل متكرر لضغط الملفات الصغيرة.

إشعار

لا تزيل هذه العملية الملفات القديمة. لإزالتها، قم بتشغيل الأمر فراغ .

استبدال محتوى جدول أو مخططه

في بعض الأحيان قد تحتاج إلى استبدال جدول Delta. على سبيل المثال:

  • تكتشف أن البيانات الموجودة في الجدول غير صحيحة وتريد استبدال المحتوى.
  • تريد إعادة كتابة الجدول بأكمله لإجراء تغييرات مخطط غير متوافقة (مثل تغيير أنواع الأعمدة).

بينما يمكنك حذف الدليل بأكمله لجدول Delta وإنشاء جدول جديد على نفس المسار، فإنه لا يوصى به لأن:

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

إذا لم تكن بحاجة إلى تغيير مخطط الجدول، يمكنك حذف البيانات من جدول Delta وإدراج البيانات الجديدة، أو تحديث الجدول لإصلاح القيم غير الصحيحة.

إذا كنت تريد تغيير مخطط الجدول، يمكنك استبدال الجدول بأكمله بشكل ذري. على سبيل المثال:

Python

dataframe.write \
  .format("delta") \
  .mode("overwrite") \
  .option("overwriteSchema", "true") \
  .saveAsTable("<your-table>") # Managed table

dataframe.write \
  .format("delta") \
  .mode("overwrite") \
  .option("overwriteSchema", "true") \
  .option("path", "<your-table-path>") \
  .saveAsTable("<your-table>") # External table

SQL

REPLACE TABLE <your-table> USING DELTA AS SELECT ... -- Managed table
REPLACE TABLE <your-table> USING DELTA LOCATION "<your-table-path>" AS SELECT ... -- External table

Scala

dataframe.write
  .format("delta")
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .saveAsTable("<your-table>") // Managed table

dataframe.write
  .format("delta")
  .mode("overwrite")
  .option("overwriteSchema", "true")
  .option("path", "<your-table-path>")
  .saveAsTable("<your-table>") // External table

هناك فوائد متعددة مع هذا النهج:

  • الكتابة فوق جدول أسرع بكثير لأنه لا يحتاج إلى سرد الدليل بشكل متكرر أو حذف أي ملفات.
  • لا يزال الإصدار القديم من الجدول موجودا. إذا حذفت الجدول الخطأ، يمكنك بسهولة استرداد البيانات القديمة باستخدام السفر عبر الزمن. راجع العمل مع محفوظات جدول Delta Lake.
  • إنها عملية ذرية. لا يزال بإمكان الاستعلامات المتزامنة قراءة الجدول أثناء حذف الجدول.
  • بسبب ضمانات معاملة Delta Lake ACID، إذا فشل الكتابة فوق الجدول، فسيكون الجدول في حالته السابقة.

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

التخزين المؤقت ل Spark

لا توصي Databricks باستخدام التخزين المؤقت Spark للأسباب التالية:

  • تفقد أي تخطي للبيانات يمكن أن يأتي من عوامل تصفية إضافية تمت إضافتها أعلى المخزن مؤقتا DataFrame.
  • قد لا يتم تحديث البيانات التي يتم تخزينها مؤقتا إذا تم الوصول إلى الجدول باستخدام معرف مختلف.

الاختلافات بين Delta Lake وParquet على Apache Spark

يعالج Delta Lake العمليات التالية تلقائيا. يجب ألا تقوم بهذه العمليات يدويا:

  • REFRESH TABLE: تقوم جداول دلتا دائما بإعادة أحدث المعلومات، لذلك ليست هناك حاجة للاتصال REFRESH TABLE يدويا بعد التغييرات.
  • إضافة أقسام وإزالتها: يتتبع Delta Lake تلقائيا مجموعة الأقسام الموجودة في جدول ويحدث القائمة عند إضافة البيانات أو إزالتها. ونتيجة لذلك، ليست هناك حاجة لتشغيل ALTER TABLE [ADD|DROP] PARTITION أو MSCK.
  • تحميل قسم واحد: قراءة الأقسام مباشرة غير ضرورية. على سبيل المثال، لا تحتاج إلى تشغيل spark.read.format("parquet").load("/data/date=2017-01-01"). بدلا من ذلك، استخدم عبارة WHERE لتخطي البيانات، مثل spark.read.table("<table-name>").where("date = '2017-01-01'").
  • لا تقم بتعديل ملفات البيانات يدويا: يستخدم Delta Lake سجل المعاملات لإجراء تغييرات على الجدول تلقائيا. لا تقم بتعديل ملفات بيانات Parquet أو إضافتها أو حذفها مباشرة في جدول Delta، لأن هذا قد يؤدي إلى فقدان البيانات أو تلف الجدول.

تحسين الأداء لدمج Delta Lake

يمكنك تقليل الوقت المستغرق للدمج باستخدام الأساليب التالية:

  • تقليل مساحة البحث عن التطابقات: بشكل افتراضي، merge تبحث العملية في جدول Delta بأكمله للعثور على التطابقات في الجدول المصدر. تتمثل إحدى طرق الإسراع merge في تقليل مساحة البحث عن طريق إضافة قيود معروفة في حالة المطابقة. على سبيل المثال، افترض أن لديك جدولا مقسما حسب country وتريد date استخدامه merge لتحديث المعلومات لليوم الأخير وبلد معين. إضافة الشرط التالي يجعل الاستعلام أسرع، كما يبحث عن التطابقات فقط في الأقسام ذات الصلة:

    events.date = current_date() AND events.country = 'USA'
    

    علاوة على ذلك، يقلل هذا الاستعلام أيضا من فرص التعارضات مع العمليات المتزامنة الأخرى. راجع مستويات العزل وتعارضات الكتابة على Azure Databricks لمزيد من التفاصيل.

  • الملفات المضغوطة: إذا تم تخزين البيانات في العديد من الملفات الصغيرة، فقد تصبح قراءة البيانات للبحث عن التطابقات بطيئة. يمكنك ضغط الملفات الصغيرة في ملفات أكبر لتحسين معدل نقل القراءة. راجع ملفات البيانات المضغوطة مع التحسين على Delta Lake للحصول على التفاصيل.

  • التحكم في أقسام التبديل العشوائي للكتابات: تقوم merge العملية بخلط البيانات عدة مرات لحساب البيانات المحدثة وكتابتها. يتم التحكم في عدد المهام المستخدمة في التبديل العشوائي بواسطة تكوين spark.sql.shuffle.partitionsجلسة Spark . لا يتحكم تعيين هذه المعلمة في التوازي فحسب، بل يحدد أيضا عدد ملفات الإخراج. تؤدي زيادة القيمة إلى زيادة التوازي ولكنها تولد أيضا عددا أكبر من ملفات البيانات الأصغر.

  • تمكين عمليات الكتابة المحسنة: بالنسبة للجداول المقسمة، merge يمكن أن ينتج عددا أكبر بكثير من الملفات الصغيرة من عدد الأقسام العشوائية. وذلك لأن كل مهمة تبديل يمكن أن تكتب ملفات متعددة في أقسام متعددة، ويمكن أن تصبح ازدحاما في الأداء. يمكنك تقليل عدد الملفات عن طريق تمكين عمليات الكتابة المحسنة. راجع عمليات الكتابة المحسنة ل Delta Lake على Azure Databricks.

  • ضبط أحجام الملفات في الجدول: يمكن ل Azure Databricks الكشف تلقائيا عن ما إذا كان جدول Delta يحتوي على عمليات متكررة merge تعيد كتابة الملفات وقد تختار تقليل حجم الملفات التي تمت إعادة كتابتها تحسبا لإعادة كتابة الملفات مرة أخرى في المستقبل. راجع القسم الخاص بضبط أحجام الملفات للحصول على التفاصيل.

  • دمج التبديل العشوائي المنخفض: يوفر دمج التبديل العشوائي المنخفض تنفيذا MERGE محسنا يوفر أداء أفضل لأحمال العمل الأكثر شيوعا. بالإضافة إلى ذلك، فإنه يحافظ على تحسينات تخطيط البيانات الموجودة مثل ترتيب Z على البيانات غير المعدلة.

إدارة راحة البيانات

في بداية كل استعلام، يتم تحديث جداول Delta تلقائيا إلى أحدث إصدار من الجدول. يمكن ملاحظة هذه العملية في دفاتر الملاحظات عند تقارير حالة الأمر: Updating the Delta table's state. ومع ذلك، عند تشغيل التحليل التاريخي على جدول، قد لا تحتاج بالضرورة إلى بيانات تصل إلى اللحظة الأخيرة، خاصة بالنسبة للجداول التي يتم فيها استيعاب البيانات المتدفقة بشكل متكرر. في هذه الحالات، يمكن تشغيل الاستعلامات على لقطات قديمة من جدول Delta. يمكن أن يقلل هذا الأسلوب من زمن الانتقال في الحصول على النتائج من الاستعلامات.

يمكنك تكوين التسامح مع البيانات القديمة عن طريق تعيين تكوين spark.databricks.delta.stalenessLimit جلسة Spark بقيمة سلسلة زمنية مثل 1h أو 15m (لمدة ساعة واحدة أو 15 دقيقة، على التوالي). هذا التكوين خاص بجلسة العمل، ولا يؤثر على العملاء الآخرين الذين يصلون إلى الجدول. إذا تم تحديث حالة الجدول ضمن حد الثبات، يقوم استعلام مقابل الجدول بإرجاع النتائج دون انتظار آخر تحديث للجدول. لا يمنع هذا الإعداد الجدول من التحديث أبدا، وعند إرجاع البيانات القديمة، يتم معالجة التحديث في الخلفية. إذا كان آخر تحديث للجدول أقدم من حد الثبات، فلن يرجع الاستعلام النتائج حتى يكتمل تحديث حالة الجدول.

نقاط التحقق المحسنة للاستعلامات ذات زمن الانتقال المنخفض

يكتب Delta Lake نقاط التحقق كحالة تجميعية لجدول Delta بتردد محسن. تعمل نقاط التحقق هذه كنقطة بداية لحساب أحدث حالة للجدول. بدون نقاط التحقق، سيتعين على Delta Lake قراءة مجموعة كبيرة من ملفات JSON (ملفات "دلتا") التي تمثل الالتزامات بسجل المعاملات لحساب حالة الجدول. بالإضافة إلى ذلك، يتم تخزين الإحصائيات على مستوى العمود التي يستخدمها Delta Lake لتنفيذ تخطي البيانات في نقطة التحقق.

هام

تختلف نقاط تفتيش Delta Lake عن نقاط التحقق Structured Streaming.

يتم تخزين الإحصائيات على مستوى العمود كبنية وJSON (للتوافق مع الإصدارات السابقة). يجعل تنسيق البنية Delta Lake يقرأ بشكل أسرع بكثير، لأن:

  • لا تقوم Delta Lake بتحليل JSON باهظ الثمن للحصول على إحصائيات على مستوى العمود.
  • تقلل إمكانيات تقليم عمود Parquet بشكل كبير من الإدخال/الإخراج المطلوب لقراءة إحصائيات العمود.

يتيح تنسيق البنية مجموعة من التحسينات التي تقلل من حمل عمليات قراءة Delta Lake من ثوان إلى عشرات المللي ثانية، ما يقلل بشكل كبير من زمن الانتقال للاستعلامات القصيرة.

إدارة الإحصائيات على مستوى العمود في نقاط التحقق

يمكنك إدارة كيفية كتابة الإحصائيات في نقاط التحقق باستخدام خصائص delta.checkpoint.writeStatsAsJson الجدول و delta.checkpoint.writeStatsAsStruct. إذا كانت كلتا خصائص الجدول هي false، فلن يتمكن Delta Lake من تنفيذ تخطي البيانات.

  • تكتب Batch إحصائيات الكتابة بتنسيق JSON والبنية. delta.checkpoint.writeStatsAsJson عبارة عن true.
  • delta.checkpoint.writeStatsAsStruct غير معرف بشكل افتراضي.
  • يستخدم القراء عمود البنية عند توفره وإلا يعود إلى استخدام عمود JSON.

هام

لا تقطع نقاط التحقق المحسنة التوافق مع برامج قراءة مصدر مفتوح Delta Lake. ومع ذلك، قد يكون للإعداد delta.checkpoint.writeStatsAsJson إلى false آثار على قراء Delta Lake الخاصين. اتصل بالموردين لمعرفة المزيد حول الآثار المترتبة على الأداء.

تمكين نقاط التحقق المحسنة للاستعلامات المتدفقة المنظمة

إذا لم يكن لأحمال عمل Structured Streaming متطلبات زمن انتقال منخفض (زمن انتقال فرعي)، يمكنك تمكين نقاط التحقق المحسنة عن طريق تشغيل أمر SQL التالي:

ALTER TABLE [<table-name>|delta.`<path-to-table>`] SET TBLPROPERTIES
('delta.checkpoint.writeStatsAsStruct' = 'true')

يمكنك أيضا تحسين زمن انتقال كتابة نقطة التحقق عن طريق تعيين خصائص الجدول التالية:

ALTER TABLE [<table-name>|delta.`<path-to-table>`] SET TBLPROPERTIES
(
 'delta.checkpoint.writeStatsAsStruct' = 'true',
 'delta.checkpoint.writeStatsAsJson' = 'false'
)

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