Storacle - децентралізоване сховище файлів

Storacle - децентралізоване сховище файлів

Перш ніж почну, повинен залишити посилання на попередню статтющоб було зрозуміло про що саме мова.

У цій статті хотів би розібрати шар, який відповідає за зберігання файлів, і як це може бути використано будь-якою людиною. Storacle - самостійна бібліотека, ніякого зв'язку з музикою немає. Можна організувати зберігання будь-яких файлів.

У попередній статті я трохи "накотив бочку" на ipfs, але це сталося саме в контексті завдання, що мною вирішується. Загалом, я вважаю цей проект крутим. Просто мені більше подобається можливість створювати різні мережі під різні завдання. Це дозволяє краще організовувати структуру та знижувати навантаження на окремі вузли та мережу в цілому. Можна навіть у рамках одного якогось проекту, за потреби, дробити мережу на шматки за якимись критеріями, знижуючи загальне навантаження.

Отже, storacle використовує механізм що поширюється для організації мережі. Основні особливості:

  • Файли можуть додаватися до сховища через будь-який вузол.
  • Файли зберігаються повністю, не блоками.
  • Кожен файл має свій унікальний хеш за вмістом для подальшої роботи з ним.
  • Файли можуть дублюватися для більшої надійності
  • Кількість файлів на одному вузлі обмежена лише файловою системою (є виняток, про нього буде нижче)
  • Кількість файлів у мережі обмежена можливостями spreadable за кількістю допустимих вузлів у мережі, які у другій версії зможуть дозволяти працювати з нескінченним числом вузлів (про це в іншій статті)

Простий приклад, як це взагалі працює із програми:

Сервер:

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

Клієнт:

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

Погляд з середини

Під капотом нічого надприродного. Інформація про кількість файлів, сукупний їх розмір та інші моменти зберігаються в in-memory базі та оновлюються при видаленні та додаванні файлів, тому необхідності часто звертатися до файлової системи немає. Винятком є ​​включення збирача сміття, коли потрібна циркуляція файлів при досягненні якихось розмірів сховища, а не заборона додавання нових. В цьому випадку доводиться обходити сховище, і робота з великою кількістю файлів (> мільйона скажемо) може призводити до суттєвих навантажень. І краще зберігати менше файлів і запускати більше вузлів. Якщо "чистильник" вимкнено, то такої проблеми немає.

Сховище файлів є 256 папок і 2 рівня вкладеності. Файли зберігаються у папках другого рівня. Тобто за наявності 1млн. файлів у кожній такій папці буде близько 62500 1000000 штук (256 / sqrt(XNUMX)).

Назва папок формуються з хеш файлу, щоб можна було швидко отримати доступ, знаючи хеш.

Така структура була обрана виходячи з великої кількості різних вимог до сховища: підтримка слабких файлових систем, де в одній папці не бажано мати багато файлів, швидкий обхід усіх папок за потреби, і т.д. Якась золота середина.

Кешування

При додаванні файлів, а також при їх отриманні в кеш записуються посилання на файли.
Завдяки цьому дуже часто не потрібно обходити всю мережу в пошуках файлу. Це прискорює отримання посилань та зменшує навантаження на мережу. Також кешування відбувається через http заголовки.

Ізоморфність

Клієнт написаний на JavaScript та ізоморфний, його можна використовувати прямо з браузера. 
Можна завантажити файл https://github.com/ortexx/storacle/blob/master/dist/storacle.client.js як скрипт і отримати доступ до window.ClientStoracle або імпортувати через систему збирання і.т.п.

Відкладені посилання

Цікавою фічею також є "відкладене посилання". Це посилання на файл, який можна отримати синхронно, тут і зараз, а файл підтягнеться, коли вже буде знайдений у сховищі. Це дуже зручно, коли, наприклад, потрібно показати на сайті якісь картинки. Просто проставляємо в src відкладене посилання та все. Кейсів можна вигадати багато.

Api клієнта

  • асинхронний Client.prototype.storeFile() - Збереження файлу
  • асинхронний Client.prototype.getFileLink() - Отримання прямого посилання на файл
  • асинхронний Client.prototype.getFileLinks() — отримання списку прямих посилань на файл із усіх вузлів, де він є
  • асинхронний Client.prototype.getFileToBuffer() - Отримати файл у буфер
  • асинхронний Client.prototype.getFileToPath() - Отримати файл у файлову систему
  • асинхронний Client.prototype.getFileToBlob() - Отримати файл в blob (для браузерної версії)
  • асинхронний Client.prototype.removeFile() - Видалити файл
  • Client.prototype.createRequestedFileLink() - Створити відкладене посилання

Експорт файлів на інший сервер

Для того, щоб перенести файли на інший вузол можна:

  • Просто скопіювати всю папку сховища разом із налаштуваннями. (У майбутньому це може не працювати)
  • Копіювати лише папку з файлами. Але в цьому випадку потрібно буде один раз запустити функцію node.normalizeFilesInfo(), щоб перерахувати всі дані та занести до бази.
  • Використати функцію node.exportFiles()яка почне копіювання файлів.

Основні налаштування вузла
Запускаючи вузол сховища, можна вказати всі необхідні налаштування.
Опишу основні, решту можна знайти на гітхабі.

  • storage.dataSize - Розмір папки з файлами
  • storage.tempSize - Розмір тимчасової папки
  • storage.autoCleanSize - Мінімальний розмір сховища, який потрібно утримувати. Якщо вказати цей параметр, то як тільки місця почне бракувати найменш використовувані файли будуть видалятися.
  • file.maxSize - максимальний розмір файлу
  • file.minSize - Мінімальний розмір файлу
  • file.preferredDuplicates - Переважна кількість дублікатів файлу в мережі
  • file.mimeWhitelist - допустимі типи файлу
  • file.mimeBlacklist - Неприпустимі типи файлу
  • file.extWhitelist - Допустимі розширення файлу
  • file.extBlacklist - Неприпустимі розширення файлу
  • file.linkCache - Різні налаштування кешування посилань

Майже всі параметри, пов'язані з розмірами, можуть проставлятися і в абсолютних і відносних величинах.

Робота через командний рядок
Бібліотеку можна використовувати за допомогою командного рядка. Для цього потрібно встановити її глобально: npm i -g storacle. Після цього можна запускати потрібні екшени з директорії із проектом, де вузол. Наприклад, storacle -a storeFile -f ./file.txt -c ./config.js, щоб додати файл. Всі екшени можна знайти в https://github.com/ortexx/storacle/blob/master/bin/actions.js

Навіщо тобі це може бути потрібно

  • Якщо ти хочеш створити якийсь децентралізований проект, у якому планується зберігати та працювати з файлами зручними методами. Наприклад, проект із музикою, описаний за посиланням на початку статті, використовує storacle.
  • Якщо ти працюєш над іншими проектами, де потрібно зберігати файли розподілено. Ти можеш легко побудувати свою закриту мережу, гнучко налаштовувати вузли та додавати нові, коли це потрібно.
  • Якщо тобі просто потрібно десь зберігати файли свого сайту і тобі влом писати все самому. Можливо ця бібліотека підійде краще за інших, у твоєму випадку.
  • Якщо у тебе проект, у якому ти працюєш із файлами, але хочеш усі маніпуляції робити з браузера. Ти можеш уникнути написання серверного коду.

Мої контакти:

Джерело: habr.com

Додати коментар або відгук