Ein Blog über Code, Hardware und Co

Storj

Wie ich 3,5 Monate meiner Storagenode-Einnahmen verloren habe

Durch den betrieb eines oder mehrerer Storagenodes im Storj-Netzwerk wird man nicht reich. Umso ärgerlicher ist es daher, wenn einem auch die geringen Vergütungen verloren gehen – so ist es mir passiert. Gott sei Dank ließ sich das Problem leicht lösen.

Eigentlich habe ich meine Storagenodes im Hintergrund laufen und verstehe die Auszahlungen als passives Einkommen. Ein kleines Zubrot nebenher 😉
Allerdings ist mir im Laufe der Zeit aufgefallen, dass die Einnahmen meines ersten Storagenodes massiv abgefallen sind und weit unterhalb der Erwartungen lagen.

Also habe ich mir den Node etwas genauer angeschaut.
Und siehe da: Irgendwie ist seit einigen Monaten kein ausgehender Traffic in den Statistiken zu sehen – und dementsprechend auch nicht vergütet worden. Der letzte Monat, in dem Traffic erfasst worden ist, ist März 2020 gewesen.

Es handelt sich auch um keinen Anzeigefehler. Auch in der Auszahlungshistorie in meinem Wallet sehe ich, dass ich keine Auszahlungen für Traffic erhalten habe.

Die Ursache des Problems: Eine gelockte Datenbank

Also bin ich auf Ursachenforschung gegangen. Zunächst ging ich von einem problem auf Satellitenseite aus, da ich in meinem log des Storagenodes nicht sonderlich außergewöhnliches feststellen konnte.
Allerdings wurde dieses Log auch mit jedem Neustart des Storagenode-Containers bzw. des NAS gelöscht und begann danach von vorne.
Tipp: Seitdem speichere ich die logs meiner Storagenodes persistent in einem anderen Verzeichnis, sodass sie nicht in der Konsole des jeweiligen Docker-Containers landen und nach jedem Neustart des Containers verschwunden sind.

Also habe ich einen Thread im Forum des Storj-Projekts erstellt und dann auf Anraten ein Support-Ticket erstellt.

Das Team erkannte, dass mein Node tatsächlich keine Bandwith-Orders an den Satelliten übermittelt hatte*.
Ich sammelte nun für einige Zeit die Logs des Nodes und es erschienen einige Fehler, z.B.:

WARN orders DB contains invalid marshalled orders {"error": "ordersdb error: database disk image is malformed", "errorVerbose": "ordersdb error: database disk image is malformed\n\tstorj.io/storj/storagenode/storagenodedb.(*ordersDB).ListUnsentBySatellite:169\n\tstorj.io/storj/storagenode/orders.(*Service).sendOrders:177\n\tstorj.io/storj/storagenode/orders.(*Service).Run.func1:134\n\tstorj.io/common/sync2.(*Cycle).Run:92\n\tstorj.io/common/sync2.(*Cycle).Start.func1:71\n\tgolang.org/x/sync/errgroup.(*Group).Go.func1:57"}

Und in diesem Fehler bzw. diesen Logeintragen fand sich der Schlüssel zu meinem Problem: Das Storj Netzwerk funktioniert auf Basis sog. „orders“. Wenn ein Kunde ein File downloaden möchte, welches auf meinem Node gespeichert ist, wird dafür eine Order erzeugt und das Teilstück des Files heruntergeladen. Auf Basis dieser Orders wird dann die Vergütung des Storagenodes errechnet.
Die Datenbank, die diese Orders speichert und mit dem Satelliten abgleicht ist bei meinem Node „locked“, also gesperrt.

Die Folge ist, dass keine neuen Einträge und damit auch keine neuen Orders mehr eingetragen und gespeichert werden können. Der Node funktionierte also, es gab Traffic. Er wurde nur nicht getrackt und vergütet.

Die Lösung: Datenbank reparieren

Wie kann ich das Problem nun heben, wenn das Kind bereits in den Brunnen gefallen ist, ohne meinen Node zu verlieren?

Gott sei dank, gibt es eine Möglichkeit. SQLite bietet eine integrierte Möglichkeit, defekte Datenbankfiles zu reparieren.

Das Storj-Team hat eigens eine Anleitung dafür verfasst: https://support.storj.io/hc/en-us/articles/360029309111-How-to-fix-a-database-disk-image-is-malformed-

Mein Tipp: Nutzt für das Reparieren der orders.db unbedingt eine Ramdisk. Das Beschleunigt den Prozess enorm.
Ich hatte den Prozess zunächst auf der ursprünglichen Festplatte begonnen. Hier hätte die Reparatur Monate oder Jahre (!) gebraucht.
Selbst auf einer SSD hätte ich noch tagelang warten müssen. Tage, in denen mein Node offline gewesen wäre.
Mit Hilfe einer Ramdisk ging die Reparatur dann innerhalb von zwei Stunden.

Wie kann man das in Zukunft vermeiden?

Locks von SQLite Datenbanken kommen zustande, wenn auf der jeweiligen Datenbank bzw. dem jeweiligen Datenbankfile gerade andere Aktionen durchgeführt werden.

Das Datenbankfile wird dann gelockt. Wenn die Input/Output-Operationen I/O derart ansteigen, dass die Festplatte bzw. das System überlastet sind, kann es vorkommen, dass ein derartiger Lock nicht mehr verschwindet.

Besonders SMR-Festplatten sind beim Betrieb von Storagenodes bzw. allgemein für gelockte SQLite-Files anfällig, da sie nur eine geringere Anzahl an I/O-Operationen durchführen können und merklich langsamer sind, als ihre CMR Pendants.

SMR steht für Shingled Magnetic Recording, eine Technologie, die die Art und weise beschreibt, wie Daten auf einen magnetischen Datenträger (Festplatte) geschrieben werden.
SMR ist eine neuere Technologie, die eine weitaus höhere Datendichte erlaubt und damit mehr Daten je Platter einer HDD ermöglicht.
Diese Technologie geht jedoch zu Lasten insbesondere der Schreibrate bei vielen kleinen Daten.
Die herkömmliche Technologie ist CMR/PMR.

In Zukunft: Speicher mit viel I/O-Leistung

Da das Problem durch Locks der Datenbankfiles durch langsame Festplatten und eine (zu) hohe I/O-Auslastung zustande gekommen ist, habe ich die stark frequentierten Datenbankfiles auf eine schnelle SSD ausgelagert.

Die I/O-Leistung von SSD-Speicher ist um ein Vielfaches höher. Seitdem habe ich keine Probleme mehr.

Die Storagenode-Software bietet dazu in der Docker-Version eine Variable, die man in der config-Datei anpassen kann. Hier kann man den Pfad zu den Datenbankfiles hinterlegen.

Fazit

Die Einnahmen sind verloren, schade. Trotzdem habe ich eine Menge über die Funktionsweise eines Storagenodes und vor allem von SQLite Datenbanken bzw. filebasierten Datenbanken gelernt.

Update Oktober 2020:
Da genau dieses Problem sowie andere Probleme, die mit einer gesperrten orders-Datenbank zusammenhingen, sind mittlerweile vom Storj-Team adressiert worden.

Seit Version 1.13.X werden Orders nicht mehr in einer Datenbank gespeichert, sondern direkt auf Fileebene. Dadurch entfällt die oben beschriebene Problematik zumindest bei den betroffenen Datenbankfiles 😉

Schreibe eine Antwort