在开发PySpark程序时通常会需要用到Java的对象,而PySpark本身也是建立在Java API之上,通过Py4j来创建JavaSparkContext

这里有几点是需要注意的

1. Py4j只运行在driver

也就是说worker目前来说引入不了第三方的jar包。因为worker结点的PySpark是没有启动Py4j的通信进程的,相应的jar包自然也加载不了。之前没有详细看这部分文档,系统设计时企图在worker结点利用client模式直连Hbase来获取部分数据,从而避免对整个表的JOIN操作,当然对于python来说这样的操作只有通过引入jar包来实现(不考虑thrift方式)。但是测试的jar写好之后,一直不成功,最后只有修改方案,后来才去查了官方文档。

2. PythonRDD 的原型是 JavaRDD[String]

所有的经过PythonRDD传递的数据都通过BASE64编码

3. PySpark 中的方法和匿名函数是通过cloudpickle序列化

为何函数需要被序列化,因为做map或者flatMap时,此时的函数或者lambda表达式是需要传递到各个worder的,如果函数里有用到闭包,cloudpickle也能巧妙的序列化。但是,需要传递的函数里请不要是用self关键字,因为传递过去后,self的指代关系已经不明确了。

文档还提到PythonRDD的序列化是可定制的了,但是目前没这个需求,所有没测试

代码示例

java 测试代码, 编译生成 pyspark-test.jar

package org.valux.py4j;
public class Calculate {
public int sqAdd(int x){
return x * x + 1;
}
}

Python 测试代码,放在文件 driver.py

from pyspark import SparkContext
from py4j.java_gateway import java_import sc = SparkContext(appName="Py4jTesting")
java_import(sc._jvm, "org.valux.py4j.Calculate")
func = sc._jvm.Calculate()
print func.sqAdd(5)
"""
[OUTPUT] > 26
"""
"""
!!![错误用法]
这里是想在每个work上调用自定义的方法,
前面已经提到过PySpark目前是不支持的
"""
rdd = sc.parallelize([1, 2, 3])
result = rdd.map(func.sqAdd).collect() """
!!![错误用法]
之前还有个错误的思路是想在work单独 import 相应的 jar
"""
def foo(x):
java_import(sc._jvm, "org.valux.py4j.Calculate")
func = sc._jvm.Calculate()
func.sqAdd(x)
rdd = sc.parallelize([1, 2, 3])
rdd.map(foo).collect()
测试时,提交程序需要记得带上jar包
> bin/spar-submit --driver-class-path pyspark-test.jar driver.py

这里又有一个坑,之前提交为了方便,一直都用的是 --jars 参数

--driver-class-path 附加的 jar 只会在 driver引入 --jars 附加的jar会在所有worker引入

帮助文档里面还提到

--jars Comma-separated list of local jars to include on the driver and executor classpaths.

所有就偷个懒用了 --jars ,结果一直报如下错误:

py4j.protocol.Py4JError: Trying to call a package.

测试了好久终于解决了

参考文档

https://cwiki.apache.org/confluence/display/SPARK/PySpark+Internals

PySpark调用自定义jar包的更多相关文章

  1. Jmeter调用自定义jar包

    一. 场景 在测试过程中, 可能需要调用第三方jar包来生成测试数据或者使用java工具类来实现业务场景, 普遍的做法是手动调用jar包, 再把这些值赋给jmeter中的某个参数, 以满足业务测试需求 ...

  2. Kettle自定义jar包供javascript使用

    我们都知道 Kettle 是用 Java 语言开发,并且可以在 JavaScript 里面直接调用 java 类方法.所以有些时候,我们可以自定义一些方法,来供 JavaScript 使用. 本篇文章 ...

  3. spring boot项目使用swagger-codegen生成服务间调用的jar包

    swagger-codegen的github:https://github.com/swagger-api/swagger-codegen 需要的环境:jdk > 1.7   maven > ...

  4. 【Maven】如何使用pom.xml引入自定义jar包

    这里我以这个jar包为例,aliyun-java-sdk-core-3.2.3.jar ,这是我在做手机短信服务用到的jar包 ①进入C盘下的maven仓库C:\Users\用户\.m2\reposi ...

  5. java自定义jar包让jemeter使用

    背景:可能在做定义化的要求上,jmeter原有的jar包,已经不能满足我们,就需要自己写一个方法,以下就是写入的一个模拟post的请求,在jmeter中使用的案例 一:写代码 1.代码中的有两个包,原 ...

  6. 服务器程序动态加载自定义jar包的过程

    需求: 用过hive的都知道,可以自定义hive的一个udf jar,然后将这个jar add到hive服务端,就会加载这个jar实现用户自定义逻辑.现在的需求就是实现这么一个服务端所做的事情! 场景 ...

  7. maven增加自定义jar包

    1.博客来源: http://www.cnblogs.com/leiOOlei/p/3356834.html 导入平台SDK的方法 mvn install:install-file -DgroupId ...

  8. 关于自定义jar包(tomcat)的添加

    1 鼠标右击工程 选择 properties 或者 Ait + Enter 2 选择Libraries 3 点击Add Library... 4 选择User Library  点击 Next 5 如 ...

  9. Maven引入自定义jar包

    1.将项目打成jar包  或者下载某个jar包  放在某个目录下(随便吧,桌面也行),这里是放在F:/  jar包为 alipay.jar 2.给jar包取个名字   用原名也行(maven打包默认会 ...

随机推荐

  1. 总结Selenium自动化测试方法(六)常见的异常错误处理

    六.常见的异常错误处理 NoSuchElementException: Message: Unable to locate element: {"method":"xpa ...

  2. Client-Side UI Automation Provider - WinForm Sample

    Client-Side UI Automation Provider -  WinForm Sample 2014-09-15 源代码 目录 引用程序集实现提供程序接口分发客户端提供程序注册和配置客户 ...

  3. java日期格式的转换

    1.转换指定格式的日期 /** * 日期格式转换 * @throws ParseException */ public String dateformat(String date,String tab ...

  4. JAVA使用JNI调用C++动态链接库

    JAVA使用JNI调用C++动态链接库 使用JNI连接DLL动态链接库,并调用其中的函数 首先 C++中写好相关函数,文件名为test.cpp,使用g++编译为DLL文件,指令如下: g++ -sha ...

  5. Qt之QProgressIndicator(等待提示框)

    简述 很早以前在网上看到一个纯代码实现的旋转动画感觉效果很不错,分享给大家.不得不说,条条大道通罗马,我们需要更多地创造... 详见:QProgressIndicator 简述 效果 源码 使用 更多 ...

  6. CSS之可折叠导航

    简述 下面我们来讲述如何仅仅用CSS来实现一个可折叠的导航. 简述 nav标签 summary标签 效果 源码 解释 为小三角添加CSS样式 <nav>标签 定义和用法 <nav&g ...

  7. Qt之QLabel

    简述 QLabel提供了一个文本或图像的显示,没有提供用户交互功能. 一个QLabel可以包含以下任意内容类型: 内容 设置 纯文本 使用setText()设置一个QString 富文本 使用setT ...

  8. iso中第三方框架SDWebImage的使用步骤

    一.SDWebImage的使用 1.依赖的框架 * ImageIO.framework * MapKit.framework 2.UIImageView下载图片需要的头文件:UIImageView+W ...

  9. android layoutparams应用指南(转)

    LayoutParams相当于一个Layout的信息包,它封装了Layout的位置.高.宽等信息.假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉L ...

  10. scala学习笔记(4):占位符

    scala 中占位符的用法 1.作为“通配符”,类似Java中的*.如import scala.math._ 2.:_*作为一个整体,告诉编译器你希望将某个参数当作参数序列处理!例如val s = s ...