استنساخ جدول على Azure Databricks
يمكنك إنشاء نسخة من جدول Delta Lake موجود على Azure Databricks في إصدار معين باستخدام clone
الأمر . يمكن أن تكون المستنسخات عميقة أو ضحلة.
يدعم Azure Databricks أيضا استنساخ جداول Parquet و Iceberg. راجع استنساخ جداول Parquet و Iceberg بشكل متزايد إلى Delta Lake.
للحصول على تفاصيل حول استخدام النسخ مع كتالوج Unity، راجع استنساخ سطحي لجداول كتالوج Unity.
إشعار
توصي Databricks باستخدام Delta Sharing لتوفير الوصول للقراءة فقط إلى الجداول عبر مؤسسات مختلفة. راجع ما المقصود بمشاركة دلتا؟.
أنواع النسخ
- النسخة العميقة هي نسخة تنسخ بيانات الجدول المصدر إلى هدف النسخ بالإضافة إلى بيانات التعريف للجدول الموجود. بالإضافة إلى ذلك، يتم أيضا استنساخ بيانات تعريف الدفق بحيث يمكن إيقاف الدفق الذي يكتب إلى جدول Delta على جدول مصدر ومتابعة هدف نسخة من حيث توقفت.
- النسخة الضحلة هي نسخة لا تنسخ ملفات البيانات إلى هدف النسخ. بيانات تعريف الجدول مكافئة للمصدر. هذه المستنسخات أرخص في الإنشاء.
تتضمن بيانات التعريف المستنسخة: المخطط، ومعلومات التقسيم، والمتباينات، وقابلية القيم الخالية. بالنسبة للنسخ العميقة فقط، يتم أيضا استنساخ بيانات التعريف الدفق والنسخ إلى . بيانات التعريف غير المستنسخة هي وصف الجدول وبيانات تعريف التثبيت المعرفة من قبل المستخدم.
ما دلالات عمليات استنساخ دلتا؟
إذا كنت تعمل مع جدول Delta مسجل في Hive metastore أو مجموعة من الملفات غير المسجلة كجدول، فإن الاستنساخ يحتوي على الدلالات التالية:
هام
في Databricks Runtime 13.3 LTS وما فوق، تدعم الجداول المدارة كتالوج Unity النسخ الضحلة. تختلف دلالات الاستنساخ لجداول كتالوج Unity بشكل كبير عن دلالات استنساخ Delta Lake في بيئات أخرى. راجع استنساخ سطحي لجداول كتالوج Unity.
- أي تغييرات أجريت على النسخ العميقة أو الضحلة تؤثر فقط على المستنسخين أنفسهم وليس الجدول المصدر.
- استنساخ سطحي لملفات البيانات المرجعية في الدليل المصدر. إذا قمت بتشغيل
vacuum
على الجدول المصدر، فلن يتمكن العملاء بعد الآن من قراءة ملفات البيانات المشار إليها ويتمFileNotFoundException
طرح . في هذه الحالة، يؤدي تشغيل النسخة مع استبدال فوق الاستنساخ الضحل إلى إصلاح النسخة. إذا حدث ذلك في كثير من الأحيان، ففكر في استخدام نسخة عميقة بدلا من ذلك لا تعتمد على الجدول المصدر. - لا تعتمد النسخ العميقة على المصدر الذي تم استنساخها منه، ولكنها مكلفة في الإنشاء لأن النسخ العميق ينسخ البيانات بالإضافة إلى بيانات التعريف.
- يؤدي الاستنساخ مع
replace
إلى هدف يحتوي بالفعل على جدول في هذا المسار إلى إنشاء سجل Delta إذا لم يكن موجودا في هذا المسار. يمكنك تنظيف أي بيانات موجودة عن طريق تشغيلvacuum
. - بالنسبة لجداول Delta الموجودة، يتم إنشاء تثبيت جديد يتضمن بيانات التعريف الجديدة والبيانات الجديدة من الجدول المصدر. هذا التثبيت الجديد تزايدي، ما يعني أن التغييرات الجديدة فقط منذ آخر نسخة ملتزمة بالجدول.
- استنساخ جدول ليس هو نفسه أو
Create Table As Select
CTAS
. نسخة تنسخ بيانات التعريف للجدول المصدر بالإضافة إلى البيانات. يحتوي الاستنساخ أيضا على بناء جملة أبسط: لا تحتاج إلى تحديد التقسيم والتنسيق والمتباينات وقابلية القيم الخالية وما إلى ذلك كما يتم أخذها من الجدول المصدر. - يحتوي الجدول المستنسخ على محفوظات مستقلة عن الجدول المصدر الخاص به. لا تعمل استعلامات السفر عبر الزمن على جدول مستنسخ مع نفس المدخلات أثناء عملها على الجدول المصدر الخاص به.
مثال على بناء جملة الاستنساخ
توضح أمثلة التعليمات البرمجية التالية بناء الجملة لإنشاء نسخ عميقة وضحلة:
SQL
CREATE TABLE target_table CLONE source_table; -- Create a deep clone of source_table as target_table
CREATE OR REPLACE TABLE target_table CLONE source_table; -- Replace the target
CREATE TABLE IF NOT EXISTS target_table CLONE source_table; -- No-op if the target table exists
CREATE TABLE target_table SHALLOW CLONE source_table;
CREATE TABLE target_table SHALLOW CLONE source_table VERSION AS OF version;
CREATE TABLE target_table SHALLOW CLONE source_table TIMESTAMP AS OF timestamp_expression; -- timestamp can be like “2019-01-01” or like date_sub(current_date(), 1)
Python
from delta.tables import *
deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=True, replace=False) # clone the source at latest version
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=True, replace=False) # clone the source at a specific version
# clone the source at a specific timestamp such as timestamp="2019-01-01"
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=True, replace=False)
Scala
import io.delta.tables._
val deltaTable = DeltaTable.forName(spark, "source_table")
deltaTable.clone(target="target_table", isShallow=true, replace=false) // clone the source at latest version
deltaTable.cloneAtVersion(version=1, target="target_table", isShallow=true, replace=false) // clone the source at a specific version
deltaTable.cloneAtTimestamp(timestamp="2019-01-01", target="target_table", isShallow=true, replace=false) // clone the source at a specific timestamp
للحصول على تفاصيل بناء الجملة، راجع إنشاء نسخة جدول.
استنساخ المقاييس
CLONE
يبلغ عن المقاييس التالية ك DataFrame صف واحد بمجرد اكتمال العملية:
source_table_size
: حجم الجدول المصدر الذي يتم استنساخه بالبايت.source_num_of_files
: عدد الملفات في الجدول المصدر.num_removed_files
: إذا تم استبدال الجدول، فكم عدد الملفات التي تتم إزالتها من الجدول الحالي.num_copied_files
: عدد الملفات التي تم نسخها من المصدر (0 للنسخ الضحلة).removed_files_size
: الحجم بالبايت للملفات التي تتم إزالتها من الجدول الحالي.copied_files_size
: الحجم بالبايت للملفات المنسخة إلى الجدول.
الأذونات
يجب تكوين أذونات للتحكم في الوصول إلى جدول Azure Databricks وموفر السحابة الخاص بك.
التحكم في الوصول إلى الجدول
الأذونات التالية مطلوبة لكل من النسخ العميقة والضحلة:
SELECT
إذن في الجدول المصدر.- إذا كنت تستخدم
CLONE
لإنشاء جدول جديد،CREATE
فإذن على قاعدة البيانات التي تقوم بإنشاء الجدول فيها. - إذا كنت تستخدم
CLONE
لاستبدال جدول، يجب أن يكون لديكMODIFY
إذن على الجدول.
أذونات موفر السحابة
إذا قمت بإنشاء نسخة عميقة، يجب أن يكون لأي مستخدم يقرأ النسخة العميقة حق الوصول للقراءة إلى دليل النسخ. لإجراء تغييرات على النسخة، يجب أن يكون لدى المستخدمين حق الوصول للكتابة إلى دليل النسخ.
إذا قمت بإنشاء نسخة ضحلة، فإن أي مستخدم يقرأ النسخة الضحلة يحتاج إلى إذن لقراءة الملفات في الجدول الأصلي، نظرا لأن ملفات البيانات تظل في الجدول المصدر مع نسخ ضحلة، بالإضافة إلى دليل النسخ. لإجراء تغييرات على النسخة، سيحتاج المستخدمون إلى الوصول للكتابة إلى دليل النسخ.
استخدام النسخ لأرشفة البيانات
يمكنك استخدام النسخ العميق للحفاظ على حالة الجدول في نقطة زمنية معينة لأغراض الأرشفة. يمكنك مزامنة النسخ العميقة بشكل متزايد للحفاظ على حالة محدثة لجدول مصدر لاسترداد البيانات بعد الكوارث.
-- Every month run
CREATE OR REPLACE TABLE archive_table CLONE my_prod_table
استخدام النسخ لإعادة إنتاج نموذج التعلم الآلي
عند القيام بالتعلم الآلي، قد ترغب في أرشفة إصدار معين من جدول قمت بتدريب نموذج التعلم الآلي عليه. يمكن اختبار النماذج المستقبلية باستخدام مجموعة البيانات المؤرشفة هذه.
-- Trained model on version 15 of Delta table
CREATE TABLE model_dataset CLONE entire_dataset VERSION AS OF 15
استخدام النسخ للتجارب قصيرة المدى على جدول إنتاج
لاختبار سير عمل على جدول إنتاج دون إتلاف الجدول، يمكنك بسهولة إنشاء نسخة ضحلة. يسمح لك هذا بتشغيل مهام سير عمل عشوائية على الجدول المستنسخ الذي يحتوي على جميع بيانات الإنتاج ولكنه لا يؤثر على أي أحمال عمل إنتاج.
-- Perform shallow clone
CREATE OR REPLACE TABLE my_test SHALLOW CLONE my_prod_table;
UPDATE my_test WHERE user_id is null SET invalid=true;
-- Run a bunch of validations. Once happy:
-- This should leverage the update information in the clone to prune to only
-- changed files in the clone if possible
MERGE INTO my_prod_table
USING my_test
ON my_test.user_id <=> my_prod_table.user_id
WHEN MATCHED AND my_test.user_id is null THEN UPDATE *;
DROP TABLE my_test;
استخدام النسخ لتجاوز خصائص الجدول
تعد تجاوزات خصائص الجدول مفيدة بشكل خاص ل:
- إضافة تعليقات توضيحية إلى الجداول التي تحتوي على معلومات المالك أو المستخدم عند مشاركة البيانات مع وحدات عمل مختلفة.
- مطلوب أرشفة جداول دلتا ومحفوظات الجداول أو السفر عبر الوقت. يمكنك تحديد فترات استبقاء البيانات والسجلات بشكل مستقل لجدول الأرشيف. على سبيل المثال:
SQL
CREATE OR REPLACE TABLE archive_table CLONE prod.my_table
TBLPROPERTIES (
delta.logRetentionDuration = '3650 days',
delta.deletedFileRetentionDuration = '3650 days'
)
Python
dt = DeltaTable.forName(spark, "prod.my_table")
tblProps = {
"delta.logRetentionDuration": "3650 days",
"delta.deletedFileRetentionDuration": "3650 days"
}
dt.clone(target="archive_table", isShallow=False, replace=True, tblProps)
Scala
val dt = DeltaTable.forName(spark, "prod.my_table")
val tblProps = Map(
"delta.logRetentionDuration" -> "3650 days",
"delta.deletedFileRetentionDuration" -> "3650 days"
)
dt.clone(target="archive_table", isShallow = false, replace = true, properties = tblProps)