Bevezetés a Spark Graph feldolgozásába GraphFrame-ekkel

1. Bemutatkozás

A grafikonfeldolgozás számos alkalmazásban hasznos, a közösségi hálózatoktól a hirdetésekig. Nagy adatforgalom esetén szükségünk van egy eszközre a feldolgozási terhelés elosztására.

Ebben az oktatóanyagban betöltjük és feltárjuk a grafikon lehetőségeit a Java Apache Spark használatával. Az összetett struktúrák elkerülése érdekében egy egyszerű és magas szintű Apache Spark graph API-t fogunk használni: a GraphFrames API-t.

2. Grafikonok

Mindenekelőtt definiáljunk egy gráfot és annak összetevőit. A grafikon olyan adatstruktúra, amelynek élei és csúcsai vannak. A az élek információt hordoznak amely a csúcsok közötti kapcsolatokat ábrázolja.

A csúcsok az an pontjai n-dimenziós tér, és az élek összekapcsolják a csúcsokat kapcsolataik szerint:

A fenti képen van egy közösségi hálózati példa. Láthatjuk a betűkkel ábrázolt csúcsokat és az éleket, amelyek a csúcsok között milyen kapcsolatot mutatnak.

3. Maven Setup

Kezdjük a projektet a Maven konfigurációjának beállításával.

Tegyük hozzá spark-graphx 2.11,grafikonvázak, és szikra-sql 2.11:

 org.apache.spark spark-graphx_2.11 2.4.4 graphframes graphframes 0.7.0-spark2.4-s_2.11 org.apache.spark spark-sql_2.11 2.4.4 

Ezek a műtárgy-verziók támogatják a Scala 2.11-et.

Az is előfordul, hogy a GraphFrames nincs a Maven Centralban. Tehát tegyük hozzá a szükséges Maven-tárat is:

  SparkPackagesRepo //dl.bintray.com/spark-packages/maven 

4. Szikra konfigurálása

A GraphFrames használatához le kell töltenünk a Hadoop-ot és meg kell határoznunk a HADOOP_HOME környezeti változó.

A Windows, mint operációs rendszer esetén a megfelelő verziót is letöltöttük winutils.exe hoz HADOOP_HOME / bin mappába.

Ezután kezdjük el kódunkat az alapkonfiguráció létrehozásával:

SparkConf sparkConf = new SparkConf () .setAppName ("SparkGraphFrames") .setMaster ("local [*]"); JavaSparkContext javaSparkContext = új JavaSparkContext (sparkConf);

Létre kell hoznunk a SparkSession:

SparkSession munkamenet = SparkSession.builder () .appName ("SparkGraphFrameSample") .config ("spark.sql.warehouse.dir", "/ fájl: C: / temp") .sparkContext (javaSparkContext.sc ()) .master ( "helyi [*]") .getOrCreate ();

5. Grafikonszerkezet

Most mindannyian készen állunk a fő kódunkra. Tehát definiáljuk a csúcsok és élek entitásait, és hozzuk létre a GraphFrame példa.

Dolgozunk a felhasználók közötti kapcsolatokon egy hipotetikus társadalmi hálózatról.

5.1. Adat

Először ebben a példában definiáljuk mindkét entitást Felhasználó és Kapcsolat:

public class Felhasználó {private Long id; privát karakterlánc neve; // konstruktor, getterek és beállítók} public class Kapcsolat megvalósításai Serializable {private String type; privát String src; privát húr dst; privát UUID azonosító; public Relationship (String típus, String src, String dst) {this.type = típus; ez.src = src; ez.dst = dst; this.id = UUID.randomUUID (); } // szerelők és beállítók}

Ezután definiáljunk néhányat Felhasználó és Kapcsolat példányok:

Felhasználók listája = new ArrayList (); users.add (új felhasználó (1L, "John")); users.add (új felhasználó (2L, "Martin")); users.add (új felhasználó (3L, "Peter")); users.add (új felhasználó (4L, "Alicia")); Listakapcsolatok = new ArrayList (); kapcsolatok.add (új Kapcsolat ("Barát", "1", "2")); kapcsolatok.add (új Kapcsolat ("Követés", "1", "4")); kapcsolatok.add (új Kapcsolat ("Barát", "2", "4")); kapcsolatok.add (új Kapcsolat ("Rokon", "3", "1")); kapcsolatok.add (új Kapcsolat ("Rokon", "3", "4"));

5.2. GraphFrame Példa

A kapcsolati grafikon létrehozása és kezelése érdekében létrehozunk egy példányt GraphFrame. A GraphFrame a kivitelező kettőre számít Adatkészlet példányok: az első a csúcsokat, a második a széleket jelöli:

Adatkészlet userDataset = session.createDataFrame (users, User.class); Adatkészlet relationshipDataset = session.createDataFrame (kapcsolatok, Relation.class); GraphFrame graph = új GraphFrame (userDataframe, relationshipDataframe);

Végül naplózza a csúcsokat és az éleket a konzolon, hogy lássa, hogyan néz ki:

graph.vertices (). show (); graph.edges (). show ();
+ --- + ------ + | id | név | + --- + ------ + | 1 | János | | 2 | Martin | | 3 | Péter | | 4 | Alicia | + --- + ------ + + --- + -------------------- + --- + -------- - + | dst | id | src | típus | + --- + -------------------- + --- + --------- + | 2 | 622da83f-fb18-484 ... | 1 | Barát | | 4 | c6dde409-c89d-490 ... | 1 | Követve | | 4 | 360d06e1-4e9b-4ec ... | 2 | Barát | | 1 | de5e738e-c958-4e0 ... | 3 | Rokon | | 4 | d96b045a-6320-4a6 ... | 3 | Rokon | + --- + -------------------- + --- + --------- +

6. Grafikon operátorok

Most, hogy van egy GraphFrame lássuk, mit tehetünk vele.

6.1. Szűrő

A GraphFrames lehetővé teszi számunkra az élek és csúcsok szűrését egy lekérdezés alapján.

Ezután szűrjük le a csúcsokat a név ingatlan a Felhasználó:

graph.vertices (). filter ("name = 'Martin'"). show ();

A konzolon láthatjuk az eredményt:

+ --- + ------ + | id | név | + --- + ------ + | 2 | Martin | + --- + ------ +

Ezenkívül hívással közvetlenül szűrhetünk a grafikonon filterEdges vagy filterVertices:

graph.filterEdges ("type = 'Friend'") .dropIsolatedVertices (). csúcsok (). show ();

Most, hogy leszűrtük az éleket, lehet, hogy van még néhány elszigetelt csúcsunk. Tehát, felhívjuk dropIsolatedVertices ().

Ennek eredményeként van egy részgrammunk, még mindig a GraphFrame például csak a „Friend” státuszú kapcsolatokkal:

+ --- + ------ + | id | név | + --- + ------ + | 1 | János | | 2 | Martin | | 4 | Alicia | + --- + ------ +

6.2. Fokozat

Egy másik érdekes funkciókészlet a fok műveletek összessége. Ezek a műveletek visszaadják az egyes csúcsokra eső élek számát.

A fok A művelet csak az egyes csúcsok összes élének számát adja vissza. Másrészről, inDegrees csak a bejövő éleket számolja, és outDegrees csak a kimenő éleket számolja.

Számoljuk meg grafikonunkban az összes csúcs bejövő fokát:

graph.inDegrees (). show ();

Ennek eredményeként van egy GraphFrame amely az egyes csúcsok bejövő éleinek számát mutatja, kivéve azokat, amelyeknek nincsenek csúcsai:

+ --- + -------- + | id | inDegree | + --- + -------- + | 1 | 1 | | 4 | 3 | | 2 | 1 | + --- + -------- +

7. Grafikon algoritmusok

A GraphFrames népszerű használatra kész algoritmusokat is kínál - vessünk egy pillantást ezekre.

7.1. Page Rank

A Page Rank algoritmus a beérkező éleket egy csúcsra súlyozza, és ponttá alakítja.

Az elképzelés az, hogy minden bejövő él egy jóváhagyást képvisel, és a csúcsot relevánsabbá teszi az adott grafikonon.

Például egy közösségi hálózatban, ha egy embert különféle emberek követnek, akkor magas rangsorban lesz.

Az oldalrangsor algoritmus futtatása meglehetősen egyszerű:

graph.pageRank () .maxIter (20) .resetProbability (0.15) .run () .vertices () .show ();

Az algoritmus konfigurálásához csak meg kell adnunk:

  • maxIter - a futtatható oldalrész ismétléseinek száma - 20 ajánlott, túl kevés csökkenti a minőséget, és túl sok rontja a teljesítményt
  • resetProbability - a véletlenszerű visszaállítás valószínűsége (alfa) - minél alacsonyabb, annál nagyobb lesz a pontszám eloszlása ​​a nyertesek és a vesztesek között - az érvényes tartományok 0 és 1 között vannak.

A válasz hasonló GraphFrame, bár ezúttal egy további oszlopot látunk, amely megadja az egyes csúcsok oldalrangsorát:

+ --- + ------ + ------------------ + | id | név | pagerank | + --- + ------ + ------------------ + | 4 | Alicia | 1.9393230468864597 | | 3 | Péter | 0,4848822786454427 | | 1 | János | 0,7272991738542318 | | 2 | Martin | 0,848495500613866 | + --- + ------ + ------------------ +

Grafikonunkban Alicia a legrelevánsabb csúcs, őt Martin és John követi.

7.2. Csatlakoztatott alkatrészek

Az összekapcsolt komponensek algoritmusa izolált klasztereket vagy izolált algráfokat talál. Ezek a klaszterek összekapcsolt csúcsok halmazai egy gráfban, ahol minden csúcs elérhető ugyanazon halmaz bármely más csúcsától.

Az algoritmust paraméterek nélkül hívhatjuk meg a connectedComponents () módszer:

graph.connectedComponents (). run (). show ();

Az algoritmus a GraphFrame amely tartalmazza az egyes csúcsokat és az összetevőket, amelyekhez kapcsolódnak:

+ --- + ------ + ------------ + | id | név | alkatrész | + --- + ------ + ------------ + | 1 | János | 154618822656 | | 2 | Martin | 154618822656 | | 3 | Péter | 154618822656 | | 4 | Alicia | 154618822656 | + --- + ------ + ------------ +

Grafikonunk csak egy komponenst tartalmaz - ez azt jelenti, hogy nincsenek külön algráfjaink. A komponensnek automatikusan generált azonosítója van, esetünkben 154618822656.

Bár itt van még egy oszlopunk - a komponens azonosítója -, a grafikonunk továbbra is ugyanaz.

7.3. Háromszög számlálás

A háromszögszámlálást általában közösségi észlelésként és számlálásként használják a közösségi háló grafikonján. A háromszög három csúcs halmaza, ahol minden csúcs kapcsolatban áll a háromszög másik két csúcsával.

A közösségi hálózatok közösségében könnyű megtalálni jelentős számú háromszöget, amelyek összekapcsolódnak egymással.

Könnyedén elvégezhetünk egy háromszög számlálást közvetlenül a mi számunkra GraphFrame példa:

graph.triangleCount (). run (). show ();

Az algoritmus visszatér a GraphFrame az egyes csúcsokon áthaladó háromszögek számával.

+ ----- + --- + ------ + | számít | id | név | + ----- + --- + ------ + | 1 | 3 | Peter | | 2 | 1 | János | | 2 | 4 | Alicia | | 1 | 2 | Martin | + ----- + --- + ------ +

8. Következtetés

Az Apache Spark nagyszerű eszköz releváns mennyiségű adat optimalizált és elosztott módon történő kiszámításához. És a GraphFrames könyvtár lehetővé teszi számunkra, hogy könnyen oszthatja el a gráfműveleteket a Spark felett.

Mint mindig, a példa teljes forráskódja elérhető a GitHubon.