Data skew happens when some parts of your data are much bigger than others. This can slow down your processing. Handling data skew helps your big data jobs run faster and smoother.
Handling data skew at scale in Apache Spark
spark.conf.set("spark.sql.shuffle.partitions", number_of_partitions) # Example of salting keys to reduce skew from pyspark.sql.functions import concat, lit, floor, rand # Add a salt column with random number salted_df = df.withColumn("salt", floor(rand() * salt_range)) # Modify join key by adding salt salted_df = salted_df.withColumn("salted_key", concat(salted_df["key"], lit("_"), salted_df["salt"]))
Setting shuffle partitions controls how many pieces data is split into during shuffle.
Salting means adding a random number to keys to spread out big groups.
spark.conf.set("spark.sql.shuffle.partitions", 200)
from pyspark.sql.functions import concat, lit, floor, rand salt_range = 10 salted_df = df.withColumn("salt", floor(rand() * salt_range)) salted_df = salted_df.withColumn("salted_key", concat(salted_df["key"], lit("_"), salted_df["salt"]))
# Group using salted keys grouped_df = salted_df.groupBy("salted_key").count()
This program creates a small dataset with one very common key 'A' and two rare keys 'B' and 'C'. It shows counts before and after adding a salt to the keys to spread out the skew.
from pyspark.sql import SparkSession from pyspark.sql.functions import concat, lit, floor, rand spark = SparkSession.builder.appName("DataSkewHandling").getOrCreate() # Create example data with skewed keys keys = ["A"] * 1000 + ["B"] * 10 + ["C"] * 10 values = list(range(1020)) data = list(zip(keys, values)) df = spark.createDataFrame(data, ["key", "value"]) # Show count per key before handling skew print("Counts before handling skew:") df.groupBy("key").count().show() # Add salt to spread out skewed key 'A' salt_range = 5 salted_df = df.withColumn("salt", floor(rand() * salt_range)) salted_df = salted_df.withColumn("salted_key", concat(salted_df["key"], lit("_"), salted_df["salt"])) # Show count per salted_key print("Counts after salting keys:") salted_df.groupBy("salted_key").count().orderBy("salted_key").show() spark.stop()
Salting works well when one key is very large but others are small.
Too many partitions can cause overhead, too few can cause skew.
Always check your data distribution before and after applying skew handling.
Data skew slows down big data jobs by making some tasks very large.
Salting keys spreads out large groups to balance work.
Adjust shuffle partitions to control parallelism and reduce skew impact.
Practice
Solution
Step 1: Understand data skew impact
Data skew means some keys have many more records, causing uneven task sizes.Step 2: Identify effect on tasks
Tasks processing large keys take longer, slowing the whole job.Final Answer:
Some tasks become much larger and slower than others -> Option AQuick Check:
Data skew = uneven task sizes [OK]
- Thinking all tasks run equally fast
- Believing Spark fixes skew automatically
- Confusing data loss with skew
user_id in PySpark?Solution
Step 1: Understand salting technique
Salting adds a random value to the key to spread data across partitions.Step 2: Check correct syntax for salting
Concatenatinguser_idwith a random number as string is correct.Final Answer:
df.withColumn('salted_key', concat(col('user_id'), lit('_'), rand())) -> Option AQuick Check:
Salting = concat key + random [OK]
- Adding random float directly to string key
- Casting key without salting
- Using substring instead of salting
salted_df if df has 1000 rows?from pyspark.sql.functions import col, concat, lit, rand
salted_df = df.withColumn('salted_key', concat(col('key'), lit('_'), (rand() * 10).cast('int')))
count = salted_df.count()Solution
Step 1: Understand salting effect on row count
Salting adds a new column but does not change the number of rows.Step 2: Count rows after salting
The count remains the same as original DataFrame, 1000 rows.Final Answer:
1000 -> Option BQuick Check:
Salting adds column, count unchanged [OK]
- Thinking salting duplicates rows
- Confusing salt range with row count
- Assuming count changes after withColumn
df1_salted = df1.withColumn('salt', (rand() * 5).cast('int'))
df2_salted = df2.withColumn('salt', (rand() * 5).cast('int'))
joined = df1_salted.join(df2_salted, ['key', 'salt'])Solution
Step 1: Understand salting for joins
To fix skew, salt both DataFrames on join key with same salt range.Step 2: Verify join condition
Joining on both original key and salt column ensures balanced partitions.Final Answer:
Correct: salting both sides and joining on key and salt -> Option DQuick Check:
Salt both sides + join on key & salt [OK]
- Salting only one DataFrame
- Joining without salt column
- Using fixed salt value instead of random
Solution
Step 1: Apply salting to spread skewed key
Adding a salt column with random values breaks large groups into smaller ones.Step 2: Adjust shuffle partitions to increase parallelism
Increasing shuffle partitions allows more tasks to run in parallel, reducing bottlenecks.Step 3: Combine salting and partition tuning
Both salting and increasing partitions together balance load and improve job speed.Final Answer:
Add a salt column with random values, join on salted keys, and increase shuffle partitions -> Option CQuick Check:
Salt + more partitions = balanced load [OK]
- Keeping shuffle partitions too low after salting
- Not salting and only increasing partitions
- Using fixed salt value causing no skew fix
Ready to prove it?
Pass the test and this pattern moves unknown
