Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPARK-35181][CORE] Use zstd for spark.io.compression.codec by default #32286

Closed
wants to merge 3 commits into from
Closed

[SPARK-35181][CORE] Use zstd for spark.io.compression.codec by default #32286

wants to merge 3 commits into from

Conversation

dongjoon-hyun
Copy link
Member

@dongjoon-hyun dongjoon-hyun commented Apr 22, 2021

What changes were proposed in this pull request?

This PR aims to use zstd as spark.io.compression.codec instead of lz4 in order to reduce the disk IOs and traffic during shuffle processing and worker decommission storage migration (between executors and to external storage).

  • Since SPARK-29434 and SPARK-29576, Apache Spark 3.0+ uses ZSTD spark.shuffle.mapStatus.compression.codec by default instead of GZIP.
  • Since SPARK-34503, Apache Spark 3.2 uses ZSTD for spark.eventLog.compression.codec by default instead of LZ4.

Why are the changes needed?

To reduce the disk footprint. For TPCDS 3TB case, zstd has 44% less shuffle write size and 43% less shuffle read size
For some cases, the query execution with zstd io is 20% faster than lz4 io.

Does this PR introduce any user-facing change?

No.

How was this patch tested?

Pass the CIs.

@SparkQA
Copy link

SparkQA commented Apr 22, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/42304/

@SparkQA
Copy link

SparkQA commented Apr 22, 2021

Kubernetes integration test status failure
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/42304/

Copy link
Member

@MaxGekk MaxGekk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to reduce the disk IOs and traffic during shuffle

@dongjoon-hyun How about CPU load. If user's job is CPU bound than zstd can introduce perf regression in the case if zstd consumes more CPU.

@SparkQA
Copy link

SparkQA commented Apr 22, 2021

Test build #137777 has finished for PR 32286 at commit b8266fd.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Member

@srowen srowen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems OK for consistency and maybe better speed; we should mention it in a migration guide.

@@ -52,6 +52,8 @@ class AdaptiveQueryExecSuite

import testImplicits._

override protected def sparkConf = super.sparkConf.set("spark.io.compression.codec", "lz4")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be define more like a method with braces, etc or is that how similar code does it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for late reply.

For this one, we can use this simple form like the other places.

$ git grep 'override protected def sparkConf' | grep super
sql/core/src/test/scala/org/apache/spark/sql/AggregateHashMapSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/AggregateHashMapSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/AggregateHashMapSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/connector/FileDataSourceV2FallBackSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf.set(SQLConf.USE_V1_SOURCE_LIST, "")
sql/core/src/test/scala/org/apache/spark/sql/execution/DataSourceScanExecRedactionSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/execution/DataSourceScanExecRedactionSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/execution/DataSourceScanExecRedactionSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/execution/adaptive/AdaptiveQueryExecSuite.scala:  override protected def sparkConf = super.sparkConf.set("spark.io.compression.codec", "lz4")
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/AlterTableRecoverPartitionsSuite.scala:  override protected def sparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v1/AlterTableRecoverPartitionsSuite.scala:  override protected def sparkConf = super.sparkConf
sql/core/src/test/scala/org/apache/spark/sql/execution/datasources/orc/OrcPartitionDiscoverySuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf.set(SQLConf.USE_V1_SOURCE_LIST, "")
sql/core/src/test/scala/org/apache/spark/sql/streaming/StreamSuite.scala:  override protected def sparkConf: SparkConf = super.sparkConf

Or, like the following~

  override protected def sparkConf: SparkConf =
    super
      .sparkConf
      .set(SQLConf.USE_V1_SOURCE_LIST, "parquet")

@SparkQA
Copy link

SparkQA commented May 9, 2021

Kubernetes integration test unable to build dist.

exiting with code: 1
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/42828/

@SparkQA
Copy link

SparkQA commented May 9, 2021

Test build #138306 has finished for PR 32286 at commit e89681b.

  • This patch fails PySpark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@viirya
Copy link
Member

viirya commented May 9, 2021

retest this please

@SparkQA
Copy link

SparkQA commented May 9, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/42830/

@SparkQA
Copy link

SparkQA commented May 9, 2021

Kubernetes integration test status failure
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/42830/

@SparkQA
Copy link

SparkQA commented May 9, 2021

Test build #138308 has finished for PR 32286 at commit e89681b.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@LucaCanali
Copy link
Contributor

LucaCanali commented May 21, 2021

I have tested this with a few runs of TPCDS query q64 that is shuffle-intensive. I see indeed a very inportant reduction of shuffle write and read bytes (about -40% as reported by @dongjoon-hyun). Also shuffleWriteTime and shuffleFetchWaitTime are improved (about -25% and a -75%) in my test.
I also measured an increase of CPU usage though, of about 10% in my test. (note q64 used for this test performed using TPCDS scale 1500 and spark 3.2.0-SNAPSHOT from master 20210510, reads 473 GB of shuffle data when using lz4, which is compressed to 290 GB with zstd. I would imagine the CPU overhead to be proportional to the amount of shuffle data that is compressed/decompressed).
Overall the query execution time in my setup/test was basically unchanged, considering the test measurement noise.
It still seems worth doing this, because of the large improvement on the shuffle footprint, however the increase of CPU usage should be noted as pointed out by @MaxGekk

Copy link
Member

@srowen srowen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is probably good idea, to trade a little more CPU for less I/O and storage. @dongjoon-hyun I'm a little concerned about changing a fairly fundamental default. Would you put this in 3.2.0? not out of the question IMHO just needs to be in a migration guide I think, and maybe worth one more ping to dev@ to solicit input.

@dongjoon-hyun
Copy link
Member Author

Thank you for your feedbacks, @LucaCanali and @srowen .

@SparkQA
Copy link

SparkQA commented Jun 17, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44473/

@SparkQA
Copy link

SparkQA commented Jun 17, 2021

Kubernetes integration test status success
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44473/

@SparkQA
Copy link

SparkQA commented Jun 17, 2021

Test build #139946 has finished for PR 32286 at commit a5d26a0.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44581/

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Kubernetes integration test status success
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44581/

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Test build #140053 has finished for PR 32286 at commit ee50d33.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44609/

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Kubernetes integration test status failure
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44609/

@SparkQA
Copy link

SparkQA commented Jun 21, 2021

Test build #140081 has finished for PR 32286 at commit 0a745b8.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@mridulm mridulm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor queries, I like the change.

@@ -66,6 +66,7 @@ class CoalesceShufflePartitionsSuite extends SparkFunSuite with BeforeAndAfterAl
.setAppName("test")
.set(UI_ENABLED, false)
.set(IO_ENCRYPTION_ENABLED, enableIOEncryption)
.set(IO_COMPRESSION_CODEC.key, "lz4")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, does this test require it to be lz4 ?
Same for AdaptiveQueryExecSuite below - why not rely on the new default value of zstd ?

@dongjoon-hyun
Copy link
Member Author

Thank you for review, @mridulm . The change is required because the UT depends on the results based on the intermediate statistics of the query.

@mridulm
Copy link
Contributor

mridulm commented Jun 27, 2021

Thanks for clarifying @dongjoon-hyun !
I am guessing this is use of spark.sql.adaptive.advisoryPartitionSizeInBytes ?
Sounds good to continue using lz4 to preserve current behavior.
We can always modify the test in a later PR to adapt targetPostShuffleInputSize for the new codec.

@dongjoon-hyun
Copy link
Member Author

Thank you. Sure, @mridulm .

This PR aims to use `zstd` as `spark.io.compression.codec` instead of `lz4` in order to reduce the disk IOs and traffic during shuffle processing and  worker decommission storage migration (between executors and to external storage).

- Since SPARK-29434 and SPARK-29576, Apache Spark 3.0+ uses ZSTD MapOutputStatus Ser/Deser instead of `GZIP`.
- Since SPARK-34503, Apache Spark 3.2 uses ZSTD for `spark.eventLog.compression.codec` by default.

**BEFORE**

**AFTER**
@mridulm
Copy link
Contributor

mridulm commented Jun 28, 2021

Looks good to me (pending other reviews comments ofcourse).
Why is this still draft btw ? Are we still testing this or waiting for other feedback/eval ?

@dongjoon-hyun
Copy link
Member Author

Thank you for your comments, @mridulm . I'm looking at the stability of GitHub Action.
As you know, recently, ZStandard 1.5.0 landed at master branch and it seems to increase the memory usage and causes GitHub Action UT failures.

@SparkQA
Copy link

SparkQA commented Jun 29, 2021

Test build #140387 has started for PR 32286 at commit 70cb336.

@SparkQA
Copy link

SparkQA commented Jun 30, 2021

Kubernetes integration test unable to build dist.

exiting with code: 1
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/44910/

@SparkQA
Copy link

SparkQA commented Jul 2, 2021

Test build #140554 has finished for PR 32286 at commit 15c5818.

  • This patch fails to build.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented Jul 2, 2021

Kubernetes integration test starting
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/45066/

@SparkQA
Copy link

SparkQA commented Jul 2, 2021

Kubernetes integration test status success
URL: https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder-K8s/45066/

@github-actions
Copy link

We're closing this PR because it hasn't been updated in a while. This isn't a judgement on the merit of the PR in any way. It's just a way of keeping the PR queue manageable.
If you'd like to revive this PR, please reopen it and ask a committer to remove the Stale tag!

@github-actions github-actions bot added the Stale label Oct 12, 2021
@github-actions github-actions bot closed this Oct 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants