Apache Spark: tác động của việc phân vùng lại, sắp xếp và lưu vào bộ nhớ cache khi tham gia


10

Tôi đang khám phá hành vi của Spark khi tham gia một bảng vào chính nó. Tôi đang sử dụng Databricks.

Kịch bản giả của tôi là:

  1. Đọc bảng bên ngoài dưới dạng dataframe A (các tệp cơ bản ở định dạng delta)

  2. Xác định khung dữ liệu B là khung dữ liệu A chỉ với một số cột nhất định được chọn

  3. Tham gia dataframes A và B trên cột1 và cột2

(Vâng, nó không có ý nghĩa nhiều lắm. Tôi chỉ đang thử nghiệm để hiểu cơ chế cơ bản của Spark)

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"])

Nỗ lực đầu tiên của tôi là chạy mã như vậy (lần 1). Sau đó tôi đã cố gắng phân vùng lại và bộ đệm (cố gắng 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()

Cuối cùng, tôi đã phân vùng lại, sắp xếp và lưu trữ

 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()

Các dags tương ứng được tạo ra như được đính kèm.

Câu hỏi của tôi là:

  1. Tại sao trong lần thử 1, bảng dường như được lưu vào bộ đệm ngay cả khi bộ đệm không được chỉ định rõ ràng.

  2. Tại sao InMemoreTableScan luôn được theo sau bởi một nút khác thuộc loại này.

  3. Tại sao trong nỗ lực 3 bộ nhớ đệm dường như diễn ra trên hai giai đoạn?

  4. Tại sao trong nỗ lực 3 WholeStageCodegen theo sau một (và chỉ một) InMemoreTableScan.

cố gắng 1

cố gắng 2

nhập mô tả hình ảnh ở đây


Tôi nghi ngờ rằng trình đọc DataFrame tự động lưu trữ dữ liệu khi nguồn là một bảng bên ngoài. Tôi có tình huống tương tự khi tôi đang đọc dữ liệu từ bảng cơ sở dữ liệu, trong khi có thể đang được tải xuống tab "SQL" trên 'UI Chi tiết ứng dụng' hiển thị cho tôi số lượng hàng được tải xuống nhưng chưa có tệp nào được lưu tại vị trí được chỉ định . Tôi đoán nó biết số đếm vì nó đã lưu trữ dữ liệu ở đâu đó và đó là những gì xuất hiện trên DAG. Nếu bạn đọc dữ liệu từ tệp văn bản cục bộ thì bạn sẽ không thấy trạng thái bộ đệm.
Salim

Câu trả lời:


4

Những gì bạn đang quan sát trong 3 kế hoạch này là sự pha trộn giữa thời gian chạy DataBricks và Spark.

Trước hết, trong khi chạy DataBricks runtime 3.3+, bộ đệm được tự động kích hoạt cho tất cả các tệp sàn. Cấu hình tương ứng cho điều đó: spark.databricks.io.cache.enabled true

Đối với truy vấn thứ hai của bạn, InMemoryTableScan đang xảy ra hai lần vì ngay khi tham gia được gọi, spark đã cố gắng tính toán Dataset A và Dataset B song song. Giả sử các trình thực thi khác nhau đã được chỉ định các tác vụ trên, cả hai sẽ phải quét bảng từ bộ đệm (DataBricks).

Đối với cái thứ ba, InMemoryTableScan không đề cập đến chính bộ nhớ đệm. Nó chỉ có nghĩa là bất cứ chất xúc tác kế hoạch nào được hình thành đều liên quan đến việc quét bảng được lưu trữ nhiều lần.

Tái bút: Tôi không thể hình dung được điểm 4 :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.