RDD
一、简述
RDD:核心抽象
一个RDD在抽象上代表一个hdfs文件,
分布式数据集:元素集合包含数据,实际上是被分区的,分为多个分区散落在spark集群中的不同节点(一批节点上的一批数据就是RDD)。
最重要特性:提供了容错性,节点失败中自动恢复。默认放在内存,内存不够,被写入磁盘。
二、RDD的创建
第一种创建方式:从文件中加载
>>> lines = sc.textFile("file:///usr/local/spark/mycode/pairrdd/word.txt") >>> pairRDD = lines.flatMap(lambda line : line.split(" ")).map(lambda word : (word,1)) >>> pairRDD.foreach(print)
第二种创建方式:通过并行集合(列表)创建RDD
>>> list = ["Hadoop","Spark","Hive","Spark"] >>> rdd = sc.parallelize(list) >>> pairRDD = rdd.map(lambda word : (word,1)) >>> pairRDD.foreach(print)
三、常用键值对转换
>>> pairRDD.reduceByKey(lambda a,b : a+b).foreach(print)(对相同键值对合并) >>> pairRDD.groupByKey().foreach(print)(对RDD进行分组操作) >>> pairRDD.keys().foreach(print)(采用keys()后得到的结果是一个RDD[Int],内容是{“spark”,”spark”,”hadoop”,”hadoop”}) >>> pairRDD.keys().foreach(print)(采用values()后得到的结果是一个RDD[Int],内容是{1,2,3,5}) >>> pairRDD.sortByKey().foreach(print)(sortByKey()的功能是返回一个根据键排序的RDD。) >>> pairRDD.mapValues( lambda x : x+1).foreach(print)(对values进行改变)
>>> pairRDD1 = sc.parallelize([('spark',1),('spark',2),('hadoop',3),('hadoop',5)]) >>> pairRDD2 = sc.parallelize([('spark','fast')]) >>> pairRDD1.join(pairRDD2) 【内链接rdd】
综合操作
>>>rdd = sc.parallelize([("spark",2),("hadoop",6),("hadoop",4),("spark",6)]) >>>rdd.mapValues(lambda x : (x,1)).reduceByKey(lambda x,y : (x[0]+y[0],x[1] + y[1])).mapValues(lambda x : (x[0] / x[1])).collect()
流程解释:1.mapvalues把 rdd变成('spark', (2, 1))('hadoop', (4, 1))2.reducebykey把rdd变成('hadoop', (10, 2))('spark', (8, 2))3.再mapvalues得到[('hadoop', 5.0), ('spark', 4.0)]结果
四、从RDD转换得到DataFrame
1)利用反射机制推断RDD模式
>>> from pyspark.sql.types import Row >>> def f(x): ... rel = {} ... rel['name'] = x[0] ... rel['age'] = x[1] ... return rel ... >>>peopleDF=sc.textFile("file:///usr/local/spark/examples/src/main/resources/people.txt").map(lambda line : line.split(',')).map(lambda x: Row(**f(x))).toDF() >>> peopleDF.createOrReplaceTempView("people") //必须注册为临时表才能供下面的查询使用 >>> personsDF = spark.sql("select * from people") >>> personsDF.rdd.map(lambda t : "Name:"+t[0]+","+"Age:"+t[1]).foreach(print)
2)编程方程式定义RDD模式
>>> from pyspark.sql.types import Row >>> from pyspark.sql.types import StructType >>> from pyspark.sql.types import StructField >>> from pyspark.sql.types import StringType //生成 RDD >>> peopleRDD = sc.textFile("file:///usr/local/spark/examples/src/main/resources/people.txt") //定义一个模式字符串 >>> schemaString = "name age" //根据模式字符串生成模式 >>> fields = list(map( lambda fieldName : StructField(fieldName, StringType(), nullable = True), schemaString.split(" "))) >>> schema = StructType(fields) //从上面信息可以看出,schema描述了模式信息,模式中包含name和age两个字段 >>> rowRDD = peopleRDD.map(lambda line : line.split(',')).map(lambda attributes : Row(attributes[0], attributes[1])) >>> peopleDF = spark.createDataFrame(rowRDD, schema) //必须注册为临时表才能供下面查询使用 scala> peopleDF.createOrReplaceTempView("people") >>> results = spark.sql("SELECT * FROM people") >>>results.rdd.map( lambda attributes : "name: " + attributes[0]+","+"age:"+attributes[1]).foreach(print)
五、将RDD保存为文件
第一种: peopleDF=spark.read.format("json").load("file:///usr/local/spark/examples/src/main/resources/people.json") peopleDF.select("name","age").write.format("csv").save("file:///usr/local/spark/mycode/newpeople.csv")
第二种: >>>peopleDF=spark.read.format("json").load("file:///usr/local/spark/examples/src/main/resources/people.json" >>> peopleDF.rdd.saveAsTextFile("file:///usr/local/spark/mycode/newpeople.txt")