Laden...

Zwei Dienste mit Azure Blob-Storage, Transaktionssystem und Synchronsation

Erstellt von Palladin007 vor 2 Jahren Letzter Beitrag vor 2 Jahren 401 Views
Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren
Zwei Dienste mit Azure Blob-Storage, Transaktionssystem und Synchronsation

Guten Morgen,

folgende Vorgaben: .NET 4.7.2, ASP.NET (ohne Core), Azure Blob-Storage
Es geht um eine Web-API, über die sehr große XML-Dokumente verwaltet werden sollen. Heißt: Upload, Update (inklusive Zusammenführung) und Download.
Dazu gibt's noch ein paar andere kleinere Funktionen, aber die sind Kleinkram.

Kompliziert machen es folgende Anforderungen:* Die Daten sollen auf einem Azure Blob-Storage abgelegt werden

  • Es soll jederzeit, auch im Fehlerfall, Server-Absturz, Stromausfall, etc. ein gültiger Stand geladen werden können. Für mich klingt das nach einem Transaktionssystem
  • Es sollen zwei Dienste in jeweils eigenen Netzwerken mit eigenem Blob-Storage laufen und sich untereinander synchronisieren. Ein Load Balancer verteilt die Requests
  • Es darf kein unterschiedlicher Datenstand entstehen, auch nicht, wenn zwei Daten-Updates bei beiden Diensten gleichzeitig ankommen

Ich beschreibe meine Gedanken dazu erst mal nicht, da ich keine wall of text hinterlassen will, die am Ende nur abschreckt 😁

Meine Frage ist jetzt:
Hat jemand eine Idee, wie man sowas angehen kann, oder gibt es bereits Konzepte, die sowas in der Art behandeln?

Vielen Dank und Beste Grüße

16.828 Beiträge seit 2008
vor 2 Jahren

Für mich hört sich das nach einer Ausschreibung an, an der Du teilnimmst.
Immer schwierig da Aussage zu bewerten, weil da meist Leute Texte schreiben, die kein Plan haben.

ASP.NET (ohne Core)

Hahahahhahahaa - sorry, musste sein.

Für mich klingt das nach einem Transaktionssystem

So formuliert kann das alles heissen.

Es sollen zwei Dienste in jeweils eigenen Netzwerken mit eigenem Blob-Storage laufen und sich untereinander synchronisieren.

Das is halt Bullshit. Das hat sicher jemand geschrieben, der keine Ahnung hat, was er da will oder wie die Dienste funktionieren.
Globale/Multi Redundanz kann man von Haus aus im Storage definieren, entweder über ZRS oder GRS/GZRS. Wenn nicht alles von der primären Region abhängig sein soll, dann bleibt nur GRS/GRZS; es gibt keine native Synchronisationsmöglichkeit vom Blobstorage - so funktioniert das Ding einfach nicht.

Es darf kein unterschiedlicher Datenstand entstehen, auch nicht, wenn zwei Daten-Updates bei beiden Diensten gleichzeitig ankommen

Streng genommen ist diese Anforderung nicht erfüllbar, wenn man nicht auf ZRS/GRZS setzt.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren

Hahahahhahahaa - sorry, musste sein.

Ich weiß was Du meinst 😁

Für mich hört sich das nach einer Ausschreibung an, an der Du teilnimmst.

Nein, keine Ausschreibung 😁
Ist ein laufendes Projekt, bisher auch noch halbwegs realistisch gewesen, bis den Verantwortlichen das mit dem zweiten Dienst eingefallen ist.
Und scheinbar (so klang das) arbeiten derzeit alle Systeme von denen so, wie viele davon eine Web-API mit Blob-Storage sind, weiß ich aber nicht.

Globale/Multi Redundanz kann man von Haus aus im Storage definieren, entweder über ZRS oder GRS/GZRS. Wenn nicht alles von der primären Region abhängig sein soll, dann bleibt nur GRS/GRZS

Ich muss aber auch dazu sagen, dass ich vom Blob-Storage so gar keine Ahnung habe (außer wie ich daten hoch und runter lade), aber ich schau mir mal an, was Du mit "ZRS oder GRS/GZRS" meinst. Ob ich irgendeinen Einfluss nehmen kann - vermutlich nicht ...

Das "Transaktionssystem" realisiere ich derzeit so, dass ich mehrere Versionen pflege und daneben je Version in einer kleinen Datei speichere, was die aktuelle Version ist und wo die Inhalte zu finden sind, mit ein paar zusätzlichen Infos. Wurde diese Datei der letzten Version aus irgendeinem Grund nicht vollständig geschrieben wurde (kann leicht geprüft werden, weil klein), gilt die Version als kaputt und ich greife auf den vorherigen Stand zurück.
Ungefähr das ist auch die Anforderung - tritt ein Fehler auf oder ist der Strom weg, muss danach der letzte gültige Stand gefunden werden können.

Mein Konzept zur Synchronisation greift in dem "Transaktionssystem" ein.
Wenn ein Request eine Datei nutzen möchte, muss er erst mal prüfen, ob die schon genutzt wird, dann den Zugriff für Andere sperren, den neusten Stand suchen, damit arbeiten, speichern, freigeben. Das macht das "Transaktionssystem".
Die Synchronisation könnte man so realisieren, dass jeder dieser Schritte mit dem zweiten Dienst synchron ausgeführt wird. Soll auf eine Datei zugegriffen werden, dann müssen beide Dienste den Zugriff gestatten und beide anschließend sperren und zum Schluss wird die neue Version zum anderen Dienst geschickt.
Der Knackpunkt ist, dass beide Dienste die Versions-Datei schreiben müssen, aber je, 100% absichern kann ich das nicht, aber ich kann versuchen, möglichst nahe an die 100% zu kommen.

Ich hatte auf Ideen gehofft, die mein recht komplexes Konzept als "zu komplex" strafen, aber wenn ich dich richtig verstehe, liege ich mit meiner Einschätzung, dass das eigentlich eine irre Anforderung ist, gar nicht so falsch. Umsetzen muss ich sie vermutlich trotzdem...

16.828 Beiträge seit 2008
vor 2 Jahren

was Du mit "ZRS oder GRS/GZRS" meinst. Datenredundanz - Azure Storage

Das "Transaktionssystem" realisiere ich derzeit so, dass ich mehrere Versionen pflege und daneben je Version in einer kleinen Datei speichere, was die aktuelle Version ist und wo die Inhalte zu finden sind, mit ein paar zusätzlichen Infos.

Siehe Blobversionsverwaltung - Azure Storage

dass das eigentlich eine irre Anforderung ist, gar nicht so falsch.

zum einen die Anforderung, denn sie verletzt mehrere Prinzipien, darunter das Prinzip der Datenhoheit, dass mehrere (verschiedene) Services normalerweise nicht die gemeinsame Datenbasis haben sollen. Und dann noch die Umsetzungsvorgabe der manuellen Synchronisation, die wirklich - man kanns nich anders sagen - eine sehr dumme Idee ist.
Fällt unter den Punkt Decentralized Governance, den Martin Fowler im Prinzip der Microservices niedergerschrieben hat.

Und dann halt noch die Tatsache, dass man den Storage selbst synchronisieren lassen sollte - mit seinen ausgereiften Features - und nichts drüber bauen sollte.
Traffic-Routing kann man auch einfach mit der Frontdoor machen.

Manuelles Synchronisieren kostet übrigens auch viel Geld, weil der Storage pro Zugriff bezahlt werden (pay by transaction) muss und natürlich jeder Touch damit eine Transaktion darstellt.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren

Danke für die Links, ich schau mir das mal an.

Die Versionsverwaltung scheint auf den ersten Blick ganz nützlich zu sein, in den Metadaten kann ich dann die anderen Informationen speichern, die ich zusätzlich noch brauche.
Was mich dabei aber etwas stört: Ich finde keinen Weg, eine Liste der Versionen abzurufen ...?
Ich finde auch keine info, ob der Emulator das überhaupt kann. Ich muss aber den Emulator nutzen, denn auf den tatsächlichen Blob-Storage habe ich kein Zugriff und kann auch nichts testen und einen eigenen Storage haben wir nicht.

Bezüglich der Synchronisation:
Wie es zuletzt klang, ist das ein KO-Kriterium. Die haben das bei anderen Systemen schon lange so und wollen das auch weiterhin so haben.
Ich spreche es trotzdem nochmal an, wirklich Hoffnung habe ich aber nicht.

Manuelles Synchronisieren kostet übrigens auch viel Geld, weil der Storage pro Zugriff bezahlt werden

Das ist ein wertvoller Hinweis, den habe ich (und sonst kein anderer) beachtet. Bisher klang es eher so, dass der Speicherplatz der ausschlaggebende Faktor ist.
Ich gehe dem nach, doch zur Not kann ich zumindest einige Lesezugriffe cachen, doch an den Schreibzugriffen ändert das natürlich nichts.

PS zum Thema Redundanz:
Die zwei Systeme sollen eher ein Schutz gegen Ausfallsicherheit darstellen.
Es geht hier also nicht um Datensicherheit (können jederzeit wiederhergestellt werden), sondern darum, dass die Clients, die diese Daten abrufen, jederzeit und möglich schnell einen gültigen Stand bekommen können - und natürlich alle Clients den selben Stand.

16.828 Beiträge seit 2008
vor 2 Jahren

Die VersionId ist Teil der Metadaten, siehe https://subhankarsarkar.com/document-versioning-with-azure-blob-storage/
Er schreibt, dass die Versionsauflistung nicht Teil des NuGets ist; weiß nicht, ob das heute auch noch so ist.

Ich hab das das letzte mal benötigt, als ich den Storage vom php Forum auf das jetzige .NET Forum migriert habe, und da hab ich die Azure CLI und den Storage Explorer verwendet; beide können das (weils Teil der Azure API ist).

Wie es zuletzt klang, ist das ein KO-Kriterium. Die haben das bei anderen Systemen schon lange so und wollen das auch weiterhin so haben.

Ja, leider oft mit Technologien so, dass sich Entwickler die Konzepte nicht durchlesen und einfach nen Krampf zusammen programmieren (eher schustern).
Ist kein spezielles Cloud-Problem; im Falle von Cloud kommt aber leider hinzu, dass viele versuchen On Prem Art und Weisen (weil sie es immer schon so getan haben) bauen, die in der Cloud aber gar nicht funktionieren, viele Schwachstellen haben oder ganz einfach sehr teuer sind.

Hab da wenig Mitleid; sind vielleicht, wenn sie ordentlich auf die Nase gefallen sind, irgendwann mal meine Kunden 🙂

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren

Die VersionId ist Teil der Metadaten, siehe
>

Er schreibt, dass die Versionsauflistung nicht Teil des NuGets ist; weiß nicht, ob das heute auch noch so ist.

Sowas ähnliches habe ich auch gerade gefunden:
https://subhankarsarkar.com/document-versioning-with-azure-blob-storage/
Ich habe den Artikel nicht durch, aber da gibt's auch ein Stück Code, was die Versionen mit Hilfe der REST-API abruft, im Framework finde ich immer noch keine vergleichbare Funktion.
Zur Not mache ich es über die REST-API, damit ließe sich vermutlich das "Transaktionssystem" umsetzen, vielleicht sogar etwas einfacher, als ich mir das erst gedacht hatte.
Leider kann ich damit die DateiSystem-Alternative (will mein Chef zum Testen) nicht mit einem "Transaktionssystem" ausstatten, aber das ist denke ich verkraftbar.

Das mit der Synchronisation bleibt aber ein Problem. Ich glaube nicht, dass ich daran etwas ändern kann, dafür fehlt mir auch einfach die Rückendeckung aus der eigenen Geschäftsführung 😠

16.828 Beiträge seit 2008
vor 2 Jahren

Jo, dann würde ich halt auch schon so ne Puzzlelösung umsetzen, wie der Kunde das will.
Wenn er sich am Ende beschwert kannst sagen: wir haben Dir erzählt, wie es richtig geht - selbst schuld.

Aber immer schön schriftlich festhalten 🙂

16.828 Beiträge seit 2008
vor 2 Jahren

Ach, und:

Die zwei Systeme sollen eher ein Schutz gegen Ausfallsicherheit darstellen.
Es geht hier also nicht um Datensicherheit (können jederzeit wiederhergestellt werden), sondern darum, dass die Clients, die diese Daten abrufen, jederzeit und möglich schnell einen gültigen Stand bekommen können - und natürlich alle Clients den selben Stand.

Dafür gibts bessere Methoden als zwei getrennte Systeme zu haben.
Aber ja: das ist ein typisches 1980er Vorgehen aus der On Prem IT - macht man so in der Cloud nicht.

Azure hat dafür fertige Referenzarchitekturen
Hochverfügbare Webanwendungen für mehrere Regionen - Azure Architecture Center
TLDR; Datenreplikation sollte man niemals selbst machen, sondern Azure-Features überlassen, egal ob DB, Storage oder andere Sinks.

Die Regionen lassen sich mit der Referenzarchitektur nicht nur als Aktiv/Passiv umsetzen, sondern auch Global-Redudant.
Dabei wird in der Frontdoor das Backend als Pool angelegt. Die Frontdoor entscheiden dann anhand verschiedener Parameter (Location, Latency, Auslastung) welches Backend die Anfrage erhält (quasi als Load Balancer).
Der Storage ist ebenfalls gemeinsam Global-Redudant.

So ist übrigens auch mycsharp.de ausgelegt, wobei wir nur eine Region haben (Deutschland).
Wir könnten aber einfach auch eine weitere Region in den Pool hinzufügen und wären damit Multi-Region redundant.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren

Ich hab gerade nochmal erfragt, wie das zusammenhängt und dabei hat sich ergeben, dass es hier um zwei vollständig unabhängige Azure Stack Umgebungen geht. Wie genau das zusammenhängt, weiß ich aber nicht.

Meine aktuellen Gedanken dazu, wie man es umsetzen könnte:

Ich bleibe bei dem Transaktionssystem, lass aber Versionen und die notwendigen Metadaten von Azure verwalten. In den Metadaten steht dann sowas wie aktueller Nutzer, wer gerade wartet und ob die Datei fertig geschrieben wurde. Will eine andere Anwendung darauf zugreifen, wartet sie, bis die Datei wieder freigegeben wird. Eventuell kann ich hierfür auch Zugriffsberechtigungen nutzen, dass eine Anwendung nicht nicht darauf zugreifen darf, wenn eine andere Anwendung arbeitet?
Will eine Anwendung auf eine Datei zugreifen, die nicht als "fertig" markiert wurde (im Fehlerfall, Absturz, etc.), gilt die als ungültig und es wird die vorherige Version verwendet - damit realisiere ich die Ausfallsicherheit, dass immer ein gültiger Stand gefunden werden kann.
Und alle Anwendungen greifen gleichzeitig auf dem selben Stand vom Blob-Storage zu, was die Synchronisation hinfällig macht.
Die Ausfallsicherheit wäre dann gegeben, indem die Anwendung in mehreren Rechenzentren laufen und der Blob-Storage kümmert sich im Hintergrund um das redundante Speichern der Daten.

Das könnte eine Lösung sein, doch ob das so akzeptiert wird, steht auf einem anderen Blatt.

Besten Dank für deine Hilfe 🙂

16.828 Beiträge seit 2008
vor 2 Jahren

Kannst Daten auch mit Bordmitteln zwischen zwei Stacks syncen.
Sichern Ihrer Speicherkonten in Azure Stack Hub - Azure Stack Hub - sowohl untereinander wie auch zur Public Cloud.

Palladin007 Themenstarter:in
2.079 Beiträge seit 2012
vor 2 Jahren

Oder ich schicke die Requests direkt zu beiden Storages - das schreiben sie ja auch im ersten Punkt "Anwendungsschicht".
Wenn ich die Versionierung und Metadaten für die Transaktionen nutzen darf, könnte das ein guter Mittelweg sein.
Ob ich das nutzen darf, klärt sich hoffentlich am Montag.

Bis dahin:

Vielen Dank für die Hilfe 🙂
Erstaunlich, was das alles kann und wie fatal es sein kann, nicht vorher die Doku von vorne bis hinten zu lesen, das muss ich auch auf meine Kappe nehmen.