Storacle – ein dezentrales Dateispeicher-System

Storacle – ein dezentrales Dateispeicher-System

Bevor ich beginne, möchte ich einen Link zu dem vorherigen Artikel, um klarzustellen, worum es genau geht.

In diesem Artikel möchte ich die Schicht besprechen, die für die Dateispeicherung verantwortlich ist und wie sie von jedem genutzt werden kann. Storacle ist eine eigenständige Bibliothek, die direkt nichts mit Musik zu tun hat. Es können beliebige Dateien gespeichert werden.

In dem vorherigen Artikel habe ich etwas "kritisiert" ipfs, aber das geschah genau im Kontext der von mir gelösten Aufgabe. Insgesamt halte ich dieses Projekt für großartig. Mir gefällt einfach die Möglichkeit, verschiedene Netzwerke für unterschiedliche Aufgaben zu erstellen. Das ermöglicht eine bessere Strukturorganisation und reduziert die Last auf einzelnen Knoten und dem Netzwerk insgesamt. Man kann sogar innerhalb eines bestimmten Projekts, falls nötig, das Netzwerk nach bestimmten Kriterien in Teile zerlegen, um die allgemeine Last zu senken.

Also verwendet storacle einen Mechanismus spreadable zur Organisation des Netzwerks. Die Hauptmerkmale sind:

  • Dateien können über jeden Knoten in den Speicher hinzugefügt werden.
  • Dateien werden vollständig gespeichert, nicht in Blöcken.
  • Jede Datei hat ihren eigenen einzigartigen Hash basierend auf dem Inhalt für die weitere Bearbeitung.
  • Dateien können zur Erhöhung der Zuverlässigkeit dupliziert werden
  • Die Anzahl der Dateien auf einem Knoten ist nur durch das Dateisystem begrenzt (es gibt eine Ausnahme, die weiter unten erläutert wird)
  • Die Anzahl der Dateien im Netzwerk ist durch die Möglichkeiten von spreadable hinsichtlich der zulässigen Knoten im Netzwerk begrenzt, die in der zweiten Version die Arbeit mit einer unbegrenzten Anzahl von Knoten ermöglichen werden (darüber in einem anderen Artikel)

Ein einfaches Beispiel, wie das überhaupt aus dem Programm funktioniert:

Server:

const  Node = require('storacle').Node;

(async () => {
  try {
    const node = new Node({
      port: 4000,
      hostname: 'localhost'
    });
    await node.init();
  }
  catch(err) {
    console.error(err.stack);
    process.exit(1);
  }
})();

Client:

const  Client = require('storacle').Client;

(async () => {
  try {
    const client = new  Client({
      address: 'localhost:4000'
    });
    await client.init();
    const hash = await client.storeFile('./my-file');
    const link = await client.getFileLink(hash); 
    await client.removeFile(hash);
  }
  catch(err) {
    console.error(err.stack);
    process.exit(1);
  }
})();

Ein Blick hinter die Kulissen

Unter der Haube gibt es nichts Übernatürliches. Informationen über die Anzahl der Dateien, deren kumulierte Größe und andere Details werden in einer In-Memory-Datenbank gespeichert und bei der Löschung und Hinzufügung von Dateien aktualisiert. Daher ist es nicht notwendig, häufig auf das Dateisystem zuzugreifen. Eine Ausnahme bildet der Einschluss des Garbage Collectors, wenn eine Zirkulation von Dateien erforderlich ist, sobald bestimmte Speicherkapazitäten erreicht werden, und nicht das Verbot, neue Dateien hinzuzufügen. In diesem Fall muss das Speichersystem durchlaufen werden, und die Arbeit mit einer großen Anzahl von Dateien (> eine Million zum Beispiel) kann erhebliche Lasten verursachen. Es ist besser, weniger Dateien zu speichern und mehr Knoten zu betreiben. Wenn der "Reiniger" deaktiviert ist, gibt es dieses Problem nicht.

Der Dateispeicher besteht aus 256 Ordnern und 2 Ebenen der Verschachtelung. Dateien werden in den Ordnern der zweiten Ebene gespeichert. Bei 1 Million Dateien wären in jedem dieser Ordner etwa 62500 Dateien vorhanden (1000000 / sqrt(256)).

Die Namen der Ordner werden aus dem Hash der Datei generiert, um schnellen Zugriff zu ermöglichen, wenn der Hash bekannt ist.

Diese Struktur wurde auf der Grundlage einer Vielzahl unterschiedlicher Anforderungen an den Speicher gewählt: Unterstützung für schwache Dateisysteme, in denen nicht viele Dateien in einem Ordner vorhanden sein sollten, schneller Zugriff auf alle Ordner bei Bedarf usw. Eine Art goldene Mitte.

, das durch Pufferpools bereitgestellt wird.

Beim Hinzufügen von Dateien sowie beim Abrufen werden Links zu Dateien im Cache gespeichert.
Dank dessen ist es häufig nicht erforderlich, das gesamte Netzwerk nach einer Datei zu durchsuchen. Dies beschleunigt den Erhalt von Links und verringert die Netzwerkbelastung. Das Caching erfolgt auch über HTTP-Header.

Isomorphismus

Der Client ist in JavaScript geschrieben und ist isomorph, er kann direkt aus dem Browser verwendet werden. 
Es kann eine Datei https://github.com/ortexx/storacle/blob/master/dist/storacle.client.js als Skript hochgeladen werden, um Zugriff auf window.ClientStoracle zu erhalten oder über ein Build-System zu importieren usw.

Verzögerte Links

Eine interessante Funktion ist der "verzögerte Link". Dies ist ein Link zu einer Datei, die synchron abrufbar ist, und die Datei wird abgerufen, sobald sie im Speicher gefunden wird. Dies ist sehr praktisch, wenn man beispielsweise auf einer Website Bilder anzeigen möchte. Einfach den verzögerten Link in src einfügen und das war's. Es gibt viele Anwendungsfälle.

Client-API

  • async Client.prototype.storeFile() — Datei speichern
  • async Client.prototype.getFileLink() — direkten Link zur Datei abrufen
  • async Client.prototype.getFileLinks() — Liste der direkten Links zur Datei von allen Knoten abrufen, an denen sie vorhanden ist
  • async Client.prototype.getFileToBuffer() — Datei im Puffer abrufen
  • async Client.prototype.getFileToPath() — Datei im Dateisystem abrufen
  • async Client.prototype.getFileToBlob() — Datei als Blob abrufen (für die Browser-Version)
  • async Client.prototype.removeFile() — Datei löschen
  • Client.prototype.createRequestedFileLink() — verzögerten Link erstellen

Dateiexport auf einen anderen Server

Um Dateien auf einen anderen Knoten zu übertragen, können Sie:

  • Einfach den gesamten Speicherordner mitsamt den Einstellungen kopieren. (In Zukunft könnte das nicht funktionieren)
  • Nur den Ordner mit den Dateien kopieren. In diesem Fall muss jedoch die Funktion node.normalizeFilesInfo(), einmalig ausgeführt werden, um alle Daten neu zu berechnen und in die Datenbank einzugeben.
  • Die Funktion node.exportFiles(), die den Dateiübertrag startet.

Haupteinstellungen des Knotens
Beim Starten des Speicher-Knotens können alle erforderlichen Einstellungen angegeben werden.
Ich werde die wichtigsten beschreiben, das andere kann auf GitHub gefunden werden.

  • storage.dataSize — Größe des Ordners mit Dateien
  • storage.tempSize — Größe des temporären Ordners
  • storage.autoCleanSize — die minimale Speicherkapazität, die erhalten werden muss. Wenn dieser Parameter angegeben ist, werden die am wenigsten genutzten Dateien gelöscht, sobald der Speicherplatz knapp wird.
  • file.maxSize — die maximale Dateigröße
  • file.minSize — die minimale Dateigröße
  • file.preferredDuplicates — die bevorzugte Anzahl von Datei-Duplikaten im Netzwerk
  • file.mimeWhitelist — zulässige Dateitypen
  • file.mimeBlacklist — unzulässige Dateitypen
  • file.extWhitelist — zulässige Dateiendungen
  • file.extBlacklist — unzulässige Dateiendungen
  • file.linkCache — verschiedene Link-Cache-Einstellungen

Fast alle mit Größen verbundenen Parameter können sowohl in absoluten als auch in relativen Größen angegeben werden.

Arbeiten über die Befehlszeile
Die Bibliothek kann über die Befehlszeile verwendet werden. Dazu muss sie global installiert werden: npm i -g storacle. Danach können die erforderlichen Aktionen aus dem Verzeichnis mit dem Projekt, wo der Knoten ist, ausgeführt werden. Zum Beispiel, storacle -a storeFile -f ./file.txt -c ./config.js, um eine Datei hinzuzufügen. Alle Aktionen finden Sie in https://github.com/ortexx/storacle/blob/master/bin/actions.js

Warum könnte das für dich nötig sein

  • Wenn du ein dezentrales Projekt erstellen möchtest, in dem du Dateien auf bequeme Weise speichern und bearbeiten kannst. Zum Beispiel verwendet das im Artikel eingangs beschriebene Musikprojekt storacle.
  • Wenn du an anderen Projekten arbeitest, in denen Dateien verteilt gespeichert werden müssen. Du kannst dein eigenes geschlossenes Netzwerk problemlos aufbauen, Knoten flexibel konfigurieren und neue hinzufügen, wenn es nötig ist.
  • Wenn du einfach einen Ort zum Speichern der Dateien deiner Webseite benötigst und es dir zu mühsam ist, alles selbst zu schreiben. Vielleicht ist diese Bibliothek in deinem Fall besser geeignet.
  • Wenn du ein Projekt hast, bei dem du mit Dateien arbeitest, aber alle Manipulationen aus dem Browser heraus durchführen möchtest. Du kannst das Schreiben von Servercode vermeiden.

Meine Kontakte:

Quelle: habr.com

Erwerben Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster