Seit 2014 ist Snow­flake Inc. mit dem gleich­na­mi­gen Cloud­da­ta­ware­house am Markt. In den ver­gan­ge­nen Jah­ren konnte Snow­flake dabei eine rasante Ent­wick­lung erfah­ren und wird heute bran­chen­über­grei­fend ein­ge­setzt. Haupt­trei­ber für den gro­ßen Erfolg ist die beson­dere Archi­tek­tur von Snow­flake, da das Data­ware­house, anders als viele Wett­be­wer­ber, aus­schließ­lich und nativ für die Cloud ent­wi­ckelt wurde und daher mit her­aus­ra­gen­der Ska­lier­bar­keit und Per­for­mance punk­ten kann. Aktu­ell steht Snow­flake auf AWS, Azure und GCP zur Ver­fü­gung und über­zeugt dort mit wei­te­ren Vor­tei­len, unter ande­rem der unab­hän­gi­gen Ska­lier­bar­keit von Sto­rage- und Com­pu­teres­sour­cen, aus­ge­präg­ten Data­sha­ring Mög­lich­kei­ten und einem schnell wach­sen­den Part­ner­netz­werk. Mitt­ler­weile erstre­cken sich die Kapa­zi­tä­ten von Snow­flake weit über das eigent­li­che Data­ware­housing hin­aus, da zuneh­mend auch wei­tere Work­flows wie Data Engi­nee­ring oder Data Sci­ence unter­stützt wer­den, sodass eine soge­nannte Cloud-Data­platt­form entsteht.

Hete­ro­ge­ner Nutzerkreis

Die Nut­zer­schaft von Daten in Snow­flake und im All­ge­mei­nen ist typi­scher­weise stark hete­ro­gen. Auf der einen Seite fin­den sich Mit­ar­bei­ter aus Fach­do­mä­nen, wel­che oft­mals in ers­ter Linie mit gra­phi­schen Tools arbei­ten, und Ana­lys­ten, wel­che etwa direkt mit SQL auf den Daten ope­rie­ren. Auf der ande­ren Seite stel­len Data Engi­neers und Data Sci­en­tists eine wich­tige Nut­zer­gruppe dar, wel­che häu­fig mit Tools wie Pan­das oder Spark auf und mit den Daten arbei­tet. Snow­flake zollt den unter­schied­li­chen Nut­zern und ihrem Pro­gram­mier-Know­how Tri­but, indem diverse Tools und GUIs ange­bo­ten wer­den, wel­che die Vor­lie­ben und Skills der Nut­zer respek­tie­ren. So kön­nen mit dem Web-GUI Snow­sight mit weni­gen Maus­klicks Gra­phi­ken basie­rend auf SQL Queries gene­riert wer­den, wäh­rend SnowSQL als CLI-Tool einen SQL und code­ba­sier­ten Zugriff auf sämt­li­che DDL- und DML-Ope­ra­tio­nen erlaubt. Für die letzt­ge­nannte Gruppe der Data Engi­neers und Sci­en­tists steht indes Snow­park zur Ver­fü­gung, wel­ches im wei­te­ren Ver­lauf des Arti­kels beschrie­ben wird.

Snow­park Basics

Mit Snow­park bie­tet Snow­flake eine intui­tive Data Frame API für den Zugriff auf und die Pro­zes­sie­rung von Daten in Snow­flake sowie für den Ingest von Daten in die Snow­flake an. Dabei kann zwi­schen den Pro­gram­mier­spra­chen Java, Scala und Python gewählt wer­den, in wel­chen auch benut­zer­de­fi­nierte Logik in Form von User-Defi­ned Func­tions (UDFs) for­mu­liert wer­den kann. Die Aus­füh­rung sämt­li­cher Logik der Data­frame API erfolgt direkt in der Sow­flake unter Nut­zung der dort pro­vi­sio­nier­ten Com­pu­teres­sour­cen. Nut­zer haben dabei zudem die Option, UDFS bereits im Vor­feld über die Nut­zung der Web­ober­flä­che in den Pro­gram­mier­spra­chen Java, Python und Java­Script zu defi­nie­ren und dann in Snow­park zu refe­ren­zie­ren und damit zu verwenden.

Get­ting Star­ted mit Snowpark

Die Ver­wen­dung von Snow­park zeich­net sich durch geringe Vor­aus­set­zun­gen aus. So wird neben einem Snow­flake Account (auch ein kos­ten­freier Tri­al­ac­count ist mög­lich) ledig­lich eine Cli­ent­ma­schine benö­tigt, auf wel­cher eine Instal­la­tion von Java, Scala oder Python samt kor­re­spon­die­ren­der Snow­park Library vor­han­den ist. Die Sys­tem­an­for­de­run­gen für die Cli­ent­ma­schine sind dabei mini­mal, da das Gros der Berech­nun­gen via Push­down in der Snow­flake erfolgt.

Sind die Anfor­de­run­gen erst ein­mal erfüllt, braucht es ledig­lich eine Snow­park­ses­sion, wel­che die Ver­bin­dung zur Snow­flake her­stellt. Diese kann etwa in Scala wie folgt erzeugt werden:

import com.snowflake.snowpark._ 

val snowflakeConfigMap = Map(
    "URL" -> sys.env(SnowflakeUrl),
    "USER" -> sys.env(SnowflakeUser),
    "PASSWORD" -> sys.env(SnowflakePassword),
    "ROLE" -> sys.env(SnowflakeRole),
    "WAREHOUSE" -> sys.env(SnowflakeWarehouse),
    "DB" -> sys.env(SnowflakeDatabase),
    "SCHEMA" -> sys.env(SnowflakeSchema)
)
 
val session = Session.builder.configs(snowflakeConfigMap).create

val df = session.sql("SELECT country, amount from products")
Snow­park Funktionsprinzip

Das Funk­ti­ons­prin­zip glänzt eben­falls durch geringe Kom­ple­xi­tät gegen­über dem Anwen­der. Die in Data­frames for­mu­lierte Logik wird zur Lauf­zeit auf der Cli­ent­ma­schine in SQL Code über­setzt, wel­cher dann über den Sow­flake Con­nec­tor an die Snow­flake trans­fe­riert und dort aus­ge­führt wird. Bei der Nut­zung von UDFs wird ergän­zend ein Object Seria­li­zer auf­ge­ru­fen, um den Code für die Aus­füh­rung in die Snow­flake zu transferieren.

Snowpark Funktionsprinzip

Die Nut­zung von Snow­park war­tet mit diver­sen Vor­tei­len auf. Zunächst wer­den im Data Engi­nee­ring und Data Sci­ence Milieu beliebte Pro­gram­mier­spra­chen und eine wohl­be­kannte Data­frame API ange­bo­ten. Des Wei­te­ren kann die Ska­lier­bar­keit und Leis­tungs­fä­hig­keit der Snow­flake ideal genutzt wer­den, inklu­sive der Pro­vi­sio­nie­rung von hoch per­for­man­ten Rechen­clus­tern bin­nen weni­ger Sekun­den. Zuletzt wird die Data­frame Logik durch UDFs par­ti­ell benut­zer­de­fi­nier­bar. Sollte das noch nicht genü­gen, kann auf der Cli­ent­ma­schine aber auch ergän­zend gänz­lich benut­zer­de­fi­nier­ter Code aus­ge­führt und mit der Data­frame API kom­bi­niert wer­den, was im fol­gen­den Bei­spiel demons­triert wird.

Pra­xis­bei­spiel – Gra­phQL API

Sen­sor­da­ten wer­den über eine Gra­phQL API zur Ver­fü­gung gestellt. Diese Daten sol­len zu Aus­wer­tungs­zwe­cken in die Snow­flake gela­den und trans­for­miert wer­den. Ein Cli­ent zum Abfra­gen der API ist in Snow­flake nicht nativ vor­han­den, lässt sich aber in Python, Scala oder Java dank zahl­rei­cher Libra­ries mit wenig Auf­wand imple­men­tie­ren. Die Ant­wort der API sei ein JSON String, wel­cher direkt via Data­frame API in die Snow­flake in eine Sta­ging­ta­belle geschrie­ben wer­den kann. Dazu kann der Vari­ant-Daten­typ von Snow­flake ver­wen­det wer­den, wel­cher semi­struk­tu­rierte Daten mit einer Größe von bis zu 16 MB auf­neh­men kann. Das Par­sing des JSON und diverse wei­tere Trans­for­ma­tio­nen der Daten kön­nen eben­falls mit­tels Data­frame API for­mu­liert werden.

Auf­pass­feld Variant

Die Limi­tie­rung von Daten mit einer maxi­ma­len Größe von 16 MB für den Vari­ant-Daten­typ kann je nach Struk­tur der Ant­wort der API zu Pro­ble­men füh­ren. Ant­wor­ten von APIs etwa geben die ein­zel­nen Mess­punkte typi­scher­weise als Array zurück, wel­ches wie­derum Teil eines Hea­ders sein kann. Hier als Beispiel:

{
   “data”: {
      “events”: [
         {
             “fld1”: “someValue”,
             “fld2”: “anyValue”
         },
         {
             “fld1”: “myValue”,
             “fld2”: “thisValue”
         },
         {
         …
         }
      ]
   }
}

Um die­sem Pro­blem zu begeg­nen, kann erneut mit benut­zer­de­fi­nier­ter Logik gear­bei­tet wer­den, indem auf die Daten bereits vor dem Schrei­ben nach Snow­flake ein initia­les Par­sing ange­wandt wird. Im Falle des skiz­zier­ten Bei­spiels kann etwa das Array mit den eigent­li­chen Mess­punk­ten extra­hiert und dann pro­blem­los in die Snow­flake geschrie­ben werden.

Vor­züge von Snowpark

Auf diese Weise wer­den cli­ent­sei­tig ledig­lich die hoch­gra­dig benut­zer­de­fi­nier­ten Aus­füh­rungs­schritte vor­ge­nom­men, wäh­rend alle übri­gen Trans­for­ma­tio­nen via Push­down in der Snow­flake aus­ge­führt wer­den. Der gesamte Quell­code ist dabei in einer ein­zi­gen Pro­gram­mier­spra­che for­mu­liert und es benö­tigt somit ledig­lich ein Codere­po­si­tory. Die eigent­li­che Aus­füh­rung lässt sich etwa mit einem Docker­image und einem Con­tai­ner­ser­vice wie Kuber­netes oder Open­s­hift umset­zen, sodass sich ins­ge­samt mit gerin­gem Auf­wand eine durch­gän­gige CI/CD Pipe­line instal­lie­ren lässt.