Does Spark hold DataFrame in memory when loaded from a file? - apache-spark

If I create a Dataframe like so:
val usersDF = spark.read.csv("examples/src/main/resources/users.csv")
Does spark actually load (/copy) the data (from the csv file) into memory, or into the underlying filesystem as a distributed dataset?
I ask because after loading the df, any change in the underlying file's data is not reflecting in queries against the dataframe. (Unless ofcourse the dataframe is again freshly loaded by invoking the above line of code.
I am using interactive queries on Databricks notebooks.

Unless until you perform an action on that file, the file doesn't gets loaded into memory and you will see all the contents of the file till the time it is loaded into memory when an action occurs in the execution plan.
And if an action has already been taken on the file during which any modification has been done to the file, then you will see the cached result of the first execution if it is able to fit in MEMORY.

Related

Spark is throwing FileNotFoundException while accessing cached table

There is a table which I read early in the script, but it will fail during run if the underlying table changes in a partition I read in e.g.:
java.io.FileNotFoundException: File does not exist:
hdfs://R2/projects/.../country=AB/date=2021-08-20/part-00005e4-4fa5-aab4-93f02feaf746.c000
Even when I specifically cache the table, and do an action, the script will still fail down the line if the above happens.
df.cache()
df.show(1)
My question is, how is this possible?
If I cache the data on memory/disk, why does it matter if the underlying file is updated or not?
Edit: the code is very long, the main thing:
df= read in table, whose underlying data is in the above HDFS folder
df. cache() and df.show() immediately after it, since Spark evaluates lazily. With show() I make the caching happening
Later when I refer to df: if underlying data is changed, script will fail with java.io.FileNotFoundException:
new_df= df.join(
other_df, 'id', 'right')
As discussed in comment section, Spark will automatically evict the cached data based on LRU(Lease Recently Utilized) concept whenever it encounters out of memory issue.
In your case spark might have evicted the cached table. If there is no cached data then previous lineage will be used to form the dataframe again and it will throw an error if the underlying file is missing.
You can try increasing the memory or use storage level as DISK_ONLY.
df.persist(StorageLevel.DISK_ONLY)

How to ensure that loading of Spark DataFrame from Parquet is distributed and parallelized?

When Spark loads source data from a file into a DataFrame, what factors govern whether the data are loaded fully into memory on a single node (most likely the driver/master node) or in the minimal, parallel subsets needed for computation (presumably on the worker/executor nodes)?
In particular, if using Parquet as the input format and loading via the Spark DataFrame API, what considerations are necessary in order to ensure that loading from the Parquet file is parallelized and deferred to the executors, and limited in scope to the columns needed by the computation on the executor node in question?
(I am looking to understand the mechanism Spark uses to schedule loading of source data in the distributed execution plan, in order to avoid exhausting memory on any one node by loading the full data set.)
As long as you use spark operations, all data transformations and aggregations are perfored only on executors. Therefore there is no need for driver to load the data, its job is to manage processing flow. Driver gets the data only in case you use some terminal operations, like collect(), first(), show(), toPandas(), toLocalIterator() and similar. Additionally, executors does not load all files content into memory, but gets the smallest posible chunks (which are called partitions).
If you use column store format such as Parquet only columns required for the execution plan are loaded - this is default behaviour in spark.
Edit: I just saw that there might be a bug in spark and if you use nested columns inside your schema then unnecessary columns may be loaded, see: Why does Apache Spark read unnecessary Parquet columns within nested structures?

Spark RDDs are stored in blocks or stored in memory ? Few queries around Spark

Have few questions around Spark RDD. Can someone enlighten me please.
I could see that RDDs are distributed across nodes, does that mean the
distributed RDD are cached in memory of each node or will that RDD data
reside on the hdfs disk. Or Only when any application runs the RDD data get
cached in memory ?
My understanding is, when I create a RDD based on a file which is present
on hdfs blocks , the RDD will first time read the data (I/O operation ) from
the blocks and then cache it persistently. Atleast one time it has to the
read the data from disk, Is that true ???
Is there any way if i can cache the external data directly into RDD instead
of storing the data first in hdfs and then load into RDD from hdfs blocks ?
The intention here is storing data first into hdfs and then loading it into
in memory will present latency ??
Rdd's are data structures similar to arrays and lists. When you create an RDD (example: loading a file ) if it is in the local mode it is stored in the laptop. If you are using hdfs it is stored in hdfs. Remember ON DISK.
If you want to store it in the cache (in RAM), you can use the cache() function.
Hope you got the answer for the second question too from the first one .
Yes you can directly load the data from your laptop without loading it into hdfs.
val newfile = sc.textFile("file:///home/user/sample.txt")
Specify the file path.
By default spark takes hdfs as storage u can change it by using the above line.
Dont forget to put the three ///:
file:///

Save to distributed file system from worker processes

I am quite new with pyspark. In my application with pyspark, I want to achieve following things:
Create a RDD using python list and partition it into some partitions.
Now use rdd.mapPartitions(func)
Here, the function "func" performs an iterative operation which, reads content of saved file into a local variable (for e.g. numpy array), performs some updates using the rdd partion data and again saves the content of variable to some common file system.
I am not able to figure out how to read and write a variable inside a worker process which is accessible to all processes??

Spark JavaPairRDD behaviour when file gets updated

I have one use case where I am joining data between one file and stream data.
For this purpose I read the data in file as JavaPairRDD and cache it.
But the catch is that the file is going to be updated periodically in 3-4 hours.
Now my doubt is do I have to read the file again and re create the JavaPairRDDs to reflect the changes in file or is it taken care of by Spark already i.e. whenever the file gets updated are the RDDs recreated ?
RDD's in Spark are designed to be immutable, if the underlying data changes the values in the RDD will not change unless it is uncached/unpersisted/uncheckpointed. In general Spark assumes that the backing data for an RDD doesn't change, so you would likely be better of instead creating a new RDD (or treating both as streams).

Resources