Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use graphframes with pyspark on AWS EMR?

I'm trying to use the graphframes package in pyspark in Jupyter Notebook (using Sagemaker and sparkmagic) on AWS EMR. I've tried adding a configuration option when creating the EMR cluster in the AWS console:

[{"classification":"spark-defaults", "properties":{"spark.jars.packages":"graphframes:graphframes:0.7.0-spark2.4-s_2.11"}, "configurations":[]}]

But I still got an error when trying to use the graphframes package in my pyspark code in jupyter notebook.

Here's my code (it's from the graphframes example):

# Create a Vertex DataFrame with unique ID column "id"
v = spark.createDataFrame([
  ("a", "Alice", 34),
  ("b", "Bob", 36),
  ("c", "Charlie", 30),
], ["id", "name", "age"])
# Create an Edge DataFrame with "src" and "dst" columns
e = spark.createDataFrame([
  ("a", "b", "friend"),
  ("b", "c", "follow"),
  ("c", "b", "follow"),
], ["src", "dst", "relationship"])
# Create a GraphFrame
from graphframes import *
g = GraphFrame(v, e)

# Query: Get in-degree of each vertex.
g.inDegrees.show()

# Query: Count the number of "follow" connections in the graph.
g.edges.filter("relationship = 'follow'").count()

# Run PageRank algorithm, and show results.
results = g.pageRank(resetProbability=0.01, maxIter=20)
results.vertices.select("id", "pagerank").show()

And here's the output/error:

ImportError: No module named graphframes

I read through this git thread but all the potential work-arounds seem very complicated and require ssh-ing into the master node of the EMR cluster.

like image 339
Bob Swain Avatar asked Jun 04 '19 14:06

Bob Swain


People also ask

Can we run PySpark on EMR?

You can use AWS Step Functions to run PySpark applications as EMR Steps on an existing EMR cluster. Using Step Functions, we can also create the cluster, run multiple EMR Steps sequentially or in parallel, and finally, auto-terminate the cluster.

Can spark Mllib run on EMR?

You can install Spark on an Amazon EMR cluster along with other Hadoop applications, and it can also leverage the EMR file system (EMRFS) to directly access data in Amazon S3.

How do I open PySpark shell in EMR?

You can access the Spark shell by connecting to the master node with SSH and invoking spark-shell . For more information about connecting to the master node, see Connect to the master node using SSH in the Amazon EMR Management Guide. The following examples use Apache HTTP Server access logs stored in Amazon S3.


1 Answers

I finally figured out that there is a PyPi package for graphframes. I used this to create a bootstrapping action as detailed here, although I changed things a little bit.

Here's what I did to get graphframes working on EMR:

  1. First I created a shell script and saved it so s3 named "install_jupyter_libraries_emr.sh":
#!/bin/bash

sudo pip install graphframes
  1. I then went through the advanced options EMR creation process in the AWS console.
    • During Step 1, I added in the maven coordinates of the graphframes package within the edit software settings text box:
    [{"classification":"spark-defaults","properties":{"spark.jars.packages":"graphframes:graphframes:0.7.0-spark2.4-s_2.11"}}]
    
    • During Step 3: General Cluster Settings, I went into the bootstrap actions section
    • Within the bootstrap actions section, I added a new custom boostrap action with:
      • an arbitrary name
      • The s3 location of my "install_jupyter_libraries_emr.sh" script
      • no optional arguments
    • I then started the cluster creation
  2. Once my cluster was up, I got into Jupyter and ran my code:
# Create a Vertex DataFrame with unique ID column "id"
v = spark.createDataFrame([
  ("a", "Alice", 34),
  ("b", "Bob", 36),
  ("c", "Charlie", 30),
], ["id", "name", "age"])
# Create an Edge DataFrame with "src" and "dst" columns
e = spark.createDataFrame([
  ("a", "b", "friend"),
  ("b", "c", "follow"),
  ("c", "b", "follow"),
], ["src", "dst", "relationship"])
# Create a GraphFrame
from graphframes import *
g = GraphFrame(v, e)

# Query: Get in-degree of each vertex.
g.inDegrees.show()

# Query: Count the number of "follow" connections in the graph.
g.edges.filter("relationship = 'follow'").count()

# Run PageRank algorithm, and show results.
results = g.pageRank(resetProbability=0.01, maxIter=20)
results.vertices.select("id", "pagerank").show()

And this time, finally, I got the correct output:

+---+--------+
| id|inDegree|
+---+--------+
|  c|       1|
|  b|       2|
+---+--------+

+---+------------------+
| id|          pagerank|
+---+------------------+
|  b|1.0905890109440908|
|  a|              0.01|
|  c|1.8994109890559092|
+---+------------------+
like image 165
Bob Swain Avatar answered Sep 19 '22 18:09

Bob Swain