Storacle — zdecentralizowane przechowywanie plików

Storacle — zdecentralizowane przechowywanie plików

Zanim zacznę, muszę zostawić link do poprzedniego artykułu, aby było jasne, o co dokładnie chodzi.

W tym artykule chciałbym omówić warstwę, która odpowiada za przechowywanie plików, oraz jak może być to wykorzystane przez każdego użytkownika. Storacle to niezależna biblioteka, nie ma żadnego bezpośredniego związku z muzyką. Można zorganizować przechowywanie dowolnych plików.

W poprzednim artykule trochę "przekładałem bęben" na ipfs, ale miało to miejsce w kontekście zadania, które realizowałem. Ogólnie uważam ten projekt za świetny. Po prostu bardziej podoba mi się możliwość tworzenia różnych sieci do różnych zadań. Umożliwia to lepszą organizację struktury i zmniejsza obciążenie poszczególnych węzłów oraz sieci jako całości. Nawet w ramach jednego projektu, w razie potrzeby, można podzielić sieć na kawałki według różnych kryteriów, zmniejszając całkowite obciążenie.

Zatem storacle wykorzystuje mechanizm spreadable do organizacji sieci. Główne cechy:

  • Pliki mogą być dodawane do magazynu przez dowolny węzeł.
  • Pliki są przechowywane w całości, a nie w blokach.
  • Każdy plik ma swój unikalny hash według treści do dalszej pracy z nim.
  • Pliki mogą być duplikowane dla większej niezawodności
  • Liczba plików na jednym węźle jest ograniczona tylko przez system plików (jest wyjątek, o którym będzie mowa poniżej)
  • Liczba plików w sieci jest ograniczona możliwościami spreadable co do liczby dozwolonych węzłów w sieci, które w drugiej wersji będą mogły umożliwić pracę z nieskończoną liczbą węzłów (o tym w innym artykule)

Prosty przykład, jak to w ogóle działa z programu:

Serwer:

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);
  }
})();

Klient:

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);
  }
})();

Wgląd od wewnątrz

Pod maską nie ma nic nadzwyczajnego. Informacje o liczbie plików, ich łącznym rozmiarze i innych kwestiach są przechowywane w pamięci i aktualizowane przy usuwaniu i dodawaniu plików, dlatego nie ma potrzeby częstego sięgania do systemu plików. Wyjątkiem jest włączenie zbieracza śmieci, kiedy potrzebna jest cyrkulacja plików przy osiągnięciu określonych rozmiarów przechowalni, a nie zakaz dodawania nowych. W takim przypadku trzeba przeszukać przechowalnię, a praca z dużą liczbą plików (> miliona) może prowadzić do znacznych obciążeń. Lepiej przechowywać mniej plików i uruchamiać więcej węzłów. Jeśli "czyściciel" jest wyłączony, to takiego problemu nie ma.

Przechowalnia plików składa się z 256 folderów i 2 poziomów zagnieżdżenia. Pliki są przechowywane w folderach drugiego poziomu. To znaczy, przy posiadaniu 1 mln plików w każdym takim folderze będzie około 62500 sztuk (1000000 / sqrt(256)).

Nazwy folderów są tworzone z hasha pliku, aby można było szybko uzyskać dostęp, znając hash.

Taka struktura została wybrana ze względu na wiele różnych wymagań dotyczących przechowalni: wsparcie dla słabych systemów plików, gdzie w jednym folderze nie pożądane jest posiadanie wielu plików, szybkie przeszukiwanie wszystkich folderów w razie potrzeby itd. Jest to swoiste złote środek.

Odtwarzanie

Podczas dodawania plików, a także ich pobierania, w pamięci podręcznej zapisywane są linki do plików.
Dzięki temu często nie ma potrzeby przeszukiwania całej sieci w poszukiwaniu pliku. Przyspiesza to uzyskiwanie linków i zmniejsza obciążenie sieci. Również pamięć podręczna działa przez nagłówki HTTP.

Izomorfność

Klient napisany jest w JavaScript i jest izomorficzny, można go używać bezpośrednio z przeglądarki. 
Można załadować plik https://github.com/ortexx/storacle/blob/master/dist/storacle.client.js jako skrypt i uzyskać dostęp do window.ClientStoracle lub zaimportować przez system budowy itd.

Opóźnione linki

Interesującą cechą jest również "opóźniony link". To link do pliku, który można uzyskać synchronicznie, tu i teraz, a plik zostanie pobrany, gdy tylko zostanie znaleziony w przechowalni. Jest to bardzo wygodne, gdy na przykład potrzebne jest pokazanie jakichś obrazków na stronie. Po prostu podstawiamy w src opóźniony link i tyle. Można wymyślić wiele przypadków użycia.

Api klienta

  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.storeFile() — zapis pliku
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.getFileLink() — uzyskanie bezpośredniego linku do pliku
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.getFileLinks() — uzyskanie listy bezpośrednich linków do pliku ze wszystkich węzłów, na których się znajduje
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.getFileToBuffer() — pobierz plik do bufora
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.getFileToPath() — pobierz plik do systemu plików
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.getFileToBlob() — pobierz plik jako blob (dla wersji przeglądarkowej)
  • (196 tysięcy linii kodu, 11 autorów, 7 komiterów, 11 otwartych problemów); Client.prototype.removeFile() — usuń plik
  • Client.prototype.createRequestedFileLink() — utwórz opóźniony link

Eksport plików na inny serwer

Aby przenieść pliki na inny węzeł, można:

  • Po prostu skopiować cały folder magazynu wraz z ustawieniami. (w przyszłości może to nie działać)
  • Skopiować tylko folder z plikami. Ale w takim przypadku będzie trzeba jeden raz uruchomić funkcję node.normalizeFilesInfo(), aby przeliczyć wszystkie dane i wprowadzić je do bazy.
  • Użyć funkcji node.exportFiles(), która rozpocznie kopiowanie plików.

Podstawowe ustawienia węzła
Uruchamiając węzeł magazynu, można określić wszystkie potrzebne ustawienia.
Opiszę najważniejsze, resztę można znaleźć na GitHubie.

  • storage.dataSize — rozmiar folderu z plikami
  • storage.tempSize — rozmiar folderu tymczasowego
  • storage.autoCleanSize — minimalny rozmiar magazynu, który należy utrzymać. Jeśli ustalisz ten parametr, to gdy miejsca zacznie brakować, najmniej używane pliki będą usuwane.
  • file.maxSize — maksymalny rozmiar pliku
  • file.minSize — minimalny rozmiar pliku
  • file.preferredDuplicates — preferowana liczba duplikatów pliku w sieci
  • file.mimeWhitelist — dozwolone typy plików
  • file.mimeBlacklist — niedozwolone typy plików
  • file.extWhitelist — dozwolone rozszerzenia plików
  • file.extBlacklist — niedozwolone rozszerzenia plików
  • file.linkCache — różne ustawienia pamięci podręcznej linków

Prawie wszystkie parametry związane z rozmiarami mogą być podawane zarówno w wartościach bezwzględnych, jak i względnych.

Praca przez wiersz poleceń
Bibliotekę można używać przez wiersz poleceń. W tym celu należy zainstalować ją globalnie: npm i -g storacle. Po tym można uruchamiać potrzebne akcje z katalogu z projektem, w którym jest węzeł. Na przykład, storacle -a storeFile -f ./file.txt -c ./config.js, aby dodać plik. Wszystkie akcje można znaleźć w https://github.com/ortexx/storacle/blob/master/bin/actions.js

Po co to może być potrzebne

  • Jeśli chcesz stworzyć jakiś zdecentralizowany projekt, w którym planuje się przechowywać i pracować z plikami w wygodny sposób. Na przykład, projekt z muzyką, opisany w linku na początku artykułu, wykorzystuje storacle.
  • Jeśli pracujesz nad innymi projektami, gdzie potrzebne jest przechowywanie plików w sposób rozproszony, możesz łatwo zbudować swoją zamkniętą sieć, elastycznie konfigurować węzły i dodawać nowe, gdy zajdzie taka potrzeba.
  • Jeśli po prostu potrzebujesz miejsca do przechowywania plików swojej strony i nie chce ci się nic pisać samodzielnie, być może ta biblioteka będzie lepsza niż inne w twoim przypadku.
  • Jeśli masz projekt, w którym pracujesz z plikami, ale chcesz wykonywać wszystkie operacje z poziomu przeglądarki, możesz uniknąć pisania kodu serwerowego.

Moje kontakty:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster