Serverless on AWS: Understanding the hard parts
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 94 | |
Author | ||
License | CC Attribution 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/45653 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
FrOSCon 201924 / 94
7
10
12
14
15
16
17
20
22
23
26
27
28
29
30
31
32
33
36
37
38
39
41
44
45
48
52
53
55
56
57
58
60
61
62
64
66
67
74
76
77
78
79
81
83
84
93
00:00
Point cloudMoment (mathematics)Mobile appSoftwareXMLUMLComputer animationLecture/Conference
01:06
ALT <Programm>BASICLecture/ConferenceXML
01:52
Point cloudBerechnungLecture/Conference
02:47
Service (economics)Graphical user interfaceARCHIVE <Programm>BerechnungWEBGraphical user interfaceComputer fileLink (knot theory)EmailDownloadXMLComputer animation
03:45
ARCHIVE <Programm>Graphical user interfaceService (economics)Server (computing)outputBerechnungPostgreSQLData centerRoute of administrationService (economics)ZugriffComputer animation
05:32
outputServer (computing)DownloadBerechnungWEBComputer fileAbsolute valueHTTPAPIEmailService (economics)Parameter (computer programming)SIMPL <Programmiersprache>Server (computing)Event-driven programmingAktion <Informatik>BenachrichtigungsdienstProgram flowchart
09:21
outputDemosceneServer (computing)APIGateway (telecommunications)Service (economics)WeightLaufzeitConfiguration spaceEncryptionMach's principleDrosselungBeat (acoustics)ImplementationSoftware development kitString (computer science)Run-time systemRoute of administrationParameter (computer programming)ClojureEigenvalues and eigenvectorsSocial classVersion <Informatik>Java Virtual MachineSoftware development kitParsingFunction (mathematics)Absolute valueBerechnungMotif (narrative)Computer animation
13:37
Service (economics)PRINCE2BefehlsprozessorAllokationUniversal product codeApache MavenBefehlsprozessorRoute of administrationGraphical user interfaceService (economics)LaufzeitFunction (mathematics)Computer animation
15:59
Demoscene9 (number)Version <Informatik>BefehlsprozessorSIMPL <Programmiersprache>Parameter (computer programming)LaufzeitFunction (mathematics)Run-time systemBefehlsprozessorBlock (periodic table)Route of administrationComputer programmingManual of StyleComputer animation
21:05
APIGateway (telecommunications)Identity managementAuthorizationSoftware as a serviceSoftware development kitAPIAbsolute valueSoftware development kitACCESS <Programm>Gateway (telecommunications)RandDenial-of-service attackRevision controlService (economics)Computer animation
22:28
Gateway (telecommunications)APIACCESS <Programm>Route of administrationBeta functionLink (knot theory)Universal product codeHTTPUniform resource locatorProxy serverCache (computing)ProviderService (economics)Function (mathematics)FRAMEWORK <Programm>APICodeTemplate (C++)ImplementationGateway (telecommunications)Computer fileHTTPZusammenhang <Mathematik>ZugriffAktion <Informatik>Route of administrationGraphical user interfacePoint cloudDomain nameAssembly languageEigenvalues and eigenvectorsWindows AzureMobile appAbsolute valueComputer animation
27:33
DatabaseFunction (mathematics)Server (computing)Route of administrationRelational databaseLecture/ConferenceXML
28:33
Source codeChief information officerPoint cloudStructural loadString (computer science)Relational databaseMobile appRow (database)Polish Lowland SheepdogEvent horizonDatabaseUpdateSwitch <Kommunikationstechnik>Tape driveLevel (video gaming)String (computer science)Computer animation
32:05
DatabaseVolumetric flow ratePlane (geometry)NoSQL-DatenbanksystemLecture/ConferenceComputer animation
33:02
Partition (number theory)MAX <Programm>Partition (number theory)SIZNoSQL-DatenbanksystemComputer animation
34:06
Partition (number theory)Partition (number theory)NumberTable (information)Computer animation
35:06
Partition (number theory)MAX <Programm>Maximum (disambiguation)Greatest elementReading (process)Apple <Marke>Partition (number theory)Hash functionTable (information)Route of administrationBerechnungNumberSIZDatabaseQuery languageBASICLecture/ConferenceComputer animation
38:45
Route of administrationMaximum (disambiguation)Greatest elementReading (process)Apple <Marke>Partition (number theory)MAX <Programm>Table (information)Volumetric flow rateBerechnungComputer animationXML
39:59
Route of administrationBerechnungComputer animationLecture/Conference
40:44
Source codeSlide ruleTOUR <Programm>Limit (category theory)makeAPIGreatest elementLimit (category theory)MAX <Programm>Maxima and minimaConstraint (mathematics)Maximum (disambiguation)Greatest elementLinieJSON
42:37
Source codeBlogConstraint (mathematics)Aktion <Informatik>Route of administrationVolumetric flow rateLimit (category theory)Maximum (disambiguation)Lecture/ConferenceComputer animation
44:50
ACCESS <Programm>PostgreSQLMilitary operationTable (information)Relational databaseNormaleClefNoSQL-DatenbanksystemReading (process)Computer animation
46:56
Source codeMySQLHigh availabilityVolumeEIBProxy serverMaximum (disambiguation)BefehlsprozessorThresholding (image processing)Greatest elementTOUR <Programm>DatabaseHigh availabilityPostgreSQLMySQLRow (database)DatabaseParameter (computer programming)CASRelational databaseGeneric programmingConfiguration spaceRAMComputerInstanz <Informatik>Maximum (disambiguation)Computer animation
50:42
Source codeComa BerenicesAPIBeta functionDatabaseInstanz <Informatik>Relational databaseRoute of administrationVariable (mathematics)Moment (mathematics)Table (information)Cluster samplingConfiguration spaceSQLBus (computing)Large eddy simulationComputer animationXML
53:36
DatabaseMySQLPostgreSQLRoute of administrationLecture/Conference
54:22
Angular resolutionChain ruleRoute of administrationComputer fileDatabaseBerechnungLecture/ConferenceMeeting/Interview
56:56
openSUSEXMLComputer animation
Transcript: German(auto-generated)
00:07
Herzlich willkommen zu unserem Vortrag Serverless und EWS an das Thema Hardparts. Die Folien werden auf Englisch sein, die Vortragen werden wir auf Deutsch. Ich heiße Vadim und arbeite bei der Firma Apilabs.
00:20
Zu meinen zahlreichen Hobbys gehört auch AWS Cloud und Serverless insbesondere. Das ist auch mein Kollege. Ich bin Elmar, ich arbeite auch bei Apilabs im Moment im Backendbereich. Und wir haben auch viele Cloud-Themen in dem Team. Was macht Apilabs? Wir schreiben Software für die Gestaltung und Bestellung der Fotoprodukte.
00:45
Dazu gehören Poster, Prints, Kalender, Fotobücher, im Prinzip alles, worauf man ein Foto drücken lässt. Sind auf allen möglichen Geräten unterwegs. Seit 2008 eine vollständige Fujifilm-Tochter. Sind in Bonn gegründet. Wir sind auch hier Sponsor, wenn ihr Fragen habt zum Vortrag oder generell kommt gerne zu uns.
01:03
Wir organisieren auch Serverless-Bohnmittag, schon fünf, sechsmal mitorganisiert. Wie gesagt, das ist so eine Art Hobby. Wir machen auch einige Projekte mit Serverless. Für mich ist es auch ein besonderer Vortrag. Mein älterer Sohn Dennis ist mit dabei, der ist 13, gehört jetzt Papa zu. Generell schon das vierte Mal in Folge, dass ich hier vortrage.
01:23
Bevor wir jetzt zum Vortrag rübergehen, wer hat schon Erfahrungen mit EWS insgesamt, mit der Cloud? Okay, schon einige von euch. Wer hat schon Erfahrungen mit Serverless? Ein bisschen weniger. Wer war bei unserem Vortrag vor einem Jahr, wo wir über Serverless gesprochen haben?
01:41
Okay, gar keiner. Das war eher so ein Basic Vortrag, wo wir skizziert haben, wie man Serverless-Anwendung aufbaut. Hier ist es eher so ein bisschen für Fortgeschrittene, weil wir gewisse Learnings hatten aus diesem Jahr, aus diesem Projekt, auch aus anderen Projekten. Und wir haben hier gewisse Fehler auch künstlich konstruiert, damit wir nur an Beispiel eines Projekts vorankommen.
02:01
So, jetzt übergebe ich Herrn Elmer und komme dann später zum Datenbankteil dazu. Ja, funktioniert das Mikro? Ja. Okay, wir wollen euch die EWS-Themen teilweise am Beispiel von einem Projekt näherbringen, das wir letztes Jahr gemacht haben.
02:21
Wir haben bei IP Labs B2B-Kunden, an deren Umsatz hier beteiligt sind. Und wir haben jetzt letztes Jahr ein neues Tool geschrieben, was die Beträge, die wir unseren Kunden in Rechnung stellen, automatisch berechnet und was in der Cloud läuft.
02:40
Und ich werde jetzt erstmal die fünf wichtigsten Requirements nennen für dieses Projekt. Das war zunächst einmal, dass immer zu Monats ersten eine automatische Berechnung stattfindet für alle Kunden. Dass man diese Berechnung aber auch manuell anstoßen kann jederzeit über eine GUI im Web,
03:01
wo man dann auswählt, für welchen Monat und für welchen Kunden soll die Berechnung wiederholt werden. Das kann der aktuelle Monat sein oder das kann ein vergangener Monat sein, für den sich die Berechnungsregeln eventuell geändert haben rückwirkend oder vielleicht wurden sie ja auch korrigiert. In beiden Fällen werden die Berechnungsergebnisse nicht direkt in der GUI präsentiert, sondern einfach als Datei Download zur Verfügung gestellt.
03:22
Wir verschicken nach der Berechnung also nur einen E-Mail Link, per E-Mail einen Download Link. Und das macht das Ganze auch ziemlich einfach. Die Archivierung, die auch noch eine Anforderung ist, alle Berechnungsergebnisse sollen dauerhaft archiviert werden, lässt sich so natürlich auch sehr leicht realisieren.
03:41
Und dann haben wir als Fünftes noch eine Erleichterung für uns, dass das Tool nämlich nur für den internen Gebrauch bei RP-Labs gedacht ist. Dadurch haben wir weniger Probleme, den Zugriff auf die berechtigten Personen einzuschränken. Und eine ganz wichtige Rahmenbedingung für das Projekt ist das Lastverhalten, das wir zu erwarten haben.
04:02
Das sieht nämlich so aus, dass wir jeweils am Monats ersten, wenn die automatische Berechnung für alle Kunden getriggert wird, eine hohe Lastspitze haben. Aber im Rest des Monats finden nur selten mal manuell getriggerte Berechnungen statt, die dann wenige Sekunden dauern.
04:23
Und das führt dann letztlich dazu, dass der Service zu mehr als 99 Prozent der Zeit gar nichts tut. Und das ist also der ideale Einsatzzweck, Function as a Service zu verwenden, bei dem man nur für die Zeit bezahlen muss, für die, in der der Service überhaupt aktiv ist.
04:42
Und auf der nächsten Folie will ich kurz den allgemeinen Aufbau der Anwendung darstellen. Da müssen wir im herkömmlichen Rechenzentrum beginnen, in dem unsere zentrale Postgres-Datenbank die Bestelldaten ansammelt. Da haben wir einen Cron-Job hinzugefügt, der am Monats ersten jeweils die Order-Daten ausfließt und exportiert.
05:05
Der Export wird auf in einem S3-Bucket abgelegt. Ich habe jetzt eben gesehen, dass noch nicht so viele mit Amazon, mit AWS gearbeitet haben. Also S3 ist der Speicherdienst von Amazon. Dort können wir beliebig viele und beliebig große, nahezu beliebig große Daten ablegen.
05:25
Neben den exportierten Order-Daten speichern wir dort auch die Berechnungsregeln für die einzelnen Kunden, nach denen der Revenue Share berechnet werden soll. Und wenn wir jetzt die Eingabedaten in dem Speicherdienst liegen haben, dann können wir einen weiteren AWS-Dienst nutzen, und zwar den Lambda-Dienst.
05:47
Und wir haben eine Lambda-Funktion geschrieben, die diese Berechnung durchführt. Sie liest die Eingabedaten aus dem S3-Bucket, führt die Berechnung durch und legt die Ergebnisdaten ebenfalls wieder in einem anderen S3-Bucket, dem Output-Bucket, ab.
06:06
Diese Lambda-Funktion verwendet weitere AWS-Dienste, und zwar DynamoDB. Da werden zum Beispiel über die Monate akkumulierte Umsatzdaten gespeichert oder Wechselkursinformationen abgelegt.
06:23
Historische, die brauchen wir, wenn Kunden nicht in Euro bezahlen. Und schließlich benutzt die Funktion auch noch den Simple Notification Service von Amazon. Das ist wieder ein anderer. Also alle diese Dienste sind serverless. Man braucht nicht die Einrichtung eines Servers zu bezahlen, sondern diese Dienste arbeiten.
06:42
Man bekommt nur das berechnet, was man auch nutzt. In dem Fall zum Beispiel dann, ich möchte eine E-Mail mit einem Download-Link verschicken, dann bekomme ich diese E-Mail, diese Notification berechnet und muss nicht dauerhaft einen Service am Laufen haben. Ja, so weit zu der hauptsächlichen Berechnung, zu der zentralen Berechnungsfunktion.
07:02
Wir brauchen jetzt noch diese beiden Wege, die ich genannt habe, zum Aufruf dieser Funktion. Zunächst einmal zu dem manuellen Weg. Der manuelle Weg sieht so aus, dass der Benutzer in einem Webinterface, dass
07:20
man hier oben sehen kann, über dieses Webinterface gibt der Benutzer drei Parameter ein. Und zwar eine Customer-ID, die wird hier per Radio-Button ausgewählt und außerdem den Monat, für den die Berechnung gemacht werden soll. Diese drei Parameter müssen wir jetzt irgendwie an die Lambda-Funktion bekommen, weil sie diese als Eingabeparameter erwartet.
07:46
Außerdem haben wir hier als JavaScript-Code und JavaScript-Code ruft ja gerne eine HTTPS-Endpunkt auf, um diese Parameter dorthin zu senden. Aber wir können jetzt die Lambda-Funktion nicht direkt über HTTPS aufrufen und brauchen dafür noch einen Vermittler.
08:02
Und hier kommt dann der AP-Gateway ins Spiel. Das ist ein weiterer AWS-Dienst, der stellt uns so eine HTTPS-Endpunkt zur Verfügung und leitet die drei Parameter dann weiter an unsere Lambda-Funktion. Und jetzt brauchen wir noch den automatischen Aufruf, der jeweils am Monats ersten stattfindet.
08:20
Der beginnt dann dadurch, dass der Grondrop automatisch angestoßen wird und die Order-Daten ablegt. Und nun haben wir im S3 erlaubt, es mit bestimmten Ereignissen Trigger-Aktionen zu verknüpfen. Und wir haben das dann so gemacht, jedes Mal, wenn hier eine exportierte
08:41
und eine neue Datei abgelegt wird, mit exportierten Order-Daten, wird diese Aktion getriggert. Und diese Aktion kann zum Beispiel darin bestehen, eine Lambda-Funktion aufzurufen. Wir wollen ja bei dieser Gelegenheit die Berechnung anstoßen. Ein kleines Problem ist allerdings, wir brauchen für diese Funktion diese drei Parameter.
09:01
Customer, Hier und Mant. Die haben wir hier an dieser Stelle noch nicht. Und deswegen müssen wir einen kleinen zusätzlichen Umweg einschlagen. Und zwar, was wir an dieser Stelle haben statt der drei Parameter, ist der Pfad, also der Schlüssel, unter dem die exportierten Order-Daten auf S3 abgelegt werden. Dieser Schlüssel sieht zum Beispiel so aus, wie hier unten gezeigt.
09:23
Und da kann man sehen, in diesem langen Pfad befindet sich an dieser Stelle eine Customer-ID und an dieser Stelle befinden sich Jahr und Monat. Und die müssen wir aus dem Schlüssel herausparsen, damit wir diese drei Parameter haben. Und für dieses Parsing haben wir jetzt eine weitere Lambda-Funktion. Das ist dann die Lambda-Funktion, die automatisch getriggert wird durch das Ablegen der Order-Daten.
09:45
Diese Funktion extrahiert also die Parameter und ruft dann diese zentrale Berechnungsfunktion auf. Und damit haben wir diese beiden Aufrufwege abgehandelt. Und ich werde jetzt im Folgenden auf diese drei AWS-Dienste eingehen.
10:05
Lambda und Abigateware haben wir eben gesehen in der Grafik. AWS X-Ware haben wir nicht gesehen, weil das die Funktion der Anwendung nicht beeinflusst. Das geht da nur um Diagnose und Performance-Messung. Und im zweiten Teil wird Vadim dann auf die Datenbank-Themen eingehen und dabei auch DynamoDB besprechen.
10:25
Und ja, ich beginne jetzt mit dem Lambda-Dienst von AWS, der noch keine Lambda-Funktion angelegt hat, was soweit ich eben gesehen habe die meisten sind. Hier kurz einen Blick in die Web-Oberfläche von AWS, bei der man Lambda-Funktionen manuell erzeugen kann.
10:43
Hier kann man gut erkennen, was die wesentlichen Elemente sind von so einer Lambda-Funktion. Zunächst geht es darum, dass man eine Laufzeitumgebung auswählt. AWS bietet derzeit Unterstützung für die Laufzeitumgebung hier in dieser Liste an. Und wir haben uns für die Java 8 Laufzeitumgebung entschieden,
11:04
wobei wir da nicht auf die Sprache Java festgelegt sind, sondern es handelt sich um Amazon stellt uns die JVM in dieser Version zur Verfügung und wir können dann alles ausführen auf dieser JVM, was auf dieser JVM läuft. Zum Beispiel könnten wir auch Scala, Clojure und andere JVM-kompatible Sprachen da verwenden.
11:26
Wir haben also unser Projekt in Java aufgebaut und bauen auf unseren Maschinen dann ein Jar-Artifakt. Das kann man dann hier an dieser Stelle hochladen und man muss am Schluss dem AWS-Dienst, dem Lambda-Dienst noch mitteilen,
11:41
welche der vielen Methoden, die in diesem Jar-Artifakt vorhanden sind, aufgerufen werden soll, wenn die Lambda-Funktion gestartet wird. Und das machen wir hier an dieser Stelle. Hier sehen wir HandleRequest heißt die Methode. Und theoretisch kann man hier jede beliebige Methode angeben. Wir arbeiten allerdings mit dem SDK, das AWS zur Verfügung stellt
12:03
und dieses SDK gibt ein gewisses Gerüst vor, das besagt, dass man eine Lambda-Funktion immer in einer überschriebenen HandleRequest-Methode implementiert. Zunächst einmal muss man von einer Klasse ableiten. Das zeige ich jetzt auf der nächsten Folie.
12:20
Ich habe diese Klasse spaßeshalber mal nach Kotlin konvertiert. Dann passt die Mehrcode auf einen Bildschirm, weil das etwas kürzer ist. Im Prinzip ist es das Gleiche. Die anderen Klassen sind alle auf Java-Code belassen. Und das ist ja auch, Kotlin bietet eine sehr exzellente Interoperabilität. Man kann die Klassen also problemlos mischen.
12:43
Was ich jetzt sage, gilt also genauso für Java. Man muss einfach von der SDK-Klasse Request-Händler eine eigene Klasse ableiten und die HandleRequest-Methode überschreiben. Und dann definiert man für die Eingabe, die die Methode bekommt, eine eigene Datenklasse RefShareToolRequest in unserem Fall.
13:01
Und für die Ausgabe, die am Schluss hier zurückgegeben wird, braucht man ebenfalls eine eigene Klasse RefShareToolResponse, ist das in unserem Fall. So sieht das Gerüst einer Lambda-Funktion im Prinzip auch dann bei anderen Laufzeitumgebungen aus. Also es ist ziemlich einfach, so eine Lambda-Funktion zu implementieren. Die eigentliche Logik spielt jetzt hier keine Rolle.
13:23
Da können wir aus Zeitgründen auch nicht genauer drauf eingehen. Eine wichtige Einstellung, die man für jede Lambda-Funktion vornehmen muss, ist die Speichergröße, die dieser Funktion zugeordnet wird. Und darauf will ich in den nächsten Folien etwas genauer eingehen.
13:41
In unserem Beispiel haben wir die Funktion mit 512 MB zum Beispiel ausgestattet. Aber was muss man sich überhaupt überlegen, wenn man die Speichergröße einstellt? Die Speicher kostet natürlich etwas. Lambda-Funktionen werden abgerechnet in der Einheit Gigabyte-Sekunden. Es ist allerdings ein bisschen kontraintuitiv,
14:00
wie das jetzt tatsächlich sich auswirkt. Man muss nämlich noch ein weiteres Prinzip berücksichtigen. Und zwar proportional zu der Speichergröße verbessert sich auch die Leistung der CPU, mit der unsere Funktion ausgeführt wird. Das bedeutet mit anderen Worten, wenn ich die Speichergröße verdopple, habe ich zunächst einmal die doppelten Kosten wegen größerem Speicher.
14:22
Ich bekomme aber eventuell auch eine doppelt so schnelle Ausführungszeit. Ich bekomme also nur noch die Hälfte der Sekunden berechnet, wodurch sich die doppelte Speichergröße wieder ausgleicht. Das gilt natürlich nur dann, wenn meine Lambda-Funktion, wenn die CPU kontinuierlich 100 Prozent auslastet.
14:46
Andernfalls, wenn meine Lambda-Funktion teilweise warten muss oder viele Wartezeiten hat, dann skaliert sie natürlich mit der CPU nicht automatisch mit. Wenn ich die CPU doppelt so schnell mache, dann wird deswegen die Lambda-Funktion eventuell trotzdem kein bisschen schneller, weil sie hauptsächlich auf andere Dienste wartet.
15:06
Hier kommt der X-Ray-Dienst ins Spiel, den ich eben schon erwähnt habe. Das ist ein Tool von AWS, mit dem man das Laufzeitverhalten der eigenen Lambda-Funktion genauer untersuchen kann. Wir schauen uns jetzt mal gleich an,
15:22
wie die Laufzeit von unserer Revenue-Share-Berechnungsfunktion so aussieht. Um dieses X-Ray-Tool zu aktivieren, muss man theoretisch nur eine Checkbox setzen in der GUI. Wenn man das Java SDK verwendet, muss man zusätzlich noch einige Dependencies einbinden. Wir bauen unsere Anwendung ja mit Maven.
15:41
Das heißt, in unserer Maven-POM binden wir diese zusätzlichen Dependencies ein. Und wenn man das macht, dann hat man dann out of the box folgende Analysemöglichkeit. Ich habe also einmal unsere Lambda-Funktion ausgeführt und kann dann in X-Ray einen Grafen zu dieser Ausführung aufrufen. Der sieht dann wie folgt aus.
16:00
Die Funktion hat 8,5 Sekunden lang den AWS Lambda-Dienst benutzt. Die eigentliche Ausführung meiner Funktion hat allerdings nur 5 Sekunden, das ist dieser Balken, gedauert. Bevor die Funktion ausgeführt werden konnte, musste Amazon erstmal 3,1 Sekunden mit Initialisierungsaufgaben zubringen.
16:24
Das liegt daran, dass dieser eine Aufruf der Funktion ein Kaltstart war. Das heißt, Amazon musste zunächst einen Container vorbereiten, mit der Laufzeitumgebung von Java vorbereiten, in der dann diese Funktion ausgeführt werden konnte.
16:42
Hätte ich jetzt die Funktion ein zweites Mal danach sofort nochmal neu aufgerufen, dann hätte Amazon diesen Container wiederverwendet und diese ganze Initialisierungszeit wäre im Prinzip dann weggefallen. Das wäre dann ein sogenannter Warmstart gewesen. Aber das jetzt nur so am Rande, worum es hier eigentlich geht.
17:00
Wir wollten untersuchen, was tut unsere Funktion zur Laufzeit so? Und was jetzt X-Ray Out of the Box liefert, ist, dass es alle Aufrufe unserer Funktion an andere AWS-Dienste durch solche Segmente darstellt. Wir sehen hier dann zum Beispiel, dass unsere Funktion 2,6 Sekunden lang auf den DynamoDB-Dienst wartet.
17:22
Dann wartet es 436 Millisekunden auf einen Get Bucket Access Control-List-Aufruf, der an den S3-Dienst geht. Es gibt noch einen weiteren S3-Aufruf. Und am Schluss wird auch noch der SNS, Simple Notification Service, benutzt. Das ist dann das, womit wir die E-Mail abschicken.
17:42
Und diese Segmente zeigen also, dass die Positionen in unserem Code, die praktisch nicht durch eine schnellere CPU optimierbar sind, und das würde also heißen, dass wir diese Beschleunigung durch mehr Speicher eigentlich nicht so weit treiben können,
18:02
wie es in anderen Fällen möglich ist. Das war erstmal zum X-Ray-Dienst. Es gibt noch eine andere interessante Stelle, und zwar CloudWatch. CloudWatch ist der allgemeine Monitoring-Dienst von AWS.
18:21
Da findet man Log-Dateien zum Beispiel auch zur Ausführung von Lambda-Funktionen. Und wir gehen jetzt noch mal als letztes hier im X-Ray-Dienst auf dieses Raw-Data-Tab an dieser Stelle. Es geht jetzt darum, zu überprüfen, was wird uns für diesen einen Funktionsaufruf genau abgerechnet von AWS.
18:44
Und hier auf diesem Raw-Data-Tab finden wir eine Request-ID für diesen einen Aufruf. Das ist dann ein JSON-Dokument. Da können wir die Request-ID auslesen, und die können wir an anderer Stelle dann im CloudWatch-Log wiederfinden. An dieser Stelle.
19:00
Und hier sehen wir dann, dass wir 5100 Millisekunden abgerechnet bekommen haben. Das heißt also, wir bekommen nicht das gesamte Hochfahren des Containers abgerechnet, sondern nur die tatsächliche Ausführungszeit unserer Funktion. Wichtig ist dann auch die Information, wie viel Speicher tatsächlich benutzt worden ist. Wir haben zum Beispiel in diesem Beispiel 768 Megabyte gebucht.
19:21
Die müssen wir bezahlen. Aber es wurden nur 150 Megabyte tatsächlich genutzt. Sollte man sich also auch gegebenenfalls genauer anschauen, wie läuft meine Funktion mit verschiedenen Aufrufen, mit verschiedenen Parametern. Und wenn sie in jedem Fall nur wenig Speicher benutzt, dann sollte man natürlich den Speicher auch entsprechend klein einstellen, um keine unnötig hohen Kosten zu verursachen.
19:42
Apropos Kosten, es gibt noch den Lambda, das kostenlose Kontingent. Man kann bis zu einem, ich musste die Zeit, die wir am Anfang verloren haben, wieder reinholen. Deswegen will ich das nur kurz erwähnen. Man kann durchschnittlich bis zu einer Stunde pro Tag kostenlose Rechenpower von Lambda bekommen, wenn man das kostenlose Kontingent benutzt.
20:00
Für unsere Anwendung trifft das zufällig auch zu. Also wir laufen komplett, wir haben Anspruch, so wenig Rechenzeit, dass das komplett kostenlos ist. Ich wollte auch noch darauf eingehen, dass wenn Lambda-Funktionen weniger als 500 Millisekunden Laufzeit haben, dass man dann zusätzliche Überlegungen machen muss. Zum Beispiel haben wir eben gesehen, dass uns 5100 Millisekunden abgerechnet worden sind.
20:23
Das wurde auf 100 Millisekunden Blöcke gerundet. Das bedeutet, wenn ich ganz schnelle Funktionen habe, die zum Beispiel 105 Millisekunden Laufzeit haben, dann kann ich durch eine kleine Optimierung die Hälfte der Kosten sparen, weil ich die Funktion nur auf 95 Millisekunden drücken muss, um statt 200 Millisekunden nur noch 100 Millisekunden abgerechnet zu bekommen.
20:45
Man sollte sich unter Umständen auch noch klar sein, dass es auch noch eine zusätzliche Gebühr gibt pro Aufruf. Also eine Million Aufrufe von Lambda-Funktionen kosten 20 Cent. Aber ich möchte jetzt aus Zeitgründen direkt weitergehen zum AP Gateway.
21:02
Den habe ich in der Übersichtsgrafik schon mal angesprochen. Wir brauchen ihn nur, um unsere Lambda-Funktion über HTTPS ansprechen zu können. Es gibt allerdings noch, ich will kurz erwähnen, dass es eine wesentlich größere Motivation noch gibt,
21:20
den AP Gateway zu verwenden, weil es nämlich volle AP-Management-Funktionalität bietet. Dazu gehören viele Dinge, die ich jetzt nur am Rande kurz nennen kann. Zum Beispiel ist der Dienst mit dem Identity and Access Management, das ist dieses IAM von AWS verknüpft, wo man das ganze rechte Management mitregeln kann.
21:44
Und dann kann man jetzt die Aufrufe von AP-Funktionen auf bestimmte Benutzer beschränken. Man hat eine gewisse Denial of Service Protection, in dem man die Anzahl von Aufrufen pro Sekunde einschränken kann. Es gibt ein Versionsmanagement und letztlich erlaubt der AP Gateway,
22:02
dass man seine AP als Produkt vermarktet und dem AWS Marketplace gegen Gebühren anbietet. Man kann sogar auf Knopfdruck einen SDK generieren für seine AP, sodass die eigenen Kunden, die die AP benutzen, dann genauso einfach mit dem eigenen Dienst
22:22
hantieren können, wie man selbst es jetzt mit den Lambda-Diensten von AWS tut. Der AP Gateway ist auch eine Art Fassade vor einem heterogenen Backend. Wir haben hier in der Grafik die Client-Anwendungen und hier in unserem Beispiel haben wir die Lambda-Funktionen, die darüber aufgerufen werden.
22:43
Man kann mit dem AP Gateway auch an andere AWS-Dienste weiterleiten, zum Beispiel an S3. Die SNS-Dienste haben bestimmte Aktionen, die man aufrufen kann. Man kann also eine AP-Funktion definieren, die zum Beispiel eine Datei herunterlädt über S3. Die leitet dann einfach an eine bestimmte Aktion weiter und man muss für diese Funktion dann selber keinen Code schreiben.
23:03
Aber in unserem Beispiel brauchen wir wirklich nur diesen HTTP-Endpunkt. Der sieht dann zum Beispiel so aus, das ist ein längerer Domain-Namen, den kann man auch durch einen eigenen Domain-Namen ersetzen, einen Custom-Domain-Name, was natürlich ein bisschen Zusatzgebühren bewirkt.
23:20
Bei uns sieht das letztlich dann so aus im JavaScript-Code von diesem Frontend, was den manuellen Anstoß unserer Berechnungsfunktionen bewirken soll. Drückt man dann hier auf den Start-New-Button, dann wird dieser Code ausgeführt und da ist dann wieder dieser HTTPS-Endpunkt vom AP Gateway zu sehen.
23:43
An den schicken wir ein JSON-Dokument mit den drei Parametern, was hier zusammengebaut wird und wir schränken den Zugriff auf den AP Gateway so ein, dass nur Aufrufe gestattet sind von Aufrufern, die diesen AP-Key kennen,
24:01
den wir hier im Klartext eingefügt haben, was wir uns allerdings auch wieder natürlich nur erlauben können, weil diese ganze Anwendung nur IP-Labs intern benutzbar ist. Im Zusammenhang mit dem AP Gateway ist auch noch eine Erwähnung wert,
24:20
dass auch da Gebühren für die Anzahl von Aufrufen selbst berechnet werden. Die sind erheblich höher als die Gebühren für Lambda. Bei Lambda hatten wir 20 Cent für eine Million Aufrufe, beim AP Gateway haben wir 3,50 Dollar pro Million Aufrufe. Das wirkt sich dann wieder unterschiedlich aus. Also im Extremfall bei einer ganz billigen Funktion kann das die Kosten verzehnfachen,
24:42
aber normalerweise in vielen Fällen werden Lambda-Funktionen selber mehr Kosten verursachen, sodass das dann nicht mehr so stark ins Gewicht fällt. Das muss man sich dann im Einzelfall auch genauer anschauen. Ich will am Schluss noch zeigen, wie man solche AP-Funktionen effektiv,
25:03
wie man so AP Gateways, eigene APs effektiv aufbauen kann. Grundsätzlich kann man hier auch über die GUI gehen, dann müsste man allerdings für jede Funktion, die man einführen will, in unserem Beispiel ist das einfach, wir haben nur diese eine Calculate-Funktion, aber normalerweise hat eine AP hier Dutzende oder sogar Hunderte Funktionen,
25:23
gut Hunderte wäre auch wieder nicht gut, jedenfalls viele Funktionen und dann müsste man für jede Funktion hier in diesem Baum manuell ein neues Element einfügen und dann müsste man diverse GUI-Seiten ausfüllen. Also für experimentelle Zwecke oder für Übungszwecke eignet sich diese GUI sehr gut, aber letztlich möchte man ja die Infrastruktur auch automatisiert und auf Knopfdruck aufsetzen
25:45
und da in dem Zusammenhang erwähnen möchte ich kurz das Serverless Framework erwähnen. Erstmal Amazon hat auch ein eigenes Framework, das heißt SEM, mit dem kann man etwas ähnliches machen, aber Serverless finde ich jetzt deswegen attraktiv, weil es auch Cloud unabhängig ist, man kann damit also auch Serverless-Anwendung
26:06
auf Azure oder der Google Cloud-Plattform aufsetzen, aber in unserem Beispiel funktioniert das auch mit unserer AWS-Anwendung, Serverless bietet einen Command-Line-Interface, so kann man zum Beispiel mit Serverless Create aus einem Template ein neues Projekt anlegen
26:21
und die wichtigste Konfigurationsdatei in diesem Projekt ist eine YAML-Datei, die beispielsweise so aussieht, für unser Beispiel mit unserer Calculate-Funktion haben wir hier nochmal die Java bzw. Kotlin-Klasse genannt, die diese Implementierung bereitstellt und wir sagen jetzt dem Serverless Framework,
26:43
dass es ein Event definieren soll, über HTTP soll es angesprochen werden, mit der Get-Methode, über den Calculate-Fahrt und diese paar Zeilen genügen, dass dieses Framework automatisch die gesamte Infrastruktur aufsetzt, die dafür nötig ist.
27:01
Also die eigentliche Datei wird ja, also das Java-Artifakt ist natürlich auch noch wichtig zu definieren, es wird das Serverless Framework initialisiert, die Lambda-Funktion und auch setzt eine passende API im API-Gateway auf und im Hintergrund sind das schon einige komplizierten Aktionen, wie man dann sieht, man ruft wieder von der Kommandozeile Serverless Deploy auf
27:22
und dann wird die ganze Struktur aufgesetzt. Ja, das wäre es auch alles zum API-Gateway, ich würde dann an Wadim übergeben, für die Datenbank-Themen. Ich erzähle etwas über die Datenbanken. Wie wir immer schon gesagt haben, wir haben Amazon DynamoDB eingesetzt,
27:42
das war auch logische Variante, wenn man als Serverless Anwendung aufbaut, vor allem mit seltenen Picks, die wir hier haben, eben, dass wir keine Server betreiben und so weiter. Nur in einigen Fällen hatten wir gewisse Funktionen hier anzubieten, wo wir uns gefragt haben, wie macht das Amazon DynamoDB?
28:02
Das erste war, wir bräuchten solche Aggregatfunktionen, wie zum Beispiel SAM, weil zum Beispiel Revenue Share funktioniert bei uns so, je mehr man erwirtschaftet in einem Jahr, desto geringer wird Revenue Share Ersatz. Deswegen müssen wir nicht nur wissen, was in einem Monat so ein Revenue Share pro Kunde pro Monat tatsächlich gerechnet wurde,
28:21
sondern wie viel ist es insgesamt schon in einem Kalenderjahr. Da haben wir festgestellt, was in einer Relationalen Datenbank super einfach mit SAM geht, gibt es in DynamoDB einfach gar nicht. Dann haben wir uns gefragt, wie können wir uns sowas eigentlich umsetzen. Dann sind wir auf DynamoDB Streams eigentlich gestoßen. Wer hat schon Erfahrungen mit Storage Procedures in Relationalen Datenbanken?
28:45
Eigentlich die Hälfte. Im Prinzip kann man die einfach ausführen, wenn irgendein Trigger geschritten ist, und dann einfach Datenbank Sprachen was schreiben. DynamoDB Stream ist ähnlich. Der größte Unterschied zu Storage Procedures ist,
29:01
Storage Procedures werden ausgeführt im Rahmen einer Datenbank-Transaktion. Das heißt, man startet im Backend irgendwas, und wenn die Storage Procedures anspringen, dann kann theoretisch passieren, dass die Datenbank Out of Memory kriegt und der Backend eine Exception. DynamoDB Stream geschieht asynchron. Das heißt, es werden gewisse Events verarbeitet, die dann wiederum asynchron, je nach welcher Trigger gegriffen ist,
29:24
dann abgearbeitet werden. Auf diese Art und Weise kann man diese Aggregate abbilden. Im einzelnen geschieht es so, dass wir an der Stelle einfach so einen Stream aktivieren. Auf der Tabellenebene, das ist so eine Tabelle, wo wir monatliche Einträge pro Monat Revenueshare-Sätze schreiben.
29:41
Einfach Stream Enabled True. Im nächsten Schritt sagen wir, was passiert, wenn tatsächlich ein Event auf der Datenbank ausgeführt wird. Und daher sagen wir, es muss eine Lambda ausgeführt werden. Das heißt, per Trigger wird eine Lambda asynchron aufgerufen. Und so ist es einfach schematisch, was diese Lambda eigentlich machen kann. Hier kriegen wir einfach die Liste aller Events,
30:04
und daraus können wir so einen Stream-Record bekommen. Aus diesem Stream-Record kriegen wir zwei Objekte, Old und New, so ähnlich wie bei Storage Procedures. Man kriegt einen alten und neuen Datensatz. Natürlich gibt es keinen alten Datensatz, wenn Ensort geschieht. Da ist er nur neu. Oder beim Delete gibt es nur alt.
30:20
Im Update-Fall gibt es beides. Und so ein Image besteht eigentlich aus einem Map. Und ein Map besteht aus Spalten, Tube, ist das Int, String so ähnlich und eben Wert, was dort reinkommt. Und am Ende kann man noch Event ermitteln. Und so können wir einfach per Switch entscheiden im Falle von Ensort. Wir haben hier es nicht dargestellt.
30:41
Wir haben eine Revenue-Share-Yearly-Tabelle sozusagen, wo wir die Dinge akkumulieren. Pro Kunde sozusagen. Was ist insgesamt schon in einem Jahr sozusagen an Revenue-Share reingeflossen? Das heißt, wenn ein Ensort reinkommt, dann wissen wir, wir haben irgendeinen Wert für Yearly-Tabelle. Und das, was für diesen Monat reinkommt, müssen wir einfach drauf addieren.
31:04
Remove gibt es bei uns nicht, weil wir so einen Monatseintrag verschwinden sollen. Aber Update gibt es schon. Wenn irgendwas rekalkuliert wird, das heißt Year Modify, dann kann man durch die Werte vergleichen, was war davor, was ist jetzt da reingekommen und das akkumulieren mit dem Wert, was schon vorher stand.
31:22
Auf diese Art und Weise kann man ziemlich flexibel und asynchron praktisch diese Aggregate umsetzen. Natürlich hat man hier mit Eventual Consistency zu tun. Wenn man halt irgendwas schreibt und sofort liest, es kann sein, dass diese Lambda noch nicht gelaufen ist und irgendwas nicht aktualisiert hat. Das muss man halt ein bisschen beachten. Aber ansonsten ziemlich entkoppelte Architektur.
31:42
Das heißt, das, was wir mit unserer Mantel-Tabelle zu tun haben, diese Aufruf dieser Lambda hat überhaupt keinen Einfluss auf irgendein Verhalten, weil sie einfach asynchron läuft. Die zweite Sache, die wir mit bedenken sollten, war, wie wir überhaupt autoskalieren.
32:00
Obwohl DynamoDB quasi serverless heißt, für mich war sie nie serverless, weil man gewisse Dinge trotzdem von vornherein mit bedenken musste. Vor allem noch vor zwei Jahren. Und dazu muss man verstehen, wie überhaupt man DynamoDB provisioniert, wie man diesen Durchsatz provisioniert. Das ist komplett unterschiedlich, wie wir das aus NoSQL-Datenbanken kennen,
32:21
wie Cassandra und so weiter. Hier wird Durchsatz pro Tabelle provisioniert. Und zwar so, dass es gibt Right Capacity Units, oder einfach VCU werde ich jetzt abkürzen, und es gibt die Möglichkeit, ein Kilobyte pro Sekunde zu schreiben. Das heißt, schreibt man 0,5 Kilobyte, gilt das als eine VCU, schreibt man 3,5,
32:41
sind das vier VCUs. Das wird aufgerundet, je nachdem wie groß. Bei REIT ist es ähnlich, nur da wird auf 4 Kilobyte Ebene abgerundet. Und diese REIT provisioniert man völlig unabhängig. Das heißt, man muss für die Datenbank immer mit bedenken, wie viele VCUs und diese RCUs ich provisionieren will.
33:01
Dazu kommt noch eine zusätzliche Dimension ins Spiel. Ich weiß, es ist Samstag 10 Uhr, man muss diese komischen Formeln durch. Denn in der NoSQL-Datenbank gibt es sowas wie Partitioning und Sharding. Das heißt, irgendwann hat man damit zu tun, dass nicht alles in einer Partition abgespeichert wird,
33:22
sondern dann eben in mehreren. Und eine Modib hat eine gewisse Formel, man muss nur im Prinzip wissen, es gibt zwei Dimensionen. Das ist bei Capacity und bei Size. Und bei Capacity ist es eben diese Formel, diese RCUs, die wir haben, durch 3000, und diese VCUs durch 1000, und dann ermittelt man einen Wert. Und bei Size ist es so, dass eine Partition maximal 10 GB größer sein kann.
33:43
Haben wir mehr Daten, brauchen wir mehr Partitions. Und DynamoDB ermittelt die Partitions, das ist im Prinzip maximal aus diesen zwei Werten bei Capacity und bei Size nur aufgerundet. Die Formel ist übrigens, das veröffentlicht das Team von Amazon, quasi DynamoDB-Team ab und zu, und das kann sich ändern,
34:01
aber das ist in den letzten Jahren so konstant geblieben. Im Prinzip muss man bedenken, es gibt Einschränkungen, wie viel pro Partition RCUs und VCUs überhaupt möglich sind. Ansonsten braucht man halt mehr Partitions. Und was vor allem wichtig ist, dass dieser Durchsatz, was wir am Anfang an provisioniert haben,
34:21
einfach gleichwertig auf Partitions aufverzahlt wird. Und kommt es dazu, dass auf eine Partition wir mehr verbrauchen, als wir provisioniert haben, kann es sein, dass wir hier Provision-throughput-Axided-Exception bekommen. Und damit muss man dann den Backend zu tun haben, sollte man sich verschätzt haben, bei der Provisionierung zu niedrige Zahlen definiert hat und so weiter.
34:43
Dazu gibt es noch ein paar Kleinigkeiten. Es gibt sowas wie Burst-Krede, das heißt, das kann bis fünf Minuten eine Tabelle sozusagen mehr leisten, als wir provisioniert haben, aber nur fünf Minuten. Es gibt sowas wie Adapted Capacity, das ist das DynamoDB-Feature vor einem Jahr automatisch freigeschaltet.
35:01
Wenn wir mehrere Partitions haben, einige unterutilisiert sind, dann werden diese nicht verbrauchten Capacity-Units auf die heiße Partition zum Beispiel drüber geschuftet. Und zwar automatisch, ohne dass wir irgendetwas tun müssen. Eine heiße Partition kann man einfach kriegen, zum Beispiel einen unglücklichen Hash definieren. Zum Beispiel haben wir deutsche Bundesländer
35:22
als Hash die erste Buchstabe definiert und dann haben wir fünf Stück mit B und wollen wir irgendetwas abfragen, dann liegen die alle in diese Partition mit B und für Rheinland-Pfalz nur eine mit R und dann hat man mit B plötzlich eine heiße Partition. Und es kann sein, dass unsere Provisionierung einfach nicht ausreicht. Das ist ja einfach nur ein Beispiel mit konkreten Zahlen.
35:41
Wir haben zum Beispiel Tabelle 40 GB und wir haben gesagt, ja, wir haben gerechnet Read Capacity Units an der halbtausend und Write Capacity Units 400 sollten ausreichen. Wenn wir jetzt berechnen, wie viele Partitionen wir brauchen, dann wird es bei Capacity den Wert 0,9 ermitteln und bei Size dann eben 4, weil nur 10 GB.
36:02
Und das heißt, es werden hier in diesem Falle einfach vier Partitionen verwendet von Amazon auf diese Daten. Das heißt, dass diese RCU und VCU einfach gleichmäßig auf diese vier Partitionen verteilt wird. Deswegen hat man eine heiße Partition, die mehr als 400 RCUs verbraucht, dann kann es sein, dass eben dieses Provision
36:21
throughput exception kommt. Es sei denn, es greift dieses Adaptive Capacity oder Burst Credit und der rettet uns, worüber geht. Ich sag mir, mit diesen Dingen muss man so ein bisschen sich auseinandersetzen, mussten, weil es kommt sowas wie On-Demand Capacity, darüber reden wir, aber vor einem Jahr gab es keine einzige Möglichkeit, das genau zu rechnen, wie oft welche abfragen,
36:42
wie oft werden sie abgefordert gegen die Datenbank. Und für mich war das so ein Gefühl, dass es eigentlich nicht serverless ist. Damit will man eigentlich mit serverless nicht zu tun haben. Trotzdem, wir hatten eben diese Situation, wo bis auf die Nacht auf den ersten des Monats praktisch in der Anwendung nichts los war. Und wir wollten die Tabellen so provisionieren,
37:02
dass wir da nicht so viel Geld bezahlen. Und da sind wir über die unterschiedlichen Optionen für Autoscaling durchgegangen. Das ist Configure Scheduled in eben diese neue On-Demand Capacity. Und wir wollten euch da ein paar Dinge zeigen. In den Basic Varianten haben wir gesagt, für unsere Tabelle reichen drei Read Capacity Units
37:21
und drei Write Capacity Units. Das ist so ein Monat zu überstehen, wenn irgendwie schon spontane Anfragen kommen und dein Modib ist richtig schnell. Man kann sehr, sehr viele Abfragen pro Sekunde lesend als auch schreibend machen. Aber in der Nacht zum ersten bräuchten wir ein bisschen mehr. Und es gibt die Möglichkeit Autoscaling zu konfigurieren. Zum Beispiel nach Regeln, wenn 70 Prozent von Read Capacity
37:42
verbraucht wird, das heißt schon zwei Units, oder auch 70 Prozent von Write Capacity auch zwei Units verbraucht werden, dann kann man Upscaling machen, das heißt von 4 bis 20 Write Capacity Units erlauben. Das heißt wir erlauben einfach mehr lesen und mehr schreiben, wenn eben so ein bisschen
38:02
Traffic drauf ist. Das hat auch mehr oder weniger gut funktioniert. Das Problem ist, dass bis diese Regel greifen, vergeht mindestens eine Minute. Weil da gibt es sowas wie CloudWatch Alarm und dein Modib, diese Autoscaling-Regel, die guckt auf Autoscaling-Alarm und ergreift mit Kleinsteinheit nach einer Minute.
38:21
Das heißt, wir haben tatsächlich Fehler bekommen, weil genau diese eine Minute, wo genau alle Berechnungen in der Nacht gestartet sind und die laufen bei uns parallel für alle Kunden, weil wir parallel die Daten exportieren und dann schlusswaren wir sozusagen dieses Provision-Fruitput Capacity Exception quasi bekommen. Das war etwas unglücklich.
38:40
Haben wir dann weitere Optionen evaluiert? Okay, zurück, nochmal zurück. Und es gibt sowas wie Scheduled Autoscaling.
39:05
Und dieses Autoscaling erlaubt es zu sagen, wann will ich tatsächlich autoskalieren, nach Zeit sozusagen. Und das ist so ein Beispiel, wie sowas mit Amazon CLI zu definieren ist. Es gibt sowas wie Put Scheduled Action.
39:21
Und wir sagen, das geht für Namespace DynamoDB, das heißt für DynamoDB. Und das ist ein Cronjob. Und er definiert, dass jeden 1. des Monats um 1.50 Uhr praktisch irgendetwas geschedult werden soll. Und das heißt, wir geben hier auch DynamoDB-IRN im Prinzip Tabelle und sagen,
39:41
diese Read Capacity Units müssen von 4 bis 20 Uhr dann autoskaliert werden um 1.50 Uhr am 1. des Monats. Wir wissen, dass wir um 2 Uhr nachts einfach die Berechnung anstoßen. Wenn wir 10 Minuten davor Autoscaling starten, dann wissen wir, dass dann ein bisschen mehr Durchsatz möglich ist. So ähnlich kann man das dann auch löschen später.
40:01
Und hier haben wir so ein bisschen gerechnet, okay, um 3.30 Uhr ist schon vorbei. Und dann kann man diese Regel im Prinzip bei Name, das ist die gleiche Name, wie hier, auch löschen. Dieses Put Scheduled Action hat uns natürlich gerettet, aber diese Delete Scheduled Action war ein bisschen tricker, weil wir haben schwächere Monate, wo die Berechnung schnell durch ist.
40:21
Wir haben zum Beispiel nach Weihnachtsgeschäft Monate, wo viel, viel mehr Daten sind und die Berechnung dauert länger. Und das heißt, dann sind wir in die Risiken gelaufen, dass um 3.30 Uhr noch nicht vorbei ist. Und wir haben diese Regel ein bisschen früher gelöscht, als es da sein soll. Und sind wiederum in die Exceptions reingelaufen. Also das war so ein bisschen das Gefühl, ja, wir kriegen wir denn tatsächlich richtig.
40:43
Und Ende des letzten Jahres kam so eine Funktionalität, die heißt On-Demand Scaling. Und die sollte genau dieses Problem lösen, dass wir mit diesem Throughput, mit diesen Formeln, was sollen wir provisionieren, wie sollen wir autoscalen, eigentlich damit nichts mehr zu tun haben oder weitgehend nicht mehr zu tun. Und generell diese Kapazitätplanung,
41:00
genauso wie mit Server, wie auch mit DynamoDB, ist einfach Trick. Entweder überprovisioniert man, aber wenn man es braucht, dann ist man plötzlich unter Capacity und dann ist man halt unzufrieden. Und Demand Capacity ermöglicht, das auf der Tabellenebene zu definieren, wollen wir Provision-Throughput, wollen wir weiterhin mit diesen Write- und Read-Capacity-Units rumhantieren
41:20
und rechnen, autoscalen, oder wollen wir diese Aufgabe praktisch DynamoDB überlassen. Und das funktioniert dann so, dass wir keine Min und Max definieren sollen, sondern es wird bei Null gestartet und autoskaliert, wie es eigentlich auch schon sein soll. Das heißt, die Aufgabe übernehmen DynamoDB schon für uns. Und das sozusagen erspart uns diese Kapazitätsplanung.
41:43
Das ist nochmal die Übersicht zwischen Provision und Demand. Mit Provision hat man Minimum und Maximum und irgendwelche Autoscaling-Regeln, sei es configured, sei es Adaptive Capacity greift, oder auch tatsächlich scheduled. Und im Falle von On Demand, es gibt keine Limits.
42:01
Das kann man auch bei Null starten und das skaliert, so wie wir es brauchen. Natürlich ist es ja nicht so, dass es alles grenzenlos ist. Es gibt gewisse Limits, 40.000 Rits und Rights pro Sekunde, aber das sind schon riesige Limits. Normalerweise braucht man das nicht. Wir haben dann pro Sekunde
42:21
selten zweistellig und hier ist es fünfstellig. Und eine Einschränkung war, dass DynamoDB innerhalb von 30 Minuten nur die Kapazität verdoppeln konnte. Das heißt, nicht besonders gut für den Use-Case, wenn wir zum Beispiel Werbung um 8 Uhr haben und dann kommen alle Benutzer plötzlich und da hat man so einen riesigen Peak.
42:41
Es wurde dabei ein Trick genannt, wie man das schaffen kann. Man müsste riesige Read- and Write Capacity Units provisionieren. Erstmal Provision Mode wählen, riesige Write- und Read Capacity Units eintragen und dann auf On Demand Capacity umschalten. Und da wurde sozusagen Pre-Warming gemacht. Und zwar zum Null Tarif. Auch etwas unglücklich,
43:01
weil das ist wiederum eine manuelle Aktion. Angeblich soll sich das auch verbessern und auch das muss nicht mehr der Fall sein. Ich glaube, dass innerhalb der nächsten Monate diese Einschränkung dann auch verschwindet und dann müssen wir gar nicht mehr eingreifen. Wann ist es gut, wenn wir tatsächlich unseren Trafik nicht gut voraussehen können?
43:20
Das heißt, sehr oft ist es der Fall. Und natürlich die zweite Sache ist On Demand Capacity siebenmal teurer als durchschnittlich throughput Capacity. Nur siebenmal ist es dann teurer, wenn wir tatsächlich am Maximum, am Limit Durchsatz haben. Und das hat keine Anwendung. In der Nacht hat man wenig und sowas.
43:42
Deswegen das relativiert sich eigentlich. Am Ende wird man vielleicht sogar weniger bezahlen als bei provisioned throughput. Hier nochmal so eine Übersicht, welche Capacity man nimmt. Es gibt auch die Möglichkeit, auch Reserve Capacity zu nehmen. Wenn man weiß, dass man einfach einen
44:02
konstanten Trafik hat, kann man diese Read Capacity Units und Write Capacity Units kaufen. Genauso wie man Institutinstanzen für ein oder drei Jahre kauft. Hier kann man auch Kapazität kaufen. Wenn man weiß, okay, ich komme damit klar und das reicht mir, dann spart man zwischen 30 und 60 Prozent. Hat man Variabletrafik,
44:21
aber den man voraussehen kann, das heißt Autoscaling-Regeln sind so klar und man läuft nicht in die Exception, dann ist provisioned Capacity eigentlich gut. Ansonsten hat man Variabletrafik und kann man den nicht vernünftig voraussehen, wie zum Beispiel auch bei unserer Anwendung. Es ist in der Nacht, aber es ist je nach Monat, je nach dem, was los war, einfach nicht vorhersehbar. Es ist tatsächlich für Un-Demand
44:41
eigentlich ein perfekter Use-Case. Da muss man sich nicht darum kümmern. Deswegen, wie gesagt, das ist so eine Entscheidungs-Skizze. Generell, deine Motivation ist natürlich eine schöne Sache, aber trotzdem, es hat gewisse Use-Cases. Zum Beispiel ganz normale Kiweli Lookups. Wenn man solche Operationen nimmt,
45:01
dann ist es ein Use-Case. Und wenn wir tatsächlich schaffen, unsere Tabellen so zu konstruieren, dass wir komplexe Queries vermeiden, das ist auch gut. Versucht man tatsächlich irgendwie mit Joins, so wie wir das aus Relationalen Datenbanken kennen, wird man damit unglücklich. Dann verliert man Performance und alles Mögliche.
45:20
Trotzdem ist halt deine Motivation nicht immer die richtige Lösung, auch nicht die Lösung für alle Probleme. Man muss immer daran denken, wie man die Tabellen designt, weil man versucht tatsächlich, diese Joins zu vermeiden und deswegen gibt es keine dritte normale Form. Alles, was wir aus Relationalen Datenbanken kennen, das muss man vergessen.
45:41
Man muss versuchen, sage ich mal, nicht besonders optimal alles zu strukturieren, aber soweit es geht, in alle Tabellen, in eine Tabelle alles zu packen, dass die Access Patterns klar sind. Dann tatsächlich glänzt deine Motivation. Und es ist praktisch unmöglich, die Struktur der Tabelle im Nachhinein zu ändern, was mit Relationalen Datenbanken einfach geht.
46:02
Neue Tabelle für den Primary Key verknüpfen, neue Joins. Und es ist fantastisch, aber mit DynamoDB wird man es nicht schaffen, sowas zu machen. Wie gesagt, man will Joins vermeiden und dann endet man mit sehr teuren Fragen, mit Full Scans und so weiter,
46:20
die sehr, sehr viele Written Write Capacity Units verbrauchen. Und auch Lernkurve ist ziemlich groß bei DynamoDB. Da muss man schon Erfahrung mit NoSQL-Datenbanken haben. Man darf ja nicht so vorgehen wie bei der Relationalen Datenbank. Aber in Serverless Space war es nicht möglich, noch vor sechs Monaten irgendwas anderes einzusetzen als DynamoDB.
46:42
Das hat sich jetzt im letzten Jahr geändert und es gibt jetzt Amazon Aurora Serverless. Und Amazon Aurora ist eine Relationalen Datenbank, aber quasi in der Serverless-Variante. Jetzt erstmal, was ist Amazon Aurora an sich? Die gibt es in zwei Varianten. Die ist MySQL- und Postgres-kompatibel.
47:00
Das heißt, man muss auch nicht wissen, dass es Aurora ist. Das ist einfach ein anderer Endpoint. Aber der Treiber, man nimmt MySQL-Treiber oder Postgres-Treiber und arbeitet als wäre auf der anderen Seite MySQL oder Postgres. Was aber Amazon Leute da gemacht haben bei Aurora? Sie haben Transaktionsverhalten, also Rechenleistung und Storage komplett entkompelt.
47:21
Und Storage ist so ähnlich wie S3 Storage. Das heißt, es gibt mindestens sechs, also es gibt sechs Kopien über drei Availability Zones, jeweils zwei Kopien eines Datensatzes in jeder Availability Zone. Und das erlaubt zum Beispiel, wenn eine Availability Zone weg ist, dann sind immer noch vier von sechs Datensätze da und das nennt sich Quorum in NoSQL-Welt.
47:42
Und das reicht, wenn vier von sechs gelesen oder geschrieben werden. Dann gilt das als okay, oder auch ein Satzverlust kann auch durchaus kompensiert werden. Und das Storage muss man nicht provisionieren, das skaliert automatisch in zehn Gigabyte-Schritten. Und deswegen, seitdem Storage komplett von Computern gekoppelt wurde,
48:02
war es möglich, praktisch diese Amazon Aurora in der Serverless-Variante anzubieten. Und das funktioniert so, dass im Prinzip Amazon hat so einen Pool von Datenbank-Instanzen, die sie warm halten. Das kann zum Beispiel M5 Large Postgres sein oder 2x Large Postgres sein.
48:21
Einfach generische Datenbanken. Und wenn eine Anfrage kommt, dann entscheidet Amazon, und ich erzähle jetzt nach welchen Kriterien, welche größere Datenbank sie nehmen, und dann attachen sie unseren Storage. Weil Datenbank compute es komplett generisch. Und Storage ist das, wo wir die Daten sozusagen abspeichern.
48:41
Und auf diese Art und Weise ist es praktisch möglich, tatsächlich eine relationale Serverless-Datenbank zu verwenden. Wenn man Amazon Aurora Serverless jetzt in die Konfiguration geht, es gibt es erstmal nur für MySQL. Für Postgres kommt das noch. Man sagt hier, wie viel minimaler Ram man braucht.
49:02
Instanzen mit RAM, hier 4. Und man kann auch Maximum eingeben. Und dann entscheidet Amazon anhand von wie viel CPU-Utilisation von der verwendeten Datenbank, wie viel Speicher und wie viel Connection jetzt genau angefragt werden, ob es autoskaliert werden soll.
49:21
Das sind diese drei Parameter. Und dann übernimmt Amazon Aurora Serverless selbst die Entscheidung, wenn man eine größere Datenbank braucht. Das Coolere dabei ist, dass man sagen kann, wenn fünf Minuten lang keine Anfrage kommt, wird die Datenbank pausiert. Das heißt, wir zahlen nicht mehr für Rechenleistung, zahlen natürlich aber für Storage. Aber das ist halt immer so in der Serverless-Welt.
49:42
Und so sieht das dann praktisch aus. Hier sehen wir erstmal nichts. Und dann gibt es plötzlich eine Anfrage. Dann wird Datenbank assigned. Dann werden mehr Connections oder mehr Abfragen abgefordert. Das wird autoskaliert. Fünf Minuten nichts, pausiert. Dann kommen wieder Anfragen, wird wieder Upscaling getriggert, werden weniger Fragen getriggert.
50:02
Dann passiert Scaledown und so weiter. Typisches Verhalten, wenn man Up- und Downscaling macht, nur eben mit der Relationalen Datenbank. Und die Use Cases dafür sind, wenn man einfach Relationalen Datenbank mag, und nicht ein NoSQL-Ding.
50:22
Ja, tatsächlich ganz normal, was bei solchen Serverless-Anwendungen in der Rolle spielt, seltene Jobs und mit großen Spikes. Test-Dev-Datenbank ist eine super Variante. Da können wir auch mit Cults starten, mit Dingen, die wir sprechen, die gut umgehen. Und wir zahlen nicht, also Dev-Umgebung, die die ganze Zeit pausiert ist.
50:40
Das ist auch super. Oder Test-Umgebung und so weiter. Aber es gibt diese Scaled Start. Wenn zum ersten Mal die Anfrage kommt und es noch keine Instanz assigned, dann muss erst mal aus dem Pool geholt werden und so weiter. Und das kann ein paar Sekunden dauern. Für Dev-Test-Umgebung ist es super, aber für Live-Umgebung, das kann schon zu Problemen führen.
51:01
Vor allem, weil wiederum in der initialen Implementierung, wer weiß, muss man eine relationale Datenbank hinter VPC stecken. Das ist bei Amazon Cloud so. Da muss man auch lernen, dahinter VPC stecken. In dieser Konfiguration ist Cults Start der erste Aufruf.
51:21
Das kann bis ca. 10 Sekunden dauern. Weil VPC fügt diese Latenzen hinzu. Und das war mit der größten Wunsch, von dieser VPC wegzukommen, um diese Latenzen nicht zu haben. Weil zum Beispiel DynamoDB ist einfach ein TTP-Engtpunkt, den wir sprechen. Da gibt es keine VPC und so weiter dazwischen.
51:42
Und genauso ähnliches wollte man auch für Aurora Serverless haben und nicht hier mit VPC zu hantieren. Der zweite Grund war, in der relationalen Datenbank baut man solche Dinge wie Connection-Pools auf. Und das ist für Serverless Anwendung aber nicht gut. Weil Serverless-Funktionen werden
52:01
ein paar Millisekunden ausgeführt und der Aufbau solcher Pools dauert. Mehr dazu, Container werden auch nach gewisser Logik auch mal rausgeschmissen von Amazon. Spätestens nach einer Stunde der Nicht-Aktivierung. Und dann muss wieder der Pool aufgebaut werden. Und diese Connection-Pool, das stand so im Wege. Und jetzt gibt es so eine, das heißt Data-EPI
52:20
in Beta, erstmal für MySQL, wo man pro Tabelle sagen kann, will man VPC-Endpunkt haben oder diese Data-EPI verwenden, die eigentlich TTP-Endpunkt ist. Und das jetzt mit der letzte Folie kurz zu zeigen, wie sowas funktioniert. Einfach Data-Service importieren und hier das Wichtige ist, dass das Endpunkt
52:41
des Clusters SQL-Statement der prepared ist. Hier geben wir die Variablen rein. Diese ID, die hier definiert ist und geben hier die Datenbank-Name. Und dann können wir einfach dieses Statement ausführen. Und in dieser Variante ist es praktisch dann komplett HTTP-basiert.
53:00
Performance ist im Moment noch nicht super gut. Vergleichbar zu DynamoDB, aber trotzdem viel schneller als wenn wir das hinter VPC stecken. Und es wird ziemlich viel JSON noch zurückgeschickt. Da arbeiten sie noch dran, um dieses Payload zu verkürzen, weil man mit dem, man kann mit den Daten auch nicht viel anfangen, die zurückkommen, die brauchen wir
53:21
eigentlich nicht zur Verarbeitung. Aber trotzdem ist es vielversprechend und vermutlich auch so die Zukunft, wenn man eine Relationale Datenbank in Serverless umfällt, tatsächlich nutzen kann. Wie gesagt, wenn er tatsächlich viel Erfahrung hat in Serverless umfällt, auch wenn Amazon Serverless vermutlich teurer wird als DynamoDB, diese Lernkurve
53:41
und so weiter, diese Erfahrung zu sammeln, das kostet auch Zeit und wiederum Geld. Deswegen, wenn Datenbank skaliert und Erfahrung hat mit Relationale Datenbank, dann kann man damit auch bleiben. Wie gesagt, das ist erstmal nur MySQL und Postgres Variante kommen sicherlich innerhalb der nächsten Monate. Das ist im Prinzip alles, was wir
54:00
euch so erzählen wollten, über die Learnings und gewisse Dinge, mit denen wir in Serverless Anwendungen hier zu tun hatten. Wir haben glaube ich noch ein paar Minuten für Fragen.
54:22
Ihr habt ja jetzt eine Batchstrecke, also ein Architekturmuster, was man eigentlich schon seit 30 Jahren verwendet, versucht auf Serverless nachzubauen. Ich würde behaupten, und Frage ob ihr schon mal drüber nachgedacht habt, ich würde behaupten, wenn ihr von der Batchverarbeitung runtergeht und versucht das zu
54:41
asynchron mit Messaging aufzubauen, sodass es permanent verarbeitet wird, werden sehr viele von den Problemen, die ihr jetzt beschrieben habt, sich in Luft auflösen. Habt ihr da schon mal versucht, drüber nachzudenken und diesen Batch Ansatz aufzugeben? Also, wir haben uns überlegt anstelle das eine Lambda, die andere aufruft, dass wir da SQS dazwischen
55:01
stellen und solche Dinge, wo wir throughput auch selbst kontrollieren aus der Anwendung heraus. Allerdings glaube ich nicht, dass zum Beispiel die Probleme von DynamoDB sich lösen lassen, weil wir irgendeinen persistenten Storage benötigen. Wir haben in der ersten Variante sogar ohne DynamoDB gemacht und gewisse Dinge, die wir schon vorkalkuliert haben auf S3 abgelegt.
55:21
Aber das war nicht bequem dort zu suchen, unterschiedliche Monatssätze in einer Datei, dafür ist die Datei nicht da. Deswegen, wir haben uns tatsächlich entschieden, Datenbank zu verwenden. Ich glaube, die sehr viele Fehler, die wir zu tun haben, die haben eben mit DynamoDB zu tun. Und da wusste ich nicht, wie ich das anders lösen kann. Wie gesagt,
55:41
mit Undemand Capacity ist es viel einfacher geworden, aber erst anderthalb Jahre nachdem wir das erstmal aufgesetzt haben. Also, mit dem gebatchten Ansatz meine ich, ihr versucht das Ganze einmal pro Monat zu machen. Die eigentlichen Abrechnungssätze, wie sie jetzt von euren Partnern reinkommen, die quasi, wie sie reinkommen,
56:01
halt in den Millisekundentakt direkt durch die ganze Kette zu schieben und nicht die Kette einmal im Monat laufen zu lassen. Das war das, was ich meinte, mit dem gebatchten Ansatz oder dem Messaging. Ich habe verstanden, ja, wäre sicherlich interessant. Aber ich glaube, da muss man viel mehr damit zu tun haben, ob wir das
56:21
reproduzieren können, wenn ein Satz verloren geht. Wie können wir sicherstellen, dass wir nichts verloren haben. Unsere Berechnung ist idempotent. Wir können die mehrfach laufen lassen, die bringt das gleiche Ergebnis. Wenn wir natürlich die Dinge streamen und irgendwas verloren geht, werden wir höchstwahrscheinlich das nicht mal bemerken. Ich verstehe schon das.
56:41
Ich verstehe, was du meinst, ja. Weitere Fragen? Ich sehe keine. Vielen Dank, haben wir doch pünktlich geschafft.