# Exploring Distributed Deep Learning Inference Using Raspberry Pi Spark Cluster
## 3 Methodology
### Apache Spark: Standalone with HDFS, Cluster Setup & Job Execution  
Spark is a data processing engine designed to replace or complement Hadoop's MapReduce processing engine. The research experiments made use of the latest Spark version \begin{table}
\begin{tabular}{c c c c} \hline \hline
**System** & **CPU** & **Memory (RAM)** & **Storage** & **Operating System** \\ \hline Configuration 1 & Quad-core ARM & 4 GB LPDDR4 & SanDisk 32 GB Class & Raspberry Pi OS \\ (Pi 4B) & Cortex-A72 @ 1.5 GHz & 10 microSD card & 10 64-bit \\ \hline Configuration 2 & 2 \(\times\) (Quad-core ARM & 2 \(\times\) (4 GB LPDDR4) & SanDisk 32 GB Class & Raspberry Pi OS \\ (2-node Pi 4B cluster) & Cortex-A72 @ 1.5 GHz) & 10 microSD card & 10 64-bit \\ \hline Configuration 3 & 2 \(\times\) (2 virtual Ryzen & 2 \(\times\) (4 GB DDR4) & 50 GB & Ubuntu 20.04 LTS \\ (2-node VM cluster) & 5 3500X cores) & 2 \(\times\) (4 GB DDR4) & Virtual hard disk & Ubuntu 20.04 LTS \\ \hline Configuration 4 & AMD Ryzen 5 3500X & 32 GB DDR4 &
\begin{tabular}{c} Corsair MP510 \\ (256 GB) \\ \end{tabular} & Windows 10 \\ \hline \hline \end{tabular}
\end{table} 
Table 4: Systems used in the Experiments. Figure 3: General flowchart for the Python programs used in Experiment 3. (3.2.1) for clustering multiple nodes and for single-node use. Configurations 2 and 3 ran Spark in standalone cluster deployment mode alongside the Hadoop Distributed File System (HDFS) which runs as a background service. As for Hadoop's HDFS, the research experiments made use of Hadoop version 3.3.1. The replication factor for HDFS was set to the number of nodes, which in this case was 2. Much like Hadoop and Spark-on-YARN, a Spark Standalone cluster has a master node in charge of coordinating and distributing all Spark jobs to all workers or working nodes of that cluster. To ease the entry of hostnames as worker nodes into the Spark environment file, the local IP addresses of the nodes for Configurations 2 and 3 were mapped to their respective hostnames in the /etc/hosts file, as these configurations use Linux operating systems, and this process was repeated in every node. As Spark requires Secure Shell (SSH) access, SSH fingerprints in the form of Rivest-Shamir-Adleman (RSA) keys were created on the master node. These keys were then placed in the worker nodes to verify and trust the master node. It is worth noting that a Spark node can be both a master and a worker at the same time. The hostnames of the nodes, which now map to their local IP addresses, were entered into the 'workers' file located under the Spark configuration folder. For checking whether all nodes were configured properly for Spark cluster use, the web UI for Spark was accessed via '(hostname): 8080' in a web browser which displays the status of all nodes, including the master node. For all cluster systems, the following environment variables were set in the.bashrc file, as seen in Figure 4. These environment variables were required by Spark. As Spark is built on Java, using a compatible Java Development Kit (JDK) version was required. During initial testing, newer versions of JDK such as 14 and 17 failed to work, and thus the decision to revert to JDK 11 was made as it is the longest supported stable JDK version compatible with Spark at the time of writing. Since Configuration 2 runs on ARM architecture, an ARM64 version of the JDK developed by the open-source community (OpenJDK) was used in place of the traditional AMD64 architecture found in modern computers, which was also used for Configuration 3. The Spark folder containing all important binaries and configuration files was in the home directory of the user account for each cluster system. For Spark to use Python, 'PYSPARK_PYTHON' would have used the system's default Python version, which was kept exactly at 3.8.10 across every node to prevent compatibility issues.