Spark vs. PL/SQL

Preview:

Citation preview

Spark vs. PL/SQLChristopher ThomsenSenior Consultant

OPITZ CONSULTING Deutschland GmbH

Marian StrübySenior Consultant

1Spark?Was ist

Fast and ExpressiveCluster Computing System

Skalierungsframework für

Sparks Kernkonzept●Transformationen auf verteilten Resilent Distributed Datasets ausführen●Verteilung der Daten im „shared-nothing Cluster“ im Arbeitsspeicher oder der Festplatte

Mit RDDs arbeiten

RDDRDDRDDRDD Transformation

Aktion Result

val file = sc textFile “myfile.csv“ val data = file map (_ split “;“)

data saveAsTextFile “myresult.txt“

2Hadoop?Und was ist dieses

Hadoop ist ...●ein Framework für die Verwaltung von Cluster-Kapazitäten.●eine Software, welche Redundanz und Lastverteilung gewährleistet.●auf Skalierung mit kostengünstiger commodity Hardware ausgelegt.●eine Open-Source Plattform für viele andere Werkzeuge.

Hersteller nutzen Hadoop um ...●ihre Software leichter skalierbarer zu machen.●performanceoptimierte Appliancelösungen anbzubieten.●eine kostengünstige Storagealternative anbieten zu können.

Data Node Data Node Data Node

Data Node Data Node Data Node

Master Node iDie Hadoop Infrastruktur bietet mit YARN eine standardisierte Skalierungsplattform für hunderte Spezialistenwerkzeuge.

Data Node Data Node Data Node

Data Node Data Node Data Node

Master Node KonsumentiDas Hadoop Filesystem (HDFS) bietet eine redundante und lastverteilte Storageplattform für aufliegende Applikationen.

Cluster

Betriebs-system YARN, Mesos

Server x86, ARM

Algorithmus MapReduce, Tez, Slider,Spark, Flink

SpracheJava, Scala, Python, HiveQL, PigLatin, ...

Applikation Datameer, RapidMiner,Big Data Discovery, ...

Beowulf, Aiyara

Meine Applikation

Spark Context

Cluster Manager

Worker

SparkExecutor

HDFS

Worker

SparkExecutor

Worker

SparkExecutor

3programmiertUnd wie

010010010101001001101101101010101001111010111

Man in Spark?

Unterstützte ProgrammiersprachenKriterium Scala Python Java RStandalone Programme X X XInteraktive Shell X X XNative Performance X XNative Collections X X

val result = sc textFile “myfile.csv“ map (_ split “;“) filter (_(1) contains “Spark“)

result = sc.textFile(“myfile.csv“).map(lambda s: s.split(“;“)).filter(lambda s: “Spark“ in s[1])

JavaRDD<String[]> result = sc.textFile(“myfile.csv“).map.(new Function<String, String[]> () {String[] call(String s) { return s.split(“;“); }

}).filter(new Function<String[], Boolean>() {Boolean call(String[] s) { return s[1].contains(“Spark“); }

})

df <- lapply(textFile(sc, “myfile.csv“) function(s) { strsplit(s, “;“) })result <- filter(df, grepl(df[1], “Spark“)

4Oracle Datenbank?

Aber geht das nicht auch in PL/SQL mit meiner

Relationale Datenbanken sind ...●Allrounder●ACID konform●für interaktive Nutzung durch Konsumenten ausgelegt

Sie scheitern häufig an ...●Datenvolumen im Terabytebereich●Streaming Applikationen●nicht tabellarischen Daten●Kostenstrukturen für Low Value Daten●Anforderungen die Spezialistentools benötigen

C

A

P

Eine Datenbankkann nur 2 dieserKriterien erfüllen

Consistency Partitiontolerance

Availability

Viele Hadoop Tools sind ...●Batchorientierte Werkzeuge●Generische Plattformen●Auf maximalen Datendurchsatz optimiert●für die Verwaltung sehr großer Dateien und Tabellen optimiert

Sie sind NICHT geeignet für ..●wahlfreie Zugriffe●Abfragen mit niedriger Latenzanforderung●direkten Zugriff durch Endkonsumenten●Die Arbeit mit vielen kleinen Dateien oder vielen kleinen Tabellen

PL/SQL Sprachgrundlagen im Vergleich

CREATE FUNCTION myFunc(someNum IN NUMBER)

RETURN NUMBERIS

result NUMBER := 0;BEGIN

FOR a in (SELECT num FROM someTable)LOOP

BEGINIF a.num < 2 ** someNum THEN

result := result – a.num / 2;ELSE

result := result + a.num - 1END;

END LOOP;END;

def myFunc(someNum: Long) = {Sc textFile "someTable" map { a =>

val num = a.numif (num < math.pow(2, someNum))

num / 2else

num - 1} reduce (_ + _)

}

PL/SQL Spark

Schleife

Funktions-signatur

Map und ReduceSchritt stattZählervariable

Orderid NUMBERclient NUMBERitem NUMBERamount FLOATstatus VARCHARmodified DATE

Clientid NUMBERname VARCHARaddress VARCHARcity VARCHARcountry VARCHAR

Itemid NUMBERname VARCHARprice FLOATdensity FLOAT

New Orders

PriceHistoryid NUMBERitem NUMBERprice FLOATvalid DATE

Report

Orderid NUMBERclient NUMBERitem NUMBERamount FLOATstatus VARCHARmodified DATE

SELECT *FROM OrderWHERE amount >= 1AND status LIKE 'Transport%';

SELECT client, ROUND(amount)FROM Order;

SELECT COUNT(DISTINCT client) FROM OrderWHERE modified >= '2015-11-17';

SELECT item, SUM(amount)FROM orderGROUP BY amount;

order filter (o => o.amount >= 1&& o.status startsWith "Transport")

order map (o => o.client -> o.amount.toInt)

(order filter (_.modified.getTime >= format parse "2015-11-17") map (_.client) distinct

).count

order map (o => o.item -> o.amount)reduceByKey (_ + _)

case class Order(id: Long, client: Long,item: Long, amount: Float,status: String, modified: Date)

val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

val order = sc textFile "Order.csv" map (_ split ";")map (o => new Order((0).toLong, o(1).toLong,

o(2).toLong, o(3).toFloat, o(4), dateFormat parse o(5))

SQL Spark

Orderid NUMBERclient NUMBERitem NUMBERamount FLOATstatus VARCHARmodified DATE

Itemid NUMBERname VARCHARprice FLOATdensity FLOAT

Clientid NUMBERname VARCHARaddress VARCHARcity VARCHARcountry VARCHAR

Wie viel m³ werden heute in Richtung Südkorea verschifft?

SQL Spark

SELECT SUM(o.amount / i.density)FROM Order oINNER JOIN Client cON o.client = c.idINNER JOIN Item iON o.item = i.idWHERE o.status = 'Transport via See'AND c.country = 'Südkorea'AND o.modified >= '2015-11-17'

val itemPair = item map (i => i.id -> i)val targetClient = client filter (

_.country == "Südkorea") map (_.id) first

order filter {o => o.status == "Transport via See"&& o.modified.getTime >= new Date().getTime

} map (o => o.item -> o) join itemPair map {e => e._2._1.amount / e._2._2.density

} reduce (_ + _)

neworder.csv

Orderid NUMBERclient NUMBERitem NUMBERamount FLOATstatus VARCHARmodified DATE

Clientid NUMBERname VARCHARaddress VARCHARcity VARCHARcountry VARCHAR

1;ArcelorMittal;Avenue de la Liberte 12;Luxemburg;Luxemburg2;Hebei Iron and Steel;Shijiazhuang;Hebei;China3;POSCO;Dongchon-dong 5;Pohang;Südkorea4;Tata Steel;Bombay House 24;Mumbai;Indien5;Gerdau;Av. Farrapos 1811;Porto Alegre;Brasilien6;ThyssenKrupp;Mannesmannstraße 101;Duisburg;Deutschland7;Evraz;6 Saint Andrew Street;London;Vereinigtes Königreich8;Severstal;ul. Stalevarov 45А;Cherepovets;Russland

1010;Hebei Iron and Steel;Shijiazhuang;Hebei;China;Zink;54.07;2015-11-15 09:26:28

1011;Nucor;1915 Rexford Rd 400;Charlotte;Vereinigte Staaten von Amerika;Zink;9.01;2015-11-15 05:27:19

1012;Gerdau;Av. Farrapos 1811;Porto Alegre;Brasilien;Nickel;69.53;2015-11-15 12:47:05

Neue Datensätze hinzufügen

neworder.csv

SQL Spark

INSERT into clientSELECT seq_dim_client.nextval, a.name, a.address, a.city, a.countryFROM ( SELECT DISTINCT s.client_name,s.address, s.city, s.country FROM ext_neworder s WHERE NOT EXISTS ( SELECT 'x' FROM client t WHERE s.client_name = t.name AND s.address = t.address AND s.city = t.city AND s.country = t.country)) a

val nextClientId = client.reduce((a, b) =>if (a.id > b.id) a else b) map (_.id)

{{

neworder filter (o => !(client exists {c => c.name == o.clientName

&& c.address == o.address&& c.city == o.city&& c.country == o.country

})}.distinct.zipWithIndex map (

o => new Client(nextClientId + o._2,o._1.clientName, o._1.address,o._1.city, o._1.country))

++ client} saveAsTextFile "stage/client.csv“

Clientid NUMBERname VARCHARaddress VARCHARcity VARCHARcountry VARCHAR

Itemid NUMBERname VARCHARprice FLOATdensity FLOAT

PriceHistoryid NUMBERitem NUMBERprice FLOATvalid DATE

SQL Spark

INSERT into price_historySELECT seq_price_history.nextval, s.id, s.price, sysdateFROM ext_item sWHERE NOT EXISTS ( SELECT 'x' FROM price_history t JOIN ( SELECT id, MAX(valid) valid FROM price_history GROUP BY id ) h ON t.id = h.id AND t.valid = h.valid WHERE s.id = t.item AND s.price = t.price);

val recentPrice = priceHistory groupBy (_.item)map (p => p._1 -> p._2 sortBy (_.valid) last)

{{

item map (i => i.name -> new )leftOuterJoin recentPricefilter (_._2._2.isEmpty)map (_._2._1)

} ++ priceHistory} saveAsTextFile "stage/priceHistory.csv“

● Hadoop - Eine Erweiterung für die Oracle DB? (Matthias Fuchs) 17.11.2015 16:00 Uhr Kiew

● Using Analytical SQL to Intelligently Explore Big Data (Keith Laker) 18.11.2015 17:00 Uhr Oslo

● How to choose between Hadoop, NoSQL or Oracle Database (Jean-Pierre Dijcks) 19.11.2015 12:00 UhrStockholm

● Big Data Processing mit Spark (Matthias Höreth)20.11.2015 9:00 Uhr Helsinki

Weitere Vorträge zu diesem Thema auf der DOAG ...

27

•BI Community Event im Rahmen der DOAG K+ADi. 17.11.2015 ab 18:30 im Landbierparadies Nürnberg Wodanstr. 15

•Unconference: OWB – Was Nun?Di. 17.11.2015 / 15 Uhr

•Data Vault ForumMi. 18.11.2015 / 15 Uhr Galileo Lounge, Ebene 3

•Data Integration Day 2015Mi. 9.12.2015 / 10 Uhr, Sulzbach (Taunus)

•DOAG BI8.-9.6.2016, Bonn, Kameha

BI Community - Veranstaltungen

28

TO DO BIG DATA

Viel Spaßauf derDOAG

Konferenz

© OPITZ CONSULTING GmbH 2015Seite 30Enterprise Big Data Testmanagement

Kontakt

Christopher Thomsen, Senior Consultant

OPITZ CONSULTING GmbHchristopher.thomsen@opitz-consulting.comTelefon +49 40 741122 1350Mobil +49 173 7279604

Marian Strüby, Senior Consultant

OPITZ CONSULTING GmbHmarian.strueby@opitz-consulting.comTelefon +49 30 6298889 1625Mobil +49 173 7279144

youtube.com/opitzconsulting

@OC_WIRE

slideshare.net/opitzconsulting

xing.com/net/opitzconsulting

Recommended