Apache Spark: вплив переділу, сортування та кешування на з'єднання


10

Я вивчаю поведінку Спарка під час приєднання таблиці до себе. Я використовую Databricks.

Мій фіктивний сценарій:

  1. Читання зовнішньої таблиці як фрейму A (основні файли у форматі delta)

  2. Визначте фрейм даних B як кадр даних A із вибраними лише певними стовпцями

  3. З'єднайте фрейми даних A і B у колонці1 та колонці2

(Так, це не має великого сенсу, я просто експериментую, щоб зрозуміти основну механіку Спарка)

a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))

b = a.select("column1", "column2", "columnA")

c= a.join(b, how="left", on = ["column1", "column2"])

Моєю першою спробою було запустити код таким, який він є (спроба 1). Потім я спробував переділити та кешувати (спроба 2)

a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).cache()

Нарешті я перерозподілив, сортував і кеширував

 a = spark.read.table("table") \
.select("column1", "column2", "column3", "column4") \
.withColumn("columnA", lower((concat(col("column4"), lit("_"), col("column5")))))
.repartition(col("column1"), col("column2")).sortWithinPartitions(col("column1"), col("column2")).cache()

Відповідні генеровані даги є такими, що додаються.

Мої запитання:

  1. Чому в спробі 1 таблиця схоже на кешування, навіть якщо кешування не було чітко вказано.

  2. Чому InMemoreTableScan завжди супроводжується іншим вузлом цього типу.

  3. Чому в спробі 3 кешування відбувається на двох етапах?

  4. Чому в спробі 3 WholeStageCodegen слідкує за одним (і єдиним) InMemoreTableScan.

спроба 1

спроба 2

введіть тут опис зображення


Я підозрюю, що зчитувач DataFrame автоматично кешує дані, коли джерелом є зовнішня таблиця. У мене схожа ситуація, коли я читаю дані з таблиці бази даних, а під час завантаження вкладка "SQL" у розділі "Інтерфейс деталей програми" показує мені кількість рядків, які завантажуються, але жоден файл ще не збережений у вказаному місці . Я здогадуюсь, він знає кількість, оскільки він десь кешує дані, і саме це з’являється в DAG. Якщо ви читаєте дані з текстового файлу локально, ви б не бачили стану кешу.
Салим

Відповіді:


4

Те, що ви спостерігаєте в цих 3 планах, - це суміш часу виконання DataBricks та Spark.

Перш за все, під час виконання програми DataBricks 3.3+, кешування автоматично вмикається для всіх файлів паркету. Відповідний конфігурація для цього: spark.databricks.io.cache.enabled true

Для вашого другого запиту InMemoryTableScan відбувається двічі, оскільки праворуч при виклику приєднання іскра намагалася паралельно обчислити набір даних A і набір даних B. Якщо припустити, що різні виконавці отримали вищезазначені завдання, обом доведеться сканувати таблицю з кешу (DataBricks).

По-третє, InMemoryTableScan не посилається на кешування в собі. Це просто означає, що будь-який план каталізатора, що склався, включав сканування кешованої таблиці кілька разів.

PS: Я не можу уявити точку 4 :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.