<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>spark on Digi Hunch</title><link>https://static.digihunch.com/tag/spark/</link><description>Recent content in spark on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Sat, 20 Jul 2024 16:54:46 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/spark/index.xml" rel="self" type="application/rss+xml"/><item><title>High Performance Computing</title><link>https://static.digihunch.com/2020/12/high-performance-computing-cluster/</link><pubDate>Fri, 11 Dec 2020 23:42:00 -0400</pubDate><guid>https://static.digihunch.com/2020/12/high-performance-computing-cluster/</guid><description>&lt;h3 class="wp-block-heading" id="h-overview"&gt;Overview&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;High Performance Computing (HPC) has recently been commoditized with the advent of commodity server hardware (x86 server), virtualization technology and cloud delivery model. It is common in specialized industries where intensive computing tasks are required, for example:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;HCL (healthcare and life science): drug discovery, computer aided diagnosis (CAD), genome engineering; &lt;/li&gt;&#10;&lt;li&gt;CAD, CAE, CAM (computer aided design, engineering, and manufacturing): 3D modeling, computational fluid dynamics (CFD), finite element analysis (FEA), structural mechanical design, etc &lt;/li&gt;&#10;&lt;li&gt;Finance: portfolio management, automated trading, risk analysis&lt;/li&gt;&#10;&lt;li&gt;Geoscience and geo-engineering: oil and gas exploration, geographic data, weather forecasting;&lt;/li&gt;&#10;&lt;li&gt;Scientific computation&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Computing performance is measured in FLOPS (floating point operations per second) and is usually delivered in a cluster to aggregate the computing power from a number of networked nodes. This is referred to as an HPC cluster. &lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-hardware-stack"&gt;Hardware stack&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;An HPC cluster features the following components:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Head node (aka master node or login node): a gateway and coordinator; head node may be broken into several nodes&lt;/li&gt;&#10;&lt;li&gt;Compute node (worker node): the executor of jobs; the compute node can either be homogenous or heterogeneous, for different purposes. the number of compute nodes can be quite large&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are four common form factors for server: tower, rack-mount, blade, mainframe. Traditionally, the nodes are rack-mount 1U &amp;#8220;pizza box&amp;#8221; servers. Bladed systems started to replace due to the increased node density, thanks to the shared/redundant power and cooling management. In the past, the HPC cluster is operated in data centres, which is an expensive operation item. In the last decades, many organizations extends their compute workload to the cloud, forming a hybrid model.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;HPC typically has specialized storage system because HPC applications notoriously create large amounts of data. NFS traditionally does not scale well as number of node increases. Some proprietary storage system such as Isilon provides good performance via NFS protocol. There are also open-source parallel file system such as Lustre and HDFS. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;HPC networking handles three types of traffic:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;computation traffic between compute nodes (if the compute nodes interact with each other)&lt;/li&gt;&#10;&lt;li&gt;file system traffic: for compute nodes to read and write on file system (e.g. NFS)&lt;/li&gt;&#10;&lt;li&gt;administrative traffic: fairly light compared to the two above&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For that, many HPC runs two networks, a private (backend) network and a public (frontend) network. Backend network must be high speed and low latency, typically in the form of 10Gig Ethernet, or InfiniBand.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-software-stack"&gt;Software stack&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On the software layer, the core functionality is &amp;nbsp;&lt;strong&gt;Message Passing Interface (MPI)&lt;/strong&gt;, a specification for the developers and users of message passing libraries. MPI constitutes a standardized and portable message-passing system which consists of a library and a protocol to support parallel computing. MPI enables passing information between various nodes of a HPC cluster or between particular clusters, and has different implementations that provide the libraries to run HPC applications in a distributed manner across different physical nodes.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the operation, user submits a job through head node in order to request the resource. User needs to specify the resources for the job (e.g. how many CPU cores, how much memory, etc). The head node runs a scheduler to allocate computing resource based on pre-defined policies, based on priority of jobs, availability of resources, distribution of load, etc. Depending on the nature of the computing jobs, the nodes participating in the task may or may not communicate with one another. If they do need to talk to each other, the program must support it. Such program can be called a cluster program, and the MPI (message passing interface) library greatly facilitates the development of such program. The sub-jobs communicating with each other also creates a considerable amount of network traffic within the cluster.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Cluster software ties all nodes in the cluster together. It turns raw hardware into a functioning cluster by provisioning (installing and configuring) the head nodes. Compute nodes can usually be added or removed dynamically therefore the head nodes should be able to provision compute nodes, and administer cluster, leaving the programming as the job for the user to complete. As mentioned, in parallel programming, the most important HPC tool is MPI (Message Passing Interface), which allows programs to talk to one another over cluster networks. There are both open (e.g. &lt;a href="https://www.open-mpi.org/" class="rank-math-link"&gt;Open MPI&lt;/a&gt;) and commercial MPI (e.g. &lt;a href="https://docs.microsoft.com/en-us/message-passing-interface/microsoft-mpi" class="rank-math-link"&gt;Microsoft MPI&lt;/a&gt;) versions. Cluster software should also provide compilers, debuggers, and profilers in addition to MPI.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are cluster software in both Linux and Windows operating systems: &lt;a href="http://www.rocksclusters.org/" class="rank-math-link"&gt;Rocks Clusters&lt;/a&gt;, &lt;a href="https://oscar-cluster.github.io/oscar/" class="rank-math-link"&gt;Oscar &lt;/a&gt;(Open Source Clusters Application Resources), Red Hat HPC solution, &lt;a href="https://docs.microsoft.com/en-us/powershell/high-performance-computing/overview?view=hpc19-ps" class="rank-math-link"&gt;Microsoft HPC pack&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/parallelcluster/latest/ug/what-is-aws-parallelcluster.html" class="rank-math-link"&gt;AWS Parallel Cluster&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-implementation"&gt;Implementation&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a class="rank-math-link" href="https://www.webmo.net/support/pdf/byoc.pdf"&gt;Here&lt;/a&gt; is an example of setting up HPC cluster with CentOS. Despite of the well documented steps, note that the author of the document refers to HPC cluster simply as cluster, which is ambiguous. There are&lt;strong&gt; three basic motivators for creating a cluster&lt;/strong&gt;: high performance computing (HPC), network traffic load balancing, and service resilience in the form of high availability (HA). The author should be specific in the &lt;a class="rank-math-link" href="https://www.webmo.net/support/pdf/byoc-centos7.pdf"&gt;document&lt;/a&gt; about the HPC cluster. If RDMA (Infiniband) network is involved, a configuration guide is provided in RedHat literature.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a href="https://aws.amazon.com/getting-started/hands-on/deploy-elastic-hpc-cluster/" class="rank-math-link"&gt;Here&lt;/a&gt; is an example of deploying HPC cluster in AWS. &lt;a href="https://docs.microsoft.com/en-us/powershell/high-performance-computing/overview?view=hpc19-ps" class="rank-math-link"&gt;Here&lt;/a&gt; is the guide to deploy HPC pack in Microsoft technologies.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-hpc-and-big-data"&gt;HPC and Big Data&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;HPC and Big Data are two distinctive computing paradigmes. Although there is some signs of convergence and blurred boundaries, it is still a long way before one can treat HPC and Big Data interchangeably. This &lt;a href="https://ieeexplore.ieee.org/document/7776538" class="rank-math-link"&gt;paper&lt;/a&gt; does a phenomenal job in comparing the two paradigms. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The fundamental difference lies in the respective problems they intend to address. HPC focuses on the large computational loads, whereas Big Data targets applications that need to handle very large and complex data sets (usually in the order of multi-terabytes or exabytes). Many scientific data analytics applications are becoming I/O bound in modern systems, such as seismic algorithms, Big Data applications are thus very demanding in terms of storage, to accommodate such a masive amount of data, while HPC is usualy thought more in inters of sheer computational needs. The open-source projects in Big Data also aims to run on conventional hardware to make it easier and less expensive to scale. This is not the main focus of HPC.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;So, you can run Big Data (e.g. Hadoop) analytics jobs on HPC gear. On the other hand, you can&amp;#8217;t run HPC jobs on commodity hardware as commonly seen in the Big Data stack. Both HPC and Hadoop analytics use parallel processing of data. In a Hadoop/analytics environment, data is stored on commodity hardware and distributed across multiple nodes of hardware. In HPC, where the size of data file is much greater, data storage in centralized. Also, because of the sheer volume of its files, HPC also requires more expensive networking communications such as Infiniband, because the size of the file it processes require high throughput and low latency.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In BigData job, each query in Hadoop reads data from disk and runs as a separate MapReduce job. Spark enables in-memory iterative processing (through the RDD abstraction), allowing the user to query repeatedly on a dataset without having to perform intermediate disk operations. RDD are exposed in the Spark API where each dataset is represented as a read-only object, and transformations are invoked using methods on these objects. For an example project, check out &lt;a href="https://static.digihunch.com/2020/09/spark-cassandra-and-python/" class="rank-math-link"&gt;this&lt;/a&gt; post.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The underlying software stacks for HPC and Big Data are fundamentally different, mainly due to the differences represent in their target class of applications, as outlined in the diagram below:&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-large"&gt;&lt;img loading="lazy" decoding="async" width="1598" height="862" src="https://static.digihunch.com/wp-content/uploads/2020/12/image.png" alt="" class="wp-image-1942"/&gt;&lt;figcaption class="wp-element-caption"&gt;software stack difference between HPC and Big Data&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As to which one is for me, the &lt;a href="https://www.techrepublic.com/article/4-steps-to-implementing-high-performance-computing-for-big-data-processing/" class="rank-math-link"&gt;over-simplified advice&lt;/a&gt; is: if you can avoid HPC and just use Hadoop for your analytics, do it. It is cheaper, easier, and more cloud friendly. However, bear in mind that an all-Hadoop shop is not possible for many industries such as life sciences, weather, pharmaceutical, and academic applications.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2020/12/instance-initialization-with-aws-cdk-in-python/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;AWS CDK example in Python – provision Kubernetes Nodes&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2020/12/ansible-tower-lab-environment-on-aws/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;AWS CDK example in Typescript – provision an AWX server&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Spark, Cassandra and Python</title><link>https://static.digihunch.com/2020/09/spark-cassandra-and-python/</link><pubDate>Tue, 15 Sep 2020 16:24:09 -0400</pubDate><guid>https://static.digihunch.com/2020/09/spark-cassandra-and-python/</guid><description>&lt;p class="wp-block-paragraph"&gt;In this &lt;a href="https://static.digihunch.com/2020/09/intro-to-big-data-projects/"&gt;post&lt;/a&gt; we touch briefly on &lt;a href="https://en.wikipedia.org/wiki/Apache_Spark"&gt;Apache Spark&lt;/a&gt; as a cluster computing framework that supports a number of drivers to pipe data in, and that its stunning performance thanks much to resilient distributed dataset (RDD) as its architectural foundation. In this hands-on guide, we expand on how to configure Spark, and use Python to connect to Cassandra data source. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Spark supports Sala, Java and Python shells. I&amp;#8217;m not familiar with Scala but I have had Python background and know it&amp;#8217;s importance in big data processing. One key data structure with big data processing in Python is Pandas &lt;a href="https://www.digitalvidya.com/blog/dataframes-in-python/"&gt;data frame&lt;/a&gt;. Spark has the ability to map its &lt;a href="https://www.analyticsvidhya.com/blog/2016/10/spark-dataframe-and-operations/"&gt;own data frame&lt;/a&gt; to Pandas data frame.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Spark also needs a third party connector to connect to Cassandra. This connector is provided by Datastax in this open-source project called &lt;a href="https://github.com/datastax/spark-cassandra-connector"&gt;spark-cassandra-connector&lt;/a&gt;. The Github page includes a README with compatibility matrix, which is very important to understand before any configuration works. However, the Github is only the source code repository for anyone to build the project themselves. An alternative source of the dependency is this &lt;a href="https://mvnrepository.com/artifact/com.datastax.spark/spark-cassandra-connector_2.11/2.5.1"&gt;page&lt;/a&gt; from Maven repository. When running Spark we can simply reference that page URL as dependency.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Suppose we install spark onto CentOS, we download and unzip &lt;a href="https://spark.apache.org/downloads.html"&gt;this&lt;/a&gt; package to somewhere such as user directory (~). Assuming we already have Open JDK 1.8 installed, when we run spark binary, it places cache and jar files in ~/.ivy2, potentially we need to manually move the following dependencies to ~/.ivy2/jars:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;org.codehaus.groovy_groovy-json-2.5.7.jar&lt;/li&gt;&lt;li&gt;com.github.jnr_jffi-1.2.19.jar&lt;/li&gt;&lt;li&gt;org.codehaus.groovy_groovy-2.5.7.jar&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;These jar files are available for download from Maven&amp;#8217;s repository as well if you wish provide them as package dependencies. We have two flavours of interactive shells to connect to Spark: the Scala shell (spark-shell) and python shell (PySpark)&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Scala Shell&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We can enter the default scala shell by &lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./bin/spark-shell --packages com.datastax.spark:spark-cassandra-connector_2.11:2.5.1 --conf spark.cassandra.connection.host&lt;span style="color:#f92672"&gt;=&lt;/span&gt;10.10.10.151 --verbose&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;During the start, note a stdout line that says:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Spark context Web UI available at http://spark-host:4040&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then we can open that tcp port on iptables and view that job in browser. From within scala shell we can test connectivity to Cassandra with the following commands:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; val new_exam = spark.read.format(&amp;#34;org.apache.spark.sql.cassandra&amp;#34;).options(Map(&amp;#34;table&amp;#34; -&amp;gt; &amp;#34;new_exam&amp;#34;,&amp;#34;keyspace&amp;#34; -&amp;gt; &amp;#34;examarchive&amp;#34;)).load()&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Python Shell&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Python Shell (aka &lt;a href="https://realpython.com/pyspark-intro/"&gt;PySpark&lt;/a&gt;) brings Python shell which is known to many engineers from system admin or development background. By default, python 2 will be used. To specify python version, set some environment variables before we start pyspark with cassandra connector package specified:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ export PYSPARK_PYTHON&lt;span style="color:#f92672"&gt;=&lt;/span&gt;python3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ export PYSPARK_DRIVER_PYTHON&lt;span style="color:#f92672"&gt;=&lt;/span&gt;python3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ export SPARK_HOME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/home/dhunch/spark-2.4.6-bin-hadoop2.7&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ export PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;$SPARK_HOME/bin:$PATH&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./bin/pyspark --packages com.datastax.spark:spark-cassandra-connector_2.11:2.5.1 --conf spark.cassandra.connection.host&lt;span style="color:#f92672"&gt;=&lt;/span&gt;10.10.10.151&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Once you&amp;#8217;re in the interactive shell, you can start with loading required python libraries, and test your connectivity:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; from pyspark import SparkContext, SparkConf&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; from pyspark.sql import SQLContext&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; load_options &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#f92672"&gt;{&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;table&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;new_exam&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;keyspace&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;examarchive&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; df&lt;span style="color:#f92672"&gt;=&lt;/span&gt;spark.read.format&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;org.apache.spark.sql.cassandra&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;.options&lt;span style="color:#f92672"&gt;(&lt;/span&gt;**load_options&lt;span style="color:#f92672"&gt;)&lt;/span&gt;.load&lt;span style="color:#f92672"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; df.show&lt;span style="color:#f92672"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; df.write.csv&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/mycsv.csv&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; &lt;span style="color:#75715e"&gt;#df.registerTempTable(&amp;#34;ne&amp;#34;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; df.createTempView&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ne&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; tw1&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext.sql&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;select count(*) from ne&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; tw1.show&lt;span style="color:#f92672"&gt;()&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; qrdf2&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext.sql&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;select study_key, image_count from ne where current_exam_version=exam_version&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt;&amp;gt;&amp;gt; qrdf2.write.csv&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/tw2&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Note that the load method returns type pyspark.sql.dataframe.DataFrame, which is already a distributed data structure. So there is no need to parallelize it with parallelize() method. As of Spark 2.0, we are supposed to use createTempView() method instead of the old registerTempTables() method. Read &lt;a href="https://dwgeek.com/spark-sql-create-temporary-tables-syntax-and-examples.html/"&gt;this&lt;/a&gt; for further information.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Python Application&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With interactive shell you run one or several commands at a time. We can build a python script and submit the whole script as an application. This is an example command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./bin/spark-submit --packages com.datastax.spark:spark-cassandra-connector_2.11:2.5.1 sample.py&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Note that the sample.py script name must be provided after &amp;#8211;packages switch. Otherwise, you will get an error saying missing dependency (Failed to find data source: org.apache.spark.sql.cassandra). In the script, we can manipulate the data from Cassandra with greater flexibility. For example, we can map one field to several fields. For example, if one of the fields stores an XML document, the script can drill down the XML tree structure parse out values at different levels of child nodes, into separate data base columns. Here is an example of python script where we register a custom UDF declared in python and apply it to some existing columns to build new columns:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#! /usr/bin/python3&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# To submit this script as an application to spark:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ./bin/spark-submit --packages com.datastax.spark:spark-cassandra-connector_2.11:2.5.1 examstat.py&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Note that the script name must be placed after --packages &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; sys&lt;span style="color:#f92672"&gt;,&lt;/span&gt;datetime&lt;span style="color:#f92672"&gt;,&lt;/span&gt;re&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; xml.etree.ElementTree &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; ET&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pyspark &lt;span style="color:#f92672"&gt;import&lt;/span&gt; SparkContext, SparkConf&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pyspark.sql &lt;span style="color:#f92672"&gt;import&lt;/span&gt; SQLContext, SparkSession&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pyspark.sql.functions &lt;span style="color:#f92672"&gt;import&lt;/span&gt; udf &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; pyspark.sql.types &lt;span style="color:#f92672"&gt;import&lt;/span&gt; StringType,StructType,StructField&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cluster_seeds&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;dest_cass_host&amp;#39;&lt;/span&gt;]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pTrimExamCode&lt;/span&gt;(raw_code):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;NULL&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; raw_code &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt; &lt;span style="color:#f92672"&gt;or&lt;/span&gt; raw_code&lt;span style="color:#f92672"&gt;==&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;None&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; str(raw_code)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;replace(&lt;span style="color:#e6db74"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;rstrip(&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\r\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;is_valid_date&lt;/span&gt;(date_str):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; isValidDate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;bool(re&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;match&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;^(19|20)\d\d(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$&amp;#34;&lt;/span&gt;,date_str))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; isValidDate:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; datetime&lt;span style="color:#f92672"&gt;.&lt;/span&gt;datetime(int(date_str[:&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;]),int(date_str[&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;]),int(date_str[&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;]))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ValueError&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; isValidDate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; isValidDate&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;pPullTags&lt;/span&gt;(study_key,raw_xml_field):&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ns&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;vc&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;http://medical.nema.org/mint&amp;#34;&lt;/span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StudyDateTag&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;None&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StudyDescriptionTag&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;None&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; raw_xml_field &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; summary_tree&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ET&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fromstring(str(raw_xml_field)) &lt;span style="color:#75715e"&gt;# str function outputs &amp;#39;None&amp;#39; or null object&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; xml_find_res&lt;span style="color:#f92672"&gt;=&lt;/span&gt;summary_tree&lt;span style="color:#f92672"&gt;.&lt;/span&gt;find(&lt;span style="color:#e6db74"&gt;&amp;#34;vc:attributes/vc:attr[@tag=&amp;#39;00080020&amp;#39;]&amp;#34;&lt;/span&gt;,ns)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; xml_find_res &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;: StudyDateTag&lt;span style="color:#f92672"&gt;=&lt;/span&gt;str(xml_find_res&lt;span style="color:#f92672"&gt;.&lt;/span&gt;attrib&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#39;val&amp;#39;&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;xml_find_res&lt;span style="color:#f92672"&gt;=&lt;/span&gt;summary_tree&lt;span style="color:#f92672"&gt;.&lt;/span&gt;find(&lt;span style="color:#e6db74"&gt;&amp;#34;vc:attributes/vc:attr[@tag=&amp;#39;00081030&amp;#39;]&amp;#34;&lt;/span&gt;,ns)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; xml_find_res &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;: StudyDescriptionTag&lt;span style="color:#f92672"&gt;=&lt;/span&gt;str(xml_find_res&lt;span style="color:#f92672"&gt;.&lt;/span&gt;attrib&lt;span style="color:#f92672"&gt;.&lt;/span&gt;get(&lt;span style="color:#e6db74"&gt;&amp;#39;val&amp;#39;&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;except&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;-----------------------&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; examstat: error parsing metadta for study_key &amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;study_key)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (StudyDateTag,StudyDescriptionTag)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# custom StructType for the output tuple&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;XMLExtractType&lt;span style="color:#f92672"&gt;=&lt;/span&gt;StructType([&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StructField(&lt;span style="color:#e6db74"&gt;&amp;#34;StudyDate&amp;#34;&lt;/span&gt;,StringType(),&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;),&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; StructField(&lt;span style="color:#e6db74"&gt;&amp;#34;StudyDescription&amp;#34;&lt;/span&gt;,StringType(),&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;)])&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sparkSession&lt;span style="color:#f92672"&gt;=&lt;/span&gt;SparkSession&lt;span style="color:#f92672"&gt;.&lt;/span&gt;builder \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;appName(&lt;span style="color:#e6db74"&gt;&amp;#39;examstat&amp;#39;&lt;/span&gt;) \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;config(&lt;span style="color:#e6db74"&gt;&amp;#39;spark.cassandra.connection.host&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(cluster_seeds)) \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;master(&lt;span style="color:#e6db74"&gt;&amp;#39;local[*]&amp;#39;&lt;/span&gt;) \&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;.&lt;/span&gt;getOrCreate()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; load_options &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#34;table&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;new_exam&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;keyspace&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;examarchive&amp;#34;&lt;/span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sqlContext&lt;span style="color:#f92672"&gt;=&lt;/span&gt;SQLContext(sparkSession)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# pyspark.sql.dataframe.DataFrame is already a distributed data structure. No need to parallelize it.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df0&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext&lt;span style="color:#f92672"&gt;.&lt;/span&gt;read&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(&lt;span style="color:#e6db74"&gt;&amp;#39;org.apache.spark.sql.cassandra&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;options(&lt;span style="color:#f92672"&gt;**&lt;/span&gt;load_options)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;load()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df0&lt;span style="color:#f92672"&gt;.&lt;/span&gt;createTempView(&lt;span style="color:#e6db74"&gt;&amp;#34;new_exam&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# pyspark.sql.functions.udf(python function,output type)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sparkSession&lt;span style="color:#f92672"&gt;.&lt;/span&gt;udf&lt;span style="color:#f92672"&gt;.&lt;/span&gt;register(&lt;span style="color:#e6db74"&gt;&amp;#34;uTrimExamCode&amp;#34;&lt;/span&gt;,udf(pTrimExamCode,StringType()))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sparkSession&lt;span style="color:#f92672"&gt;.&lt;/span&gt;udf&lt;span style="color:#f92672"&gt;.&lt;/span&gt;register(&lt;span style="color:#e6db74"&gt;&amp;#34;uPullTags&amp;#34;&lt;/span&gt;,udf(pPullTags,XMLExtractType))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# use custom UDFs uTrimExamCode and uPullTags to calculate new columns and remove dups and deleted studies&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df1&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sql(&lt;span style="color:#e6db74"&gt;&amp;#34;select study_key as StudyKey,uTrimExamCode(exam_id) as ExamCode,image_count as ImgCnt,Total_pixel_data_size as PixelSize, uPullTags(study_key,metadata_summary) as XMLExtract, metadata_summary from new_exam where exam_version=current_exam_version and is_deleted=False&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df1&lt;span style="color:#f92672"&gt;.&lt;/span&gt;createTempView(&lt;span style="color:#e6db74"&gt;&amp;#34;uniq_study&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# map the four fields in XMLExtract to separate columns. we take this as separate step as we don&amp;#39;t want uPullTags to execute multiple times in previous step &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df2&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sql(&lt;span style="color:#e6db74"&gt;&amp;#34;select StudyKey,ExamCode,ImgCnt,PixelSize,XMLExtract.StudyDate as StudyDate,XMLExtract.StudyDescription as StudyDescription from uniq_study&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;createTempView(&lt;span style="color:#e6db74"&gt;&amp;#34;uniq_study_stat&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Run analytical query&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df3&lt;span style="color:#f92672"&gt;=&lt;/span&gt;sqlContext&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sql(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT ExamCode, round(avg(PixelSize)/1024/1024) as avg_size_mb, round(sum(PixelSize)/1024/1024/1024,2) as total_size_gb,count(StudyKey) as study_count FROM uniq_study_stat GROUP BY ExamCode order by study_count desc&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#data frames are lazily loaded and processing not started until the following call&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; df3&lt;span style="color:#f92672"&gt;.&lt;/span&gt;write&lt;span style="color:#f92672"&gt;.&lt;/span&gt;csv(&lt;span style="color:#e6db74"&gt;&amp;#39;/tmp/examstat_&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;datetime&lt;span style="color:#f92672"&gt;.&lt;/span&gt;datetime&lt;span style="color:#f92672"&gt;.&lt;/span&gt;now()&lt;span style="color:#f92672"&gt;.&lt;/span&gt;strftime(&lt;span style="color:#e6db74"&gt;&amp;#34;%m&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%H%M%S&amp;#34;&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;It is important to understand the concept of lazy evaluation in Spark RDD here. The execution of function to RDD does not start until an action is triggered (eg. show method, or write method). Spark maintains the record of which operation is being called through DAG (&lt;a href="https://data-flair.training/blogs/dag-in-apache-spark/"&gt;directed acyclic graph&lt;/a&gt;). Such record is referred to as a transformation. We need to understand whether each RDD method is a transformation, or an action so we know whether it will be lazily evaluated (&lt;a href="https://data-flair.training/blogs/spark-rdd-operations-transformations-actions/"&gt;here&amp;#8217;s&lt;/a&gt; more information).&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This is a &lt;a href="https://data-flair.training/blogs/spark-vs-hadoop-mapreduce/"&gt;major difference&lt;/a&gt; between Apache Spark and Hadoop MapReduce. With MapReduce, developer spend a lot of time in minimizing the number of MapReduce passes. It happens by clubbing the operations together. &lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2020/09/intro-to-big-data-projects/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Intro to Big Data Projects&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2020/09/log-file-navigator-lnav/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Log file navigator (lnav)&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Intro to Big Data Projects</title><link>https://static.digihunch.com/2020/09/intro-to-big-data-projects/</link><pubDate>Thu, 10 Sep 2020 21:33:00 -0400</pubDate><guid>https://static.digihunch.com/2020/09/intro-to-big-data-projects/</guid><description>&lt;p class="wp-block-paragraph"&gt;Modern applications produce super large datasets beyond what traditional data-processing application can handle. Big data is a discipline that specialize in processing such data. For example, analysis, information extraction etc. The scale of large dataset grows well beyond the capacity of a single computer, which calls for computing power delivered by multi-node clustered systems. Intensive computing tasks are completed in a distributed system consisting multiple nodes each performing some tasks, known as High-Performance Computing Cluster (HPCC).&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Cluster computing inherit the challenges of distributed system. Moreover, two main challenges to solve are: distributed storage, and distributed computation. In Apache Hadoop projects, HDFS and MapReduce address these two challenges respectively. Now the Hadoop ecosystem has evolved to include several core projects:&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;HDFS&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A distributed file system for reliably storing huge amount of unstructured, semi-structured or structured data in the form of files. Parts of a single large file can be stored on different nodes across the cluster. HDFS works in master-slave mode:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;NameNode (master): holds file system namespace, controls access, keep track of DataNodes and replication factor &lt;/li&gt;&lt;li&gt;DataNode (slave): stores user data&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;HDFS is Java-based so is portable across all platforms. User interact with HDFS using a command-line interface called &amp;#8220;FS shell&amp;#8221;. There is also an interface called FUSE (filesystem in userspace) to mount HDFS to Linux OS. Since HDFS supports commodity hardware it is great for storing data for further processing. However, HDFS is not suitable for storing data related to applications requiring low latency access, nor is it good for simultaneous writes to the same file. Also HDFS is not suitable for large number of small files because the metadata for each file needs to be stored on the NameNode and is held in memory. &lt;a href="https://hadoop.apache.org/docs/stable1/hdfs_design.html"&gt;Here&lt;/a&gt; is the architecture guide for HDFS, and this &lt;a href="https://data-flair.training/blogs/hadoop-hdfs-data-read-and-write-operations"&gt;page&lt;/a&gt; expands further on the read and write operations in HDFS.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Compared to NAS(e.g. NFS), HDFS is distributed by design. The data blocks are distributed across different nodes. NFS storage may or may not be distributed depending on the implementation. HDFS is designed to work with MapReduce paradigm, where computation is moved to the data. In NAS, data is stored separately from the computations. Lastly, NAS is usually made up of enterprise grade hard drive but HDFS works with commodity hardware.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;MapReduce&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Hadoop MapRecude is a distributed algorithm framework that allows parallel processing of huge amounts of data. It breaks a large chunk into smaller ones to be processed separately on different data nodes and automatically gather the results across the multiple nodes to return a single result. If the duration of linear data processing can be done during night hours, it makes sense to choose Hadoop MapReduce. MapReduce runs on Hadoop cluster but also supports other database formats like Cassandra and HBase. MapReduce includes:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Job: a unit of work to be performed as requested by the client.&lt;/li&gt;&lt;li&gt;Task: Jobs are divided into sub-jobs known as tasks. The tasks can be run independent of each other on different nodes. There are two types of tasks: &lt;ul&gt;&lt;li&gt;Map task is performed by map() function to process one or more chunks of data and produce the output results&lt;/li&gt;&lt;li&gt;Reduce task is performed by reduce() function to consolidate the results produced by each of the map task&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;JobTracker: like the storage (HDFS), the computation (MapReduce) also works in master-slave fashion. A JobTracker node acts as the master to schedule task on appropriate nodes, coordinate execution of tasks, get the result back after execution of each task, re-execute failed tasks, and monitor overall progress. There is only one JobTracker node per Hadoop Cluster.&lt;/li&gt;&lt;li&gt;TaskTracker: a TaskTracker node acts as teh slave and is responsible for executing a task assigned to it by the JobTracker. There are usually a number of JobTracker nodes in a Hadoop Cluster. They execute the heavy lifting tasks.&lt;/li&gt;&lt;li&gt;Data Locality: if MapReduce cannot place the data and the compute on the same node, data locality put the compute on the node nearest to the respective data node(s) which contains the data to be processed.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The MapReduce programming model includes these steps: input-&amp;gt;split-&amp;gt;map-&amp;gt;combine-&amp;gt;shuffle&amp;amp;sort-&amp;gt;reduce-&amp;gt;output.&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://ars.els-cdn.com/content/image/3-s2.0-B9780128093931000064-f06-04-9780128093931.jpg?_" alt=""/&gt;&lt;figcaption&gt;MapReduce programming model&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;h3 class="wp-block-heading"&gt;YARN&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;YARN (yet another resource negotiator) is a system to schedule applications and services on an HDFS cluster and manage the cluster resources like memory and CPU. The two components are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;ResourceManager: receives the processing requests, and then passes the parts of requests to corresponding NodeManager accordingly based on the needs. ResourceManager is a central authority.&lt;/li&gt;&lt;li&gt;NodeManager: installed on every DataNode, is responsible for execution of the task on every single DataNode, monitoring the resource usage and reporting to the ResourceManager.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;h3 class="wp-block-heading"&gt;HBase&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A key-value pair NoSQL database based on HDFS storage, with column family data representation, and mater-slave replication. HBase is based on Google&amp;#8217;s BigTable concept (similar to Cassandra). It runs on a cluster of commodity hardware and scales linearly. Compared with Cassandra, HBase doesn&amp;#8217;t have a query language of its own. You will have to work with JRuby-based shell, or Apache Hive. HBase is also a master-slave architecture and it uses Zookeeper as a status manager. In that sense, Cassandra is a &amp;#8220;self-sufficient&amp;#8221; database technology whereas HBase relies on other components in Hadoop. This &lt;a href="https://www.scnsoft.com/blog/cassandra-vs-hbase"&gt;article&lt;/a&gt; also compares the data model difference between the two.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Hive&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Hive is a SQL interface over MapReduce for developers and analysts who prefer SQL interface over native Java MapReduce programming to query and manage large datasets residing in HDFS. With Hive you can map a tabular structure on to data stored in distributed storage. The Hive queries are written in SQL-like language known as HiveQL, executed via MapReduce. When a HiveQL query is issued, it triggers a Map and/or Reduce job(s) to perform the operation defined in the query.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Pig&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A scripting interface over MapReduce for developers who prefer scripting interface over the native Java MapReduce programming. It is a runtime environment with a shell (named &lt;strong&gt;Grunt Shell&lt;/strong&gt;) for execution of MapReduce jobs via a high-level scripting language called Pig Latin. Pig is an abstraction (high-level programming language) on top of a Hadoop cluster. The Pig Latin query/command are complied into one or more MapReduce jobs and then executed on Hadoop cluster. The most common commands in Pig are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;DUMP: displays the results to screen&lt;/li&gt;&lt;li&gt;STORE: stores the results to HDFS&lt;/li&gt;&lt;/ul&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img decoding="async" src="https://2.bp.blogspot.com/-w7KeAnwWnBQ/WfYBJzgtvQI/AAAAAAAAAMk/D58SpZfK7lkJ8QnKnQZW268mKzRvuOOnACLcBGAs/s640/HadoopStack.png" alt="Apache Hadoop Ecosystem"/&gt;&lt;figcaption&gt;Hadoop Ecosystem&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are some other Apache projects, which are sometimes considered as in the Hadoop ecosystem as well:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;&lt;strong&gt;Oozie&lt;/strong&gt;: worflow scheduling system to manage Hadoop jobs. In Oozie, a workflow is defined as a collection of control flow nodes and action nodes in a directed acyclic graph. Control flow nodes define the beginning and the end of a workflow, as well as a mechanism to control the workflow execution path. Action nodes are the mechanism by which a workkflow triggers the execution of a computation/processing task, such as MapReduce, Pig, etc.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Sqoop&lt;/strong&gt; (SQL-to-Hadoop): a command-line interpreter tool for importing data from database (e.g. MySQL, data warehouse, etc) into the Hadoop environment (e.g. HDFS, Hive). It can also export the data back.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Flume&lt;/strong&gt;: data ingestion for streaming logs into Hadoop environment. Flume is a distributed and reliable service for collecting and aggregating huge amounts of log data.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ZooKeeper&lt;/strong&gt;: distributed service coordinator, as previously &lt;a href="https://static.digihunch.com/2020/08/zookeeper/"&gt;discussed&lt;/a&gt;. It is based on a Paxos algorithm variant called ZAB protocol.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ambari&lt;/strong&gt;: a framework for provisioning, managing and monitoring Hadoop clusters.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Hortonworks &lt;a href="https://www.cloudera.com/downloads/hortonworks-sandbox.html"&gt;sandbox&lt;/a&gt; provide a VM image that have some Hadoop services pre-installed for beginners to get a taste of how it works all together.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Spark&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Hadoop is used in the industry owing to a simple programming model (MapReduce) but the speed and waiting time (between queries and running the program). Spark is introduced to speed up the computing process. Spark uses Hadoop for storage (HDFS) and processing. It extends the MapReduce model to efficiently use more types of computations which includes interactive queries and stream processing. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Spark started as a sub-project of Hadoop in 2009 but since 2014 Apache has run it as a top-level project. It is a lightning-fast in-memory cluster computing technology. The features are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Speed: in-memory computing makes super fast processing;&lt;/li&gt;&lt;li&gt;Built-in APIs supports multiple languages: Scala, Python and Java;&lt;/li&gt;&lt;li&gt;Advanced analytics &amp;#8211; apart from map and reduce, Spark also has libraries that supports SQL query, near real-time stream processing, Graph algorithms and machine learning.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Spark can run in &lt;a href="https://spark.apache.org/docs/latest/spark-standalone.html"&gt;standalone mode&lt;/a&gt;, on &lt;a href="https://spark.apache.org/docs/latest/running-on-mesos.html"&gt;Mesos&lt;/a&gt;, or with &lt;a href="https://spark.apache.org/docs/latest/running-on-yarn.html"&gt;YARN cluster manager&lt;/a&gt;. The document also provides guide on deployment on EC2 and &lt;a href="https://spark.apache.org/docs/latest/running-on-kubernetes.html"&gt;Kubernetes&lt;/a&gt;. Spark contains these components:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Spark Core: the underlying general execution engine for spakr platform that all other functionality is built upon. It provides in-memory computing and referencing datasets in external storage systems.&lt;/li&gt;&lt;li&gt;SparkSQL: a components on top of Spark Core that introduces a new data abstraction called SchemaRDD, which supports both structured and semi-structured data.&lt;/li&gt;&lt;li&gt;Spark Streaming: perform streaming analytics on top of Spark Core. It ingests data in mini-batches and performs RDD (Resilient Distributed Datasets) transformation on the fly.&lt;/li&gt;&lt;li&gt;MLib: a distributed machine learning framework &lt;/li&gt;&lt;li&gt;GraphX: a distributed graph-processing framework&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The speed of Spark is owing to its fundamental data structure &amp;#8211; Resilient Distributed Datasets (RDD), an immutable distributed collection of objects. Each dataset in RDD (object collection) is divided into logical partitions, which can be computed on different nodes of the cluster. The object can be any type of Python, Java or Scala object, including user-defined classes. There are two ways to create RDDS:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Parallelizing an existing collection in your driver program&lt;/li&gt;&lt;li&gt;Referencing a dataset from external storage system (e.g. HDFS, HBase) or data source offering a Hadoop Input Format&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;You can also create RDD based on other existing RDDs. This &lt;a href="https://www.tutorialspoint.com/apache_spark/apache_spark_rdd.htm"&gt;page&lt;/a&gt; explains further how RDD speeds up computing compared to MapReduce.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2020/09/host-legacy-application-with-docker-compose/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Host legacy application in Docker 1 of 2&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2020/09/spark-cassandra-and-python/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Spark, Cassandra and Python&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>