首先得cd到SPARK目录下,方便操作文件。
- 读取数据创建RDD:
lines=sc.textFlie("README.md")
pythonLines=lines.filter(lambda line: "Python" in line)
经过以上操作,在pythonLines这个对象就包含了在README.md这个文件里所有包含有“Python”这个字符的行。
这里要注意的是,RDD存在两种操作,即转化操作以及行动操作。以上属于转化操作,此时并没有真正的把数据读入到了内存里,只是在内存里形成了一个记录。
- 读取操作RDD
pythonLines.first()
pythonLines.take(3)
pythonLines.collect()
pythonLines.count()
以上三条语句均为查看RDD内容的方法。
第一个是查看包含字符的第一行。第二个是查看包含字符的前三行。第三个是查看包含字符的所有行。最后是对包含字符的行数计数。
对于collect()方法要注意,它是把所有数据读入到内存,所以得注意内存容量大小问题。
- 持久化操作RDD
因为每次进行RDD的行动操作,都会从头开始计算。为了避免这种情况, 可以将中间结果持久化。
pythonLines.persist
- 直接输入数据的parallelize方法
nums= sc.parallelize([1,2,3,4])
lines=sc.parallelize(["Hello world","hi"])
- map与flatmap的转化操作
squared=nums.map(lambda x: x*x ).collect()
//collect使其继续成为一个LIST
words=lines.flatMap(lambda line: lines.split(" "))
//可以用collect()方法调用查看结果,flatmap将所有结果融合为一个LIST
map对每一条输入进行指定的操作,然后为每一条输出产生一个对象。
而flatmap是最后将所有对象合并为一个对象,即flat,拍扁它。
- 一些简单的集合操作
RDD1.distinct() //去掉RDD1中重复元素,开销较大
RDD1.union(RDD2) //集合合并
RDD1.intersection(RDD2) //求交集
RDD1.subtract(RDD2) //去除RDD1里与RDD2有交集的元素
RDD1.cartesian(RDD2) //求笛卡尔积
RDD分区partition概念
- 集群上每一台计算机是一个节点。一个节点可以有一个或者多个worker,一般就配置1个worker。每个worker可以申请一个或多个核心(这里的核心实际上代表起的线程),核心数量一般不超过CPU物理核心数量。
- RDD的每个partition实际上就是一个用来计算的task。这些task被分布在集群里进行并行计算。
由以上两点可知,书中说最好partition的数量设置为跟节点一样,就是为了让所有机器都运转起来,提高并行度。 - spark会为生成的结果RDD 设置好分区方式 的操作有:cogroup()、groupWith()、join()、leftouterJoin()、rightouterJoin()、groupByKey()、reduceByKey()、combineByKey()、partitionBy()、sort()、mapValues()(如果父RDD有分区方式)、flatMapValues()(如果父RDD有分区方式)、以及filter()(如果父RDD有分区方式)。
JSON数据操作
- JSON格式:data={people:{ name : ‘AA’ , age : 25 }}
- 将格式字符串转为JSON: json_str = json.dumps(data)
- 读取并解析JSON数据:result = json.loads(json_str)
- 查询JSON数据: print result[‘name’]
共享变量: 累加器与广播变量
- 累加器提供了将工作节点中的值聚合到驱动器程序中的简单语法,累加器的一个常见用途是在调试时对作业执行过程中的事件进行计数。
- 累加器的实现非常高效,不需要对每次更新操作进行复杂的通信,比如当某个值在并行程序的多个地方增长时,用累加器计数会很方便。
- 广播变量可以高效地向所有工作节点发送一个较大的只读值,以供一个或者多个SPARK操作使用。
- 广播变量只会被发送到各个节点一次,应作为只读值处理。
blankLines = sc.accumulator(0) //创建了一个累加器blankLines,用于统计空行数量,0是指初始值
blankLines.value //可以访问累加器的值
signPrefixes = sc.broadcast(loadCallSignTable())
signPrefixes.value
- Python中的filter( fucthion , List ),该方法可以接收一个函数及一个序列作为参数,也可作为对象的方法被调用
filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。