Spark目前支持三种开发语言:Scala、Java、Python,目前我们大量使用Python来开发Spark App(Spark 1.2开始支持使用Python开发Spark Streaming App,我们也准备尝试使用Python开发Spark Streaming App),在这期间关于数据类型的问题曾经困扰我们很长时间,故在此记录一下心路历程。
 
Spark是使用Scala语言开发的,Hadoop是使用Java语言开发的,Spark兼容Hadoop Writable,而我们使用Python语言开发Spark (Streaming) App,Spark Programming Guides(Spark 1.5.1)其中有一段文字说明了它们相互之间数据类型转换的关系:
 
 
也说是说,我们需要处理两个方向的转换:
 
(1)Writable => Java Type => Python Type;
(2)Python Type => Java Type => Writable;
 
其中Java Type与Python Type之间数据类型的转换依赖开源组件Pyrolite,相应的数据类型转换如下:
 
(1)Python Type => Java Type;
 
 
(2)Java Type => Python Type;
 
 
也就是说,Pyrolite已经为Java Type与Python Type之间的数据类型转换建立了“标准”,我们仅仅需要处理Writable与Java Type之间的数据转换就可以了。
 
从上图“Writable Support”中可以看出PySpark已经为我们解决了常用的数据类型转换问题,但可以理解为“基本”数据类型,遇到复杂的情况,还是需要我们特殊处理,PySpark已经为我们考虑到了这种业务场景,为我们提供接口Converter(org.apache.spark.api.python.Converter),使得我们可以根据自己的需要扩展数据类型转换机制:
 
 
接口Converter仅仅只有一个方法convert,其中T表示源数据类型,U表示目标数据类型,参数obj表示源数据值,返回值表示目标数据值。
 
Spark Programming Guides(Spark 1.5.1)也为我们举例说明了一个需要自定义Converter的场景:
 
 
ArrayWritable是Hadoop Writable的一种,因为Array涉及到元素数据类型的问题,因此使用时需要实现相应的子类,如元素数据类型为整型:
 
 
从上面的描述可知,PySpark使用ArrayWritable时涉及到如下两个方向的数据类型转换:
 
(1)Tuple => Object[] => ArrayWritable;
(2)ArrayWritable => Object[] => Tuple;
 
我们以IntArrayWritable为例说明如何自定义扩展Converter,同理也需要处理两个方向的数据类型转换:Tuple => Object[] => ArrayWritable、ArrayWritable => Object[] => Tuple。
 
(1)Tuple => Object[] => IntArrayWritable;
 
假设我们有一个list,list的元素类型为tuple,而tuple的元素类型为int,我们需要将这个list中的所有数据以SequenceFile的形式保存至HDFS。对于list中的每一个元素tuple,Pyrolite可以帮助我们完成Tuple => Object[]的转换,而Object[] => IntArrayWritable则需要我们自定义Converter实现。
 
 
PySpark中使用这个Converter写入数据:
 
 
注意:SequenceFile的数据结构为<key, value>,为了简单起见,key指定为com.sina.dip.spark.converter.IntArrayWritable,value指定为org.apache.hadoop.io.NullWritable(即空值)。
 
运行上述程序时,因为有使用到我们自定义的类,因此需要将com.sina.dip.spark.converter.IntArrayWritable、com.sina.dip.spark.converter.ObjectArrayToIntArrayWritableConverter编译打包为独立的Jar:converter.jar,并通过参数指定,如下:
 
/usr/lib/spark-1.5.1-bin-2.5.0-cdh5.3.2/bin/spark-submit --jars converter.jar 1.5.1/examples/app/spark_app_save_data_to_seqfile.py
 
(2)IntArrayWritable => Object[] => Tuple;
 
我们需要将(1)中写入SequenceFile的Key(IntArrayWritable)还原为list,其中list的元素类型为tuple,tuple的元素类型为int,IntArrayWritable => Object[]也需要用到我们自定义的Converter(Object[] => Tuple由Pyrolite负责):
 
 
PySpark使用这个Converter读取数据:
 
 
同(1),我们需要将com.sina.dip.spark.converter.IntArrayWritable、com.sina.dip.spark.converter.IntArrayWritableToObjectArrayConverter编译打包为独立的Jar:converter.jar,并通过参数指定,如下:
 
/usr/lib/spark-1.5.1-bin-2.5.0-cdh5.3.2/bin/spark-submit --jars converter.jar 1.5.1/examples/app/spark_app_read_data_from_seqfile.py
 
输出结果:
 
 
可以看出,通过自定义扩展的Converter:com.sina.dip.spark.converter.ObjectArrayToIntArrayWritableConverter、com.sina.dip.spark.converter.IntArrayWritableToObjectArrayConverter,我们实现了IntArrayWritable(com.sina.dip.spark.converter.IntArrayWritable)与Tuple(Python)之间的转换。
 
 

Spark PySpark数据类型的转换原理—Writable Converter的更多相关文章

  1. 开发板A/D转换原理

    A/D转换器(Analog-to-Digital Converter)又叫模/数转换器,即使将模拟信(电压或是电流的形式)转换成数字信号.这种数字信号可让仪表,计算机外设接口或是微处理机来加以操作或是 ...

  2. adc转换原理

    模数转换器即A/D转换器,或简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件.通常的模数转换器是将一个输入电压信号转换为一个输出的数字信号.由于数字信号本身不具有实际意义,仅仅表示一个相对大 ...

  3. java学习笔记(3)数据类型、源码、反码、补码、精度损失、基本数据类型互相转换

    关于java中的数据类型: 1.数据类型的作用是什么? 程序当中有很多数据,每一个数据都是有相关类型的,不同数据类型的数据占用的空间大小不同. 数据类型的作用是指导java虚拟机(JVM)在运行程序的 ...

  4. java中数据类型的转换

    数据类型的转换,分为自动转换和强制转换. 自动转换是程序执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换 强制转换必须在代码中声明,转换顺序不受限制 自动数据类 ...

  5. Java的基本数据类型与转换

    1.1 Java为什么需要保留基本数据类型 http://www.importnew.com/11915.html 基本数据类型对大多数业务相关或网络应用程序没有太大的用处,这些应用一般是采用客户端/ ...

  6. java的数据类型的转换

    一:java的数据类型转换除布尔类型boolean(不能转换)有两种:<一> 自动转换: <二> 强制转换 <一>.自动转换:就是将小的数据类型自动转换成大的数据类 ...

  7. JavaScript学习笔记——数据类型强制转换和隐式转换

    javascript数据类型强制转换 一.转换为数值类型 Number(参数) 把任何的类型转换为数值类型 A.如果是布尔值,false为0,true为1 B.如果是数字,转换成为本身.将无意义的后导 ...

  8. eclipse 提交作业到JobTracker Hadoop的数据类型要求必须实现Writable接口

    问:在eclipse中的写的代码如何提交作业到JobTracker中的哪?答:(1)在eclipse中调用的job.waitForCompletion(true)实际上执行如下方法 connect() ...

  9. JAVA数据类型自动转换,与强制转换

    一.数据类型自动转换 public class Test{ public static void main(String[] args){ int a = 1; double b = 1.5; dou ...

随机推荐

  1. JavaScript单例模式

    一.什么是单例 意思是指获取的对象只有一份. 二.最通用的单例 任何时刻获取SingLeton.instance都是同一个对象 var SingLeton={ instance:{ property: ...

  2. 学习java随笔第五篇:流程控制

    条件语句 if(表达式){方法体}else if(表达体)else{方法体} 简写形式:if... 一般形式:if...else... 完整形式:if...else if...else 分支语句 sw ...

  3. ca-bundle.crt to java truststore(e.g. trustStore.jks)

    1. download java keyutilhttps://java-keyutil.googlecode.com/files/keyutil-0.4.0.jar 2. run the follo ...

  4. [DB2]实现项目多数据库切换(上)--环境部署

    基本软硬件信息:Windows 8.1 X64 / Microsoft Visual Studio 2012  / ThinkPad S3-S431 安装工具:IBM Data Studio 4.1. ...

  5. JavaScript中Ajax的get和post请求

    AJAX = 异步 JavaScript和XML(Asynchronous JavaScript and XML) 作用:在不重新加载整个网页的情况下,对网页的某部分进行更新.   两种请求方式: 1 ...

  6. 找不好重现的bug的一个小技巧————守株待兔

    最近碰到一个问题就是数据库中偶尔出现一条没有id的数据,可恨的是怎么也找不到重现这个问题的原因,只好换种方式来找了,那么就是我标题所说的守株待兔方法. 因为我发现出现bug的数据库里面的数据有个字段为 ...

  7. grub2 使用memdisk工具 启动任意iso

    root@zhanghua-Inspiron-:/home/zhanghua# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda6 60G 12G 46G 21% / none ...

  8. JS判断浏览器类型以及版本号

    <script type="text/javascript">        (function(){            window.nav={};       ...

  9. [CSS]float&clear浮动

    CSS float 属性 浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止. 由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样.  可取的值 ...

  10. CSS2简写代码(优化)

    [1]如果CSS属性值为0,那么你不必为其添加单位(如:px/em): 下面是你可能的写法: padding: 10px 5px 0px 0px; 但是你可能这样写: padding: 10px 5p ...