将Amazon EMR Spark与MySQL连接(编写数据)

时间:2017-06-28 04:36:29

标签: mysql apache-spark jdbc pyspark emr

我有一个潜在的愚蠢问题;我实际上在本地运行Spark时解决了这个问题,但在AWS EMR上运行它时无法解决它。

基本上,我提交了一个pyspark脚本,我提交读取数据,操作它,将其处理成Spark Dataframe并将其写入我已经在AWS RDS上其他地方托管的MySQL表。

这是EMR 5.6,使用Spark 2.1.1

我下载了MySQL连接器的最新驱动程序(“mysql-connector-java-5.1.42-bin.jar”)并将它们放入我的主节点实例(基本上将其下载到我的本地笔记本电脑上,然后使用scp把它放在主节点中。)

然后我在/ etc / spark / conf下找到了我的spark-defaults.conf文件并编辑了以下参数:

spark.driver.extraClassPath
spark.executor.extraClassPath

对于这两个,我添加了我的mysql-connector文件的路径,该文件位于/home/hadoop/mysql-connector-java-5.1.42-bin.jar

基于此SO帖子(Adding JDBC driver to Spark on EMR),我使用以下命令提交(包括“extraClassPath”的整个路径):

spark-submit sample_script.py --driver-class-path /home/hadoop/mysql-connector-java-5.1.42-bin.jar:/usr/lib/hadoop-lzo/lib/*:/usr/lib/hadoop/hadoop-aws.jar:/usr/share/aws/aws-java-sdk/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*:/usr/share/aws/emr/security/conf:/usr/share/aws/emr/security/lib/*

在我的代码中,我有一个spark数据帧,以下代码是写入数据库的内容:

SQL_CONN = "jdbc:mysql://name.address.amazonaws.com:8000/dbname?user=user&password=pwd"
spark_df.write.jdbc(SQL_CONN, table="tablename", mode="append", properties={"driver":'com.mysql.jdbc.Driver'})

我得到的具体错误是:

java.lang.ClassNotFoundException (com.mysql.jdbc.Driver) [duplicate 51]

任何意见都会受到赞赏......对我而言,这是一个非常愚蠢的错误,我无法确定。

2 个答案:

答案 0 :(得分:2)

尽管作者的回答是正确的,但是您可以使用 run_date county-state company est type val 0 2020-08-30 ColfaxNebraska Vergin 86M new 2 1 2020-08-30 ColfaxNebraska Vergin 86M confirmed 718 2 2020-08-30 ColfaxNebraska Vergin 86M death 5 3 2020-08-30 FordKansas Vergin 86K new 0 4 2020-08-30 FordKansas Vergin 86K confirmed 2178 5 2020-08-30 FordKansas Vergin 86K death 10 6 2020-08-30 FresnoCalifornia Vergin 354 new 0 7 2020-08-30 FresnoCalifornia Vergin 354 confirmed 23932 8 2020-08-30 FresnoCalifornia Vergin 354 death 239 9 2020-08-30 MorganColorado Vergin 86R new 1 10 2020-08-30 MorganColorado Vergin 86R confirmed 711 11 2020-08-30 MorganColorado Vergin 86R death 48 12 2020-08-30 ParmerTexas Vergin 86E new 1 13 2020-08-30 ParmerTexas Vergin 86E confirmed 381 14 2020-08-30 ParmerTexas Vergin 86E death 7 来提交一个jar,而不是手动放置jar,它将为您处理其余问题

import pandas as pd
import plotly.express as px

# load and clean data
df = pd.read_csv("https://gist.githubusercontent.com/jerry-shad/318595505684ea4248a6cc0949788d33/raw/31bbeb08f329b4b96605b8f2a48f6c74c3e0b594/coviddf.csv")
df.drop(columns=['Unnamed: 0'], inplace=True)  # drop this extra column
df.run_date = pd.to_datetime(df.run_date)  # set run_date to a datetime format

# convert to long form
dfl = df.set_index(['company', 'est', 'latitude', 'longitude'])[['confirmed', 'new', 'death']].stack().reset_index().rename(columns={'level_4': 'type', 0: 'vals'})

# plot
fig = px.scatter_geo(dfl,
                     lon='longitude',
                     lat='latitude',
                     color="type", # which column to use to set the color of markers
                     hover_name="company", # column added to hover information
                     size="vals", # size of markers
                     projection="albers usa")
fig.show()

虽然没有明确询问,但在 EMR笔记本中,由于您不想自己运行spark-submit,因此有更简便的方法

将jar文件上传到s3,让它成为笔记本的第一个单元格

 [
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "metadata": "=split('/',@(1,metadata))"
        }
      },
      {
        "operation": "shift",
        "spec": {
          "metadata": {
            "*": {
              "*=*": {
                "$(0,2)": "data.&(1,1)"
              }
            }
          }
        }
      }
     ]

答案 1 :(得分:1)

修复 - 我很愚蠢,忘了将jar文件放在我的从属节点中。我忘了--driver-class-path不会自动将jar分发给我的slave。

一旦我将jar文件放在与我的主节点相同的根目录中(即在我的情况下为/ home / hadoop),它就起作用了。

希望这有帮助。