Praktik terbaik: Delta Lake

Artikel ini menjelaskan praktik terbaik saat menggunakan Delta Lake.

Databricks merekomendasikan penggunaan pengoptimalan prediktif. Lihat Pengoptimalan prediktif untuk Delta Lake.

Saat menghapus dan membuat ulang tabel di lokasi yang sama, Anda harus selalu menggunakan CREATE OR REPLACE TABLE pernyataan. Lihat Menghilangkan atau mengganti tabel Delta.

Menggunakan pengklusteran cairan untuk melewatkan data yang dioptimalkan

Databricks merekomendasikan penggunaan pengklusteran cair daripada pemartisian, urutan Z, atau strategi organisasi data lainnya untuk mengoptimalkan tata letak data untuk melewatkan data. Lihat Gunakan pengklusteran cair untuk tabel Delta.

File ringkas

Pengoptimalan prediktif secara otomatis berjalan OPTIMIZE dan VACUUM perintah pada tabel terkelola Unity Catalog. Lihat Pengoptimalan prediktif untuk Delta Lake.

Databricks merekomendasikan untuk sering menjalankan perintah OPTIMIZE untuk memampatkan file kecil.

Catatan

Operasi ini tidak menghapus file yang lama. Untuk menghapusnya, jalankan perintah VACUUM.

Mengganti konten atau skema tabel

Terkadang Anda mungkin ingin mengganti tabel Delta. Contohnya:

  • Anda menemukan data dalam tabel salah dan ingin mengganti konten.
  • Anda ingin meregenerasi seluruh tabel untuk melakukan perubahan skema yang tidak kompatibel (seperti mengubah jenis kolom).

Meskipun Anda dapat menghapus seluruh direktori tabel Delta dan membuat tabel baru pada jalur yang sama, itu tidak disarankan karena:

  • Menghapus direktori tidak efisien. Direktori yang berisi file yang sangat besar dapat memakan waktu berjam-jam atau bahkan berhari-hari untuk dihapus.
  • Anda kehilangan semua konten dalam file yang dihapus; sulit untuk memulihkan jika Anda menghapus tabel yang salah.
  • Penghapusan direktori bukan atom. Saat Anda menghapus tabel, kueri bersamaan yang membaca tabel dapat gagal atau melihat tabel parsial.

Jika Anda tidak perlu mengubah skema tabel, Anda dapat menghapus data dari tabel Delta dan menyisipkan data baru Anda, atau memperbarui tabel untuk memperbaiki nilai yang salah.

Jika Anda ingin mengubah skema tabel, Anda dapat mengganti seluruh tabel secara atomis. Contohnya:

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

Ada banyak manfaat dengan pendekatan ini:

  • Menimpa tabel jauh lebih cepat karena tidak perlu mencantumkan direktori secara rekursif atau menghapus file apa pun.
  • Versi lama tabel masih ada. Jika Anda menghapus tabel yang salah, Anda dapat dengan mudah mengambil data lama menggunakan perjalanan waktu. Lihat Bekerja dengan riwayat tabel Delta Lake.
  • Ini adalah operasi atom. Kueri bersamaan masih dapat membaca tabel saat Anda menghapus tabel.
  • Karena jaminan transaksi Delta Lake ACID, jika menimpa tabel gagal, tabel akan berada dalam keadaan sebelumnya.

Selain itu, jika Anda ingin menghapus file lama untuk menghemat biaya penyimpanan setelah menimpa tabel, Anda dapat menggunakan VACUUM untuk menghapusnya. Ini dioptimalkan untuk penghapusan file dan biasanya lebih cepat daripada menghapus seluruh direktori.

Penembolokan Spark

Databricks tidak menyarankan Anda untuk menggunakan penembolokan Spark untuk alasan berikut:

  • Anda kehilangan data yang melompat-lompat yang dapat berasal dari filter tambahan yang ditambahkan di atas cache DataFrame.
  • Data yang di-cache mungkin tidak diperbarui jika tabel diakses menggunakan pengidentifikasi yang berbeda.

Perbedaan antara Delta Lake dan Parquet di Apache Spark

Delta Lake menangani operasi berikut secara otomatis. Anda tidak boleh melakukan operasi ini secara manual:

  • REFRESH TABLE: Tabel Delta selalu mengembalikan informasi terbaru, jadi tidak perlu memanggil REFRESH TABLE secara manual setelah perubahan.
  • Menambahkan dan menghapus partisi: Delta Lake secara otomatis melacak kumpulan partisi yang ada dalam tabel dan memperbarui daftar saat data ditambahkan atau dihapus. Sehingga, tidak perlu menjalankan ALTER TABLE [ADD|DROP] PARTITION atau MSCK.
  • Memuat partisi tunggal: Membaca partisi secara langsung tidak diperlukan. Misalnya, Anda tidak perlu menjalankan spark.read.format("parquet").load("/data/date=2017-01-01"). Sebagai gantinya, gunakan klausul WHERE untuk melewatkan data, seperti spark.read.table("<table-name>").where("date = '2017-01-01'").
  • Jangan memodifikasi data secara manual: Delta Lake menggunakan log transaksi untuk melakukan perubahan secara atomik ke tabel. Jangan langsung mengubah, menambahkan, atau menghapus file data Parquet dalam tabel Delta karena dapat menyebabkan kehilangan data atau kerusakan tabel.

Meningkatkan performa untuk penggabungan Delta Lake

Anda dapat mengurangi waktu yang diperlukan untuk menggabungkan dengan menggunakan pendekatan berikut:

  • Mengurangi ruang pencarian kecocokan: Secara default, operasi merge mencari seluruh tabel Delta untuk menemukan kecocokan di tabel sumber. Salah satu cara untuk mempercepat merge adalah dengan mengurangi ruang pencarian dengan menambahkan batasan yang diketahui dalam kondisi pencocokan. Misalnya, Anda memiliki tabel yang dipartisi oleh country dan date, dan Anda ingin menggunakan merge untuk memperbarui informasi satu hari terakhir dan negara tertentu. Menambahkan kondisi berikut membuat kueri lebih cepat, karena hanya mencari kecocokan di partisi yang relevan:

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

    Selain itu, kueri ini juga mengurangi kemungkinan konflik dengan operasi bersamaan lainnya. Lihat Tingkat isolasi dan tulis konflik di Azure Databricks untuk detail selengkapnya.

  • File ringkas: Jika data disimpan dalam banyak file kecil, proses membaca data untuk mencari kecocokan bisa menjadi lambat. Anda dapat meringkas file berukuran kecil ke dalam file yang berukuran lebih besar untuk meningkatkan throughput baca. Lihat Memampatkan file data dengan pengoptimalan di Delta Lake untuk detailnya.

  • Mengontrol partisi acak untuk menulis: Operasi merge mengacak data beberapa kali untuk melakukan komputasi dan menulis data yang telah diperbarui. Jumlah tugas yang digunakan untuk mengacak dikontrol oleh konfigurasi spark.sql.shuffle.partitions sesi Spark. Mengatur parameter ini tidak hanya mengontrol paralelisme, tetapi juga menentukan jumlah file output. Meningkatkan nilai turut meningkatkan paralelisme, tetapi juga menghasilkan sejumlah besar file data yang lebih kecil.

  • Mengaktifkan penulisan yang dioptimalkan: Untuk tabel yang dipartisi, merge dapat menghasilkan jumlah file kecil yang jauh lebih besar daripada jumlah partisi acak. Hal ini terjadi karena setiap tugas acak dapat menulis beberapa file di beberapa partisi, dan dapat menjadi penyempitan performa. Anda dapat mengurangi jumlah file dengan mengaktifkan penulisan yang dioptimalkan. Lihat Penulisan yang dioptimalkan untuk Delta Lake di Azure Databricks.

  • Menyetel ukuran file dalam tabel: Azure Databricks dapat secara otomatis mendeteksi apakah tabel Delta sering merge memiliki operasi yang menulis ulang file dan dapat memilih untuk mengurangi ukuran file yang ditulis ulang untuk mengantisipasi penulisan ulang file lebih lanjut di masa mendatang. Lihat bagian mengenai penyetelan ukuran file untuk detailnya.

  • Penggabungan Acak Rendah: Penggabungan Acak Rendah menyediakan implementasi MERGE yang dioptimalkan yang memberikan performa yang lebih baik untuk sebagian besar beban kerja umum. Selain itu, penggabungan dengan tingkat acak yang rendah mempertahankan pengoptimalan tata letak data yang sudah ada seperti pengurutan Z pada data yang tidak dimodifikasi.

Mengelola kebaruan data

Di awal setiap kueri, Delta memperbarui secara otomatis ke versi tabel terbaru. Proses ini dapat diamati di notebook saat status perintah melaporkan: Updating the Delta table's state. Namun, saat menjalankan analisis historis pada tabel, Anda mungkin tidak memerlukan data terbaru, terutama untuk tabel di mana data streaming sering dicerna. Dalam kasus ini, kueri dapat dijalankan pada snapshot kedaluwarsa dari tabel Delta Anda. Hal ini dapat menurunkan latensi dalam mendapatkan hasil dari kueri.

Anda dapat mengonfigurasi toleransi untuk data kedaluarsa dengan mengatur konfigurasi spark.databricks.delta.stalenessLimit sesi Spark dengan nilai string waktu seperti 1h atau 15m (masing-masing selama 1 jam atau 15 menit). Konfigurasi ini spesifik untuk sesi, dan tidak memengaruhi klien lain yang mengakses tabel. Jika status tabel telah diperbarui dalam batas keusangan, kueri terhadap tabel mengembalikan hasil tanpa menunggu pembaruan tabel terbaru. Pengaturan ini tidak pernah mencegah tabel Anda diperbarui, dan ketika data kedaluarsa dikembalikan, pembaruan akan diproses di latar belakang. Jika pembaruan tabel terakhir lebih lama dari batas keusangan, kueri tidak mengembalikan hasil hingga pembaruan status tabel selesai.

Titik pemeriksaan yang disempurnakan untuk kueri latensi rendah

Delta Lake menulis titik pemeriksaan sebagai status agregat tabel Delta di frekuensi yang dioptimalkan. Titik pemeriksaan ini berfungsi sebagai titik awal untuk mengkomputasi status tabel terbaru. Tanpa titik pemeriksaan, Delta Lake harus membaca banyak koleksi file JSON (file "delta") yang mewakili penerapan ke log transaksi untuk mengkomputasi status tabel. Selain itu, statistik tingkat kolom yang digunakan Delta Lake untuk melakukan melewatkan data disimpan di titik pemeriksaan.

Penting

Titik pemeriksaan Delta Lake berbeda dari titik pemeriksaan Streaming Terstruktur.

Statistik tingkat kolom disimpan sebagai struct dan JSON (untuk kompatibilitas mundur). Format struktur membuat Delta Lake membaca lebih cepat, karena:

  • Delta Lake tidak melakukan penguraian JSON yang mahal untuk memperoleh statistik tingkat kolom.
  • Kemampuan pemangkasan kolom parket secara signifikan mengurangi I/O yang diperlukan untuk membaca statistik untuk kolom.

Format struktur memungkinkan kumpulan pengoptimalan yang mengurangi overhead operasi baca Delta Lake dari detik menjadi puluhan milidetik, yang secara signifikan mengurangi latensi untuk kueri pendek.

Mengelola statistik tingkat kolom di titik pemeriksaan

Anda mengelola bagaimana statistik ditulis di titil pemeriksaan menggunakan properti tabel delta.checkpoint.writeStatsAsJson dan delta.checkpoint.writeStatsAsStruct. Jika kedua properti tabel adalah false, Delta Lake tidak dapat melakukan proses melewatkan data.

  • Penulisan batch menulis statistik dalam kedua format JSON dan struktur. delta.checkpoint.writeStatsAsJson adalah true.
  • delta.checkpoint.writeStatsAsStruct tidak didefinisikan secara default.
  • Pembaca menggunakan kolom struktur bila tersedia dan sebaliknya kembali menggunakan kolom JSON.

Penting

Titik pemeriksaan yang ditingkatkan tidak merusak kompatibilitas dengan pembaca Delta Lake sumber terbuka. Namun, pengaturan delta.checkpoint.writeStatsAsJson ke false mungkin memiliki implikasi pada pembaca Delta Lake yang eksklusif. Hubungi vendor Anda untuk mempelajari lebih lanjut tentang implikasi kinerja.

Mengaktifkan titik pemeriksaan yang ditingkatkan untuk kueri Streaming Terstruktur

Jika beban kerja Streaming Terstruktur tidak memiliki persyaratan latensi rendah (latensi submenit), Anda bisa mengaktifkan pemeriksaan yang disempurnakan dengan menjalankan perintah SQL berikut ini:

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

Anda juga dapat meningkatkan latensi tulis titik pemeriksaan dengan mengatur properti tabel berikut:

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

Jika melewatkan data tidak berguna dalam aplikasi Anda, Anda dapat mengatur kedua properti ke false. Kemudian tidak ada statistik yang dikumpulkan atau ditulis. Databricks tidak merekomendasikan konfigurasi ini.