PySpark Shared Variables
In PySpark, shared variables allow multiple tasks to share data efficiently on each worker node while processing a job. PySpark has two types of shared variables: Broadcast variables and Accumulators.
Broadcast Variables
In PySpark RDD and DataFrame, Broadcast variables are read-only shared variables that are cached and available on all nodes in a cluster to be accessed or used by tasks. Instead of sending this data along with every task, Spark distributes broadcast variables to machines using efficient broadcast algorithms to reduce communication costs.
Use case
Let's assume you are getting a two-letter country state code in a file and you want to transform it to a full state name (for example, CA to California, NY to New York, etc.) by doing a lookup to a reference mapping. In some instances, this data could be large and you may have many such lookups (like zip code).
Instead of distributing this information along with each task over the network (overhead and time-consuming), we can use the broadcast variable to cache this lookup info on each machine, and tasks use this cached info while executing the transformations.
How does Spark Broadcast work?
Broadcast variables are used the same way for RDD, DataFrame, and Dataset. In this lesson, I will primarily focus on RDD.
When you run a Spark RDD job that has Broadcast variables defined and used, Spark does the following:
- Spark breaks the job into stages that have distributed shuffling, and actions are executed within the stage.
- Later stages are also broken into tasks.
- Spark broadcasts the common data (reusable) needed by tasks within each stage.
- The broadcasted data is cached in serialized format and deserialized before executing each task.
You should be creating and using broadcast variables for data that is shared across multiple stages and tasks.
Creating Broadcast variable
The PySpark Broadcast is created using the broadcast(v) method of the SparkContext class. This method takes the argument v that you want to broadcast.
In PySpark
from pyspark.sql import SparkSession
# Create SparkSession
spark = SparkSession.builder.appName("AIStudyLabs.com").master("local").getOrCreate()
# Example array to broadcast
broadcastVar = spark.sparkContext.broadcast([0, 1, 2, 3])
print(broadcastVar.value)
Note that broadcast variables are not sent to executors when you call the sparkContext.broadcast(variable) statement, but they will be sent to executors when they are first used.
PySpark RDD Broadcast Variable Example
Below is a very simple example of how to use broadcast variables on RDD. This example defines commonly used data (country and states) in a dictionary variable, distributes the variable using SparkContext.broadcast(), and then uses these variables in an RDD map() transformation.
from pyspark.sql import SparkSession
# Create SparkSession
spark = SparkSession.builder.appName("AIStudyLabs.com").master("local").getOrCreate()
states = {"NY": "New York", "CA": "California", "FL": "Florida"}
countries = {"USA": "United States of America", "IN": "India"}
# Create broadcast variable
broadcastStates = spark.sparkContext.broadcast(states)
broadcastCountries = spark.sparkContext.broadcast(countries)
# Create RDD
data = [("James", "Smith", "USA", "CA"), ("Michael", "Rose", "USA", "NY"),
("Robert", "Williams", "USA", "CA"), ("Maria", "Jones", "USA", "FL")]
rdd = spark.sparkContext.parallelize(data)
# RDD Transformation
rdd2 = rdd.map(lambda f: (
f[0],
f[1],
broadcastCountries.value.get(f[2]),
broadcastStates.value.get(f[3])
))
# Collect and print RDD
print(rdd2.collect())
