初学spark和scala,做些小分析练习,学习资料可以看看这里
如何搭建scala环境和spark环境我就不说了,网上一堆堆的。
本次实例是单机运行的,步骤如下: 1. 模拟2000W人口数据 2. 编写程序分析男女比例分布 3. 编写程序分析人口星座分布
2000W行数据是自己模拟出来的,模拟随机生成人口资料。
package com.soecode.SparkDemo import java.io.PrintWriter /** * 模拟一个城市人口 */ object CreateTestFile { def main(args: Array[String]) { val start = System.currentTimeMillis(); val out = new PrintWriter("d://renkou.txt") for(i <- 1 to 20000000){ out.println(i+","+getName+","+getBirth+","+getSex) } out.close() val end = System.currentTimeMillis(); print("任务结束,耗时:"+(end-start)+"ms") } //随机产生名 def getName:String = { val chs = "abcdefghijklmnopqrstuvwxyz" val len = (1+5*Math.random()).toInt var str ="" for(i<-1 to len){ val l = (0+25*Math.random()).toInt str+=chs(l) } str } //随机产生出生日期 def getBirth:String ={ val year = (1949+67*Math.random()).toInt val month = (1 + 12*Math.random()).toInt val day = (1+30*math.random).toInt year+"-"+month+"-"+day } //随机产生性别 def getSex:Integer=if(Math.random()>0.3) 1 else 0 }代码:
package com.soecode.SparkDemo import org.apache.spark.SparkConf import org.apache.spark.SparkContext import scala.collection.mutable.ArrayBuffer /** * 分析男女分布 */ object StatBG { def main(args: Array[String]) { val conf = new SparkConf().setAppName("Demo").setMaster("local");//spark conf val sc = new SparkContext(conf);//spark上下文 println("任务开始") val start = System.currentTimeMillis(); val lines = sc.textFile("d://renkou.txt")//读取本地文件建立RDD import scala.util.parsing.json.JSON //使用map操作,形成新的集合。 如:Map(1,0,1,1,1) 0 代表女,1代表男 val result = lines.map(s=>{ val sp = s.split(",") sp(3) }).countByValue val end = System.currentTimeMillis(); println("任务结束,耗时:"+(end-start)+"ms"); print(result) } }运行结果:
任务结束,耗时:10114ms Map(0 -> 6001173, 1 -> 13998827)代码:
package com.soecode.SparkDemo import org.apache.spark.SparkConf import org.apache.spark.SparkContext import scala.collection.mutable.ArrayBuffer /** * 分析星座分布 */ object StatBirth { val dayArr = Array[Integer]( 20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 23, 22 ) val constellationArr = Array[String]("摩羯座", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座" ) def main(args: Array[String]) { val conf = new SparkConf().setAppName("Demo").setMaster("local"); val sc = new SparkContext(conf); println("任务开始") val start = System.currentTimeMillis(); val lines = sc.textFile("d://renkou.txt") import scala.util.parsing.json.JSON //RDD进行map操作,获取每行,然后split分割,换算星座返回新的map(金牛座,水瓶座,……) val result = lines.map(s=>{ val sp = s.split(",") val sp_birth = sp(2).split("-") val month = sp_birth(1).toInt val day = sp_birth(2).toInt getConstellation(month, day) }).countByValue val end = System.currentTimeMillis(); println("任务结束,耗时:"+(end-start)+"ms"); for(m <- result) println(m._1 +":"+m._2 ) } //获取星座 def getConstellation(month : Integer, day:Integer) : String = { if(day < dayArr(month - 1)) constellationArr(month - 1) else constellationArr(month) } }运行结果:
任务结束,耗时:12589ms 巨蟹座:1722834 射手座:1610733 双鱼座:1777411 白羊座:1610940 处女座:1668062 双子座:1721596 金牛座:1720431 狮子座:1665213 天秤座:1722568 水瓶座:1613145 天蝎座:1612089 摩羯座:1554978初学spark,前面踩了些坑。例如,如果在操作数据的时候,如果不注重运行效率。会导致程序跑很久。 例如我最开始生成的模拟数据是json格式的。在操作数据的时候使用scala api将json转成对象取值。
效率差到不行。仅仅200W数据就要跑313秒,引以为戒。