Dr. Hsieh is teaching how to use the state-of-the-art libraries, Spark by Apache, to conduct data analysis on hadoop platform in ISSNIP 2015, Singapore. He started with teaching the basic operations like “map, reduce, flatten, and more,” followed by explaining the extension of Spark, including MLib, GraphX, and SparkSQL.
25. 25
import java.io.IOException;
import java.util.*;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;
public class WordCount {
//////////// MAPPER function
//////////////
public static class Map extends
MapReduceBase implements
Mapper<LongWritable, Text, Text,
IntWritable> {
public void map(LongWritable key, Text
value, OutputCollector<Text, IntWritable>
output,
Reporter reporter) throws IOException {
String line = value.toString();
StringTokenizer tokenizer = new
StringTokenizer(line);
Text word = new Text();
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
output.collect(word, new IntWritable(1));
}
}
}
//////////// REDUCER function /////////////
public static class Reduce extends MapReduceBase
implements Reducer<Text, IntWritable, Text,
IntWritable> {
public void reduce(Text key, Iterator<IntWritable>
values, OutputCollector<Text,
IntWritable> output, Reporter reporter) throws
IOException {
int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
}
}
public static void main(String[] args) throws
Exception {
/////////// JOB description ///////////
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount");
conf.setMapperClass(Map.class);
conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
FileInputFormat.setInputPaths(conf, new
Path(args[0]));
FileOutputFormat.setOutputPath(conf, new
Path(args[1]));
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);
JobClient.runJob(conf);
}
}
26. 26
a = load ’input.txt';
#map
b = foreach a generate
flatten(TOKENIZE((chararray)$0)) as word;
#reduce
c = group b by word;
d = foreach c generate COUNT(b), group;
store d into ‘wordcount.txt';
29. 29
REGISTER lib.jar;
a = load ’input.txt';
#map
b = foreach a generate
flatten(TOKENIZE((chararray)$0)) as word;
b2 = foreach b generate lib.UPPER(word)
#reduce
c = group b2 by word;
d = foreach c generate COUNT(b), group;
store d into ‘wordcount.txt';
Case In sensitive
30. 30
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class UPPER extends EvalFunc<String>
{
public String exec(Tuple input) throws IOException {
if (input == null || input.size() == 0 || input.get(0) == null)
return null;
try{
String str = (String)input.get(0);
return str.toUpperCase();
}catch(Exception e){
throw new IOException(”Error in input row ", e);
}
}
}
33. 33
chsieh@dev-sfear01:~$ spark-shell --master local[4]
Spark assembly has been built with Hive, including Datanucleus jars on classpath
15/03/26 14:32:12 WARN NativeCodeLoader: Unable to load native-hadoop library for
your platform... using builtin-java classes where applicable
Welcome to
____ __
/ __/__ ___ _____/ /__
_ / _ / _ `/ __/ '_/
/___/ .__/_,_/_/ /_/_ version 1.3.0
/_/
Using Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_76)
Type in expressions to have them evaluated.
Type :help for more information.
Spark context available as sc.
SQL context available as sqlContext.
scala>
49. 49
scala> val data = Array(1, 2, 3, 4, 5)
data: Array[Int] = Array(1, 2, 3, 4, 5)
scala> val distData = sc.parallelize(data)
distData: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[5] at parallelize at
<console>:23
scala> val addone = distData.map(x => x + 1) // Transformation
addone: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[6] at map at
<console>:25
scala> val back = addone.map(x => x - 1) // Transformation
back: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[7] at map at <console>:27
scala> val sum = back.reduce( (l, r) => l + r) // Action
sum: Int = 15
50. 50
Passing functions
Object Util {
def addOne(x:Int) = {
x + 1
}
}
val addone_v1 = distData.map(x => x + 1)
// or
val addone_v2 = distData.map(Util.addOne)
54. 54
More about “persist” -- reuse
Input
(disk)
RDD1
(in memory)
RDD2
(in disk)
RDD3
(in memory)
Output
(disk)
t1 t2 t3
t4
RDD4
(in memory)
persist()
t5
58. 58
val file = sc.textFile("wc.txt")
val counts = file.flatMap(line => line.split(" "))
.map(word => (word, 1))
.reduceByKey( (l, r) => l + r)
// Using SQL syntax is possible
import sqlContext.implicits._
val sq = new org.apache.spark.sql.SQLContext(sc)
case class WC(word: String, count: Int)
val wordcount = counts.map(col => WC(col._1, col._2))
val df = wordcount.toDF()
df.registerTempTable("tbl")
val avg = sq.sql("SELECT AVG(count) FROM tbl")
60. 60
Guess what I’m doing here?
// row: (country, city, profit)
data .filter( _._1 == “us”)
.map ( (a, b, c) => (b, c))
.groupBy( _._1 )
.mapValues( v =>
v.reduce(
(a, b) => (a._1, a._2+b._2)
)
)
.values
.sortBy (x => x._2, false)
.take(3)
61. 61
sq.sql(”
SELECT city, SUM(profit) as p
FROM data
WHERE country=‘us’
GROUP BY city
ORDER BY p DESC
LIMIT 3
")
//(country, city, profit)
data .filter( _._1 == “us”)
.map ( (a, b, c) => (b, c))
.groupBy( _._1 )
.mapValues( v =>
v.reduce(
(a, b) => (a._1,
a._2+b._2)
)
)
.values
.sortBy (x => x._2, false)
.take(3)
Find top 3 cities in US with highest profit
65. 65
import org.apache.spark.mllib.clustering.KMeans
import org.apache.spark.mllib.linalg.Vectors
// Load and parse the data
val data = sc.textFile("kmeans_data.txt")
val parsedData = data.map(s => Vectors.dense(s.split(' ')
.map(_.toDouble))).cache()
// Cluster the data into two classes using KMeans
val numClusters = 2
val numIterations = 20
val clusters = KMeans.train(
parsedData, numClusters, numIterations
)
// Show results
scala> clusters.clusterCenters
res0: Array[org.apache.spark.mllib.linalg.Vector] =
Array([9.099999999999998,9.099999999999998,9.099999999999998],
[0.19999999999999998,0.19999999999999998,0.3])
71. PageRank
PR(p) = PR(p1)/c1 + … + PR(pk)/ck
pi : page pointing to p,
ci : number of links in pi
One equation for every page
N equations, N unknown variables
Credit: Prof. John Cho / CS144 (UCLA)
74. 74
// Load the edges as a graph
val graph = GraphLoader.edgeListFile(sc, "followers.txt")
// Run PageRank
val ranks = graph.pageRank(0.0001).vertices // id, rank
// Join the ranks with the usernames
val users = sc.textFile("users.txt")
.map { line =>
val fields = line.split(",")
(fields(0).toLong, fields(1)) // id, username
}
val ranksByUsername = users.join(ranks).map {
case (id, (username, rank)) => (username, rank)
}
// Print the result
println(ranksByUsername.collect().mkString("n"))