Перш чым пачну, павінен пакінуць
У гэтым артыкуле хацеў бы разабраць пласт, які адказвае за захоўванне файлаў, і як гэта можа быць скарыстана любым чалавекам.
У папярэднім артыкуле я крыху "накаціў бочку" на 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 / sqrt(256)).
Назва тэчак фармуюцца з хэша файла, каб можна было хутка атрымаць доступ, ведаючы хэш.
Такая структура была абрана зыходзячы з вялікай колькасці розных патрабаванняў да сховішча: падтрымка слабых файлавых сістэм, дзе ў адной тэчцы не пажадана мець шмат файлаў, хуткі абыход усіх тэчак пры неабходнасці, і.т.д. Нейкая залатая сярэдзіна.
кэшаванне
Пры даданні файлаў, а таксама пры іх атрыманні, у кэш запісваюцца спасылкі на файлы.
Дзякуючы гэтаму вельмі часта няма неабходнасці абыходзіць усю сетку ў пошуках файла. Гэта паскарае атрыманне спасылак і памяншае нагрузку на сетку. Таксама кэшаванне адбываецца праз http загалоўкі.
Ізаморфнасць
Кліент напісаны на JavaScript і ізаморфны, яго можна выкарыстоўваць прама з браўзэра.
Можна загрузіць файл
Адкладзеныя спасылкі
Цікавай фічай таксама з'яўляецца "адкладзеная спасылка". Гэта спасылка на файл, якую можна атрымаць сінхронна, тут і зараз, а файл падцягнецца калі ўжо будзе знойдзены ў сховішчы. Гэта вельмі зручна, калі, напрыклад, трэба паказаць на сайце нейкія карцінкі. Проста прастаўляем у 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, каб дадаць файл. Усе экшэны можна знайсці ў
Навошта табе гэта можа быць патрэбна
- Калі ты жадаеш стварыць нейкі дэцэнтралізаваны праект, у якім плануецца захоўваць і працаваць з файламі зручнымі метадамі. Напрыклад, праект з музыкай, апісаны па спасылцы ў пачатку артыкула, выкарыстоўвае storacle.
- Калі ты працуеш над любымі іншымі праектамі, дзе трэба захоўваць файлы размеркавана. Ты можаш лёгка выбудаваць сваю зачыненую сетку, гнутка наладжваць вузлы і дадаваць новыя, калі гэта трэба.
- Калі табе проста трэба недзе захоўваць файлы свайго сайта і табе ўлом пісаць усё самому. Магчыма гэтая бібліятэка падыдзе лепш за іншых, у тваім выпадкі.
- Калі ў цябе праект, у якім ты працуеш з файламі, але жадаеш усё маніпуляцыі здзяйсняць з браўзэра. Ты можаш пазбегнуць напісання сервернага кода.
Мае кантакты:
Крыніца: habr.com