Yann Moisan
Yann Moisan

Follow

May 29, 2018 · 9 min read

Spark is the core component of Teads’s Machine Learning stack. We use it for many ML applications, from ad performance predictions to user Look-alike Modeling. A Sparkot olyan intenzív munkák feldolgozására is használjuk, mint például az eszközök közötti szegmens kiterjesztése vagy a parketta az SSTables transzformációhoz az adatok Cassandra-ba történő betöltéséhez.

A Spark használatával rendszeresen elérjük klasztereink erőforrásainak határait a memória, a lemez vagy a CPU szempontjából. A skála-out csak tolja vissza a kérdést, így van, hogy a kezünket piszkos.

itt található a Spark 2.2.0 legjobb gyakorlatainak és optimalizálási tippjeinek gyűjteménye a jobb teljesítmény és a tisztább Spark kód elérése érdekében, amely magában foglalja:

  • hogyan lehet kihasználni a volfrámot,
  • végrehajtási terv elemzése,
  • adatkezelés (gyorsítótár, műsorszórás),
  • felhővel kapcsolatos optimalizálások (beleértve az S3-at is).

frissítés 07/12/2018, Lásd még a második részt, amely a hibaelhárítási trükköket és a külső adatforrás-kezelést tartalmazza.

Ez a józan ész, de a kód teljesítményének javításának legjobb módja a Spark erősségeinek megragadása. Az egyik a volfrám.

szabvány az 1.5-ös verzió óta a Tungsten egy Spark SQL komponens, amely nagyobb teljesítményt nyújt a Spark műveletek bytecode-ban történő átírásával, futásidőben. A Tungsten elnyomja a virtuális funkciókat és kihasználja a csupasz fém teljesítményét azáltal, hogy a CPU és a memória hatékonyságára összpontosít.

annak érdekében, hogy a lehető legtöbbet hozzuk ki a volfrámból, a következőkre figyelünk:

adatkészlet-struktúrák használata

annak biztosítása érdekében, hogy kódunk a lehető legnagyobb mértékben részesüljön a Tungsten-optimalizálásból, az alapértelmezett adatkészlet-API-t használjuk a Scala-val (az RDD helyett).

a Dataset mindkét világ legjobbjait hozza létre relációs (DataFrame) és funkcionális (RDD) transzformációk keverékével. Ez az API a legfrissebb, és növeli a típusbiztonságot, valamint a jobb hibakezelést és a sokkal olvashatóbb egységteszteket.

azonban kompromisszummal jár, mivel a térkép és a szűrő függvények rosszabbul teljesítenek ezzel az API-val. A keret nélküli ígéretes megoldás ennek a korlátozásnak a kezelésére.

kerülje a felhasználó által definiált függvényeket (UDF-ek) amennyire csak lehetséges

UDF használata deserializációt jelent az adatok klasszikus Scala-ban történő feldolgozásához, majd újraszerkesztéséhez. Az UDF-ek helyettesíthetők Spark SQL funkciókkal, már sok van belőlük, és rendszeresen újakat adnak hozzá.

az UDFs elkerülése nem generálhat azonnali fejlesztéseket, de legalább megakadályozza a jövőbeni teljesítményproblémákat, ha a kód megváltozik. Továbbá, a beépített Spark SQL funkciók használatával csökkentettük tesztelési erőfeszítéseinket, mivel minden a Spark oldalán történik. Ezeket a funkciókat a JVM szakértői tervezték, így az UDF-ek valószínűleg nem érnek el jobb teljesítményt.

például a következő kód helyettesíthető a beépített coalesce funkcióval:

def currency = udf(
(currencySub: String, currencyParent: String) ⇒
Option(currencyParent) match {
case Some(curr) ⇒ curr
case _ ⇒ currencySub
}
)

ha nincs beépített csere, akkor is lehetséges a Catalyst (Spark SQL optimizer) kifejezésosztályának megvalósítása és kiterjesztése. Jól fog játszani a kód generálásával. További részletekért Chris Fregly itt beszélt róla (lásd az 56.dia). Ezzel közvetlenül hozzáférünk a Tungsten formátumhoz, megoldja a sorosítási problémát és a teljesítményt.

kerülje a felhasználó által definiált összesített függvények (UDAFs)

az UDAF SortAggregate műveleteket generál, amelyek lényegesen lassabbak, mint a HashAggregate. Például, amit egy udaf írása helyett teszünk, amely kiszámítja a medián egy beépített ekvivalens (kvantilis 0,5):

df.stat.approxQuantile("value”, Array(0.5), 0)

az approxQuantile függvény a Greenwald-Khanna algoritmus variációját használja. Esetünkben végül 10 – szer gyorsabb volt, mint az egyenértékű UDAF.

kerülje az UDF-eket vagy Udaf-okat, amelyek egynél több dolgot végeznek

a szoftveres kivitelezés alapelvei nyilvánvalóan érvényesek a big data dolgok írásakor (csinálj egy dolgot, és csináld jól). Az UDF-ek felosztásával a kapott kód egy részéhez beépített funkciókat tudunk használni. Ez nagyban leegyszerűsíti a tesztelést is.

2-nézz a motorháztető alá

A Spark végrehajtási tervének elemzése egyszerű módja a lehetséges fejlesztések észlelésének. Ez a terv szakaszokból áll, amelyek a Spark fizikai végrehajtási egységei. Amikor újraírjuk a kódunkat, az első dolog, amit keresünk, az abnormális számú szakasz. A gyanús terv lehet egy igénylő 10 szakaszok helyett 2-3 egy alapvető join művelet két DataFrames.

a Sparkban és általánosabban az elosztott számítástechnikában az adatok hálózaton keresztüli küldése (más néven Shuffle a Sparkban) a legdrágább művelet. A keverések drágák, mivel magukban foglalják a lemez I / O-t, az adatok sorosítását és a hálózati I/O-t.olyan műveletekhez szükségesek, mint a Join vagy a groupBy, és a szakaszok között történnek.

ezt figyelembe véve a szakaszok számának csökkentése nyilvánvaló módja a munka optimalizálásának. Használjuk a .magyarázza el a(true) parancsot, hogy megjelenítse a végrehajtási tervet, amely részletezi a feladat összes lépését (szakaszát). Itt van egy példa:

Simple execution plan example

The Directed Acyclic Graph (DAG) in Spark UI can also be used to visualize the task repartition in each stage.

egy nagyon egyszerű dag példa — kép kredit

Az optimalizálás nagyban támaszkodik mind az adatok ismeretére, mind azok feldolgozására (beleértve. üzleti logika). A Spark SQL optimalizálás egyik korlátja a Catalyst segítségével az, hogy “mechanikus” szabályokat használ a végrehajtási terv optimalizálásához (a 2.2.0-ban).

mint sokan mások, vártunk egy költség-alapú optimalizálási motor túl broadcast csatlakozás kiválasztása. Most úgy tűnik, hogy elérhető a 2.3.0-ban, ezt meg kell vizsgálnunk.

3-Ismerje meg adatait és kezelje hatékonyan

láttuk, hogyan lehet javítani a munka teljesítményét a végrehajtási terv áttekintésével, de rengeteg lehetséges fejlesztés is van az adatoldalon.

erősen kiegyensúlyozatlan adatkészletek

annak gyors ellenőrzéséhez, hogy minden rendben van-e, áttekintjük az egyes feladatok végrehajtási időtartamát, és heterogén folyamatidőt keresünk. Ha az egyik feladat lényegesen lassabb, mint a többi, akkor meghosszabbítja a munka teljes időtartamát, és pazarolja a leggyorsabb végrehajtók erőforrásait.

meglehetősen könnyű ellenőrizni a min, max és medián időtartamot a Spark UI-ban. Itt egy kiegyensúlyozott példa:

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.