Преди да започна, трябва да си тръгна
В тази статия бих искал да разгледам слоя, който отговаря за съхраняването на файлове и как може да се използва от всеки.
В предишната статия „развъртях цевта“ малко ipfs, но това се случи точно в контекста на проблема, който решавах. Като цяло мисля, че този проект е готин. Просто предпочитам възможността да създавам различни мрежи за различни задачи. Това ви позволява да организирате по-добре структурата и да намалите натоварването на отделните възли и мрежата като цяло. Дори в рамките на един проект, ако е необходимо, можете да разделите мрежата на части според определени критерии, намалявайки общото натоварване.
Итак, storacle использует механизм
- Файловете могат да се добавят към хранилището чрез всеки възел.
- Файловете се записват изцяло, а не на блокове.
- Всеки файл има свой уникален хеш на съдържанието за по-нататъшна работа с него.
- Файловете могат да бъдат дублирани за по-голяма надеждност
- Броят на файловете на един възел е ограничен само от файловата система (има изключение, повече за това по-долу)
- Броят на файловете в мрежата е ограничен от възможностите за разпространение според броя на валидните възли в мрежата, които във втората версия ще могат да работят с безкраен брой възли (повече за това в друга статия)
Прост пример за това как обикновено работи това от програмата:
Сървър:
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 XNUMX XNUMX / sqrt(XNUMX)).
Имената на папките се формират от хеша на файла, така че да имате бърз достъп до него, ако знаете хеша.
Тази структура е избрана въз основа на голям брой различни изисквания за съхранение: поддръжка на слаби файлови системи, където не е желателно да има много файлове в една папка, бързо преминаване на всички папки, ако е необходимо и т.н. Някаква златна среда.
Кеширане
При добавяне на файлове, както и при получаването им, връзките към файловете се записват в кеша.
Благодарение на това много често няма нужда да прекосявате цялата мрежа в търсене на файл. Това ускорява получаването на връзки и намалява натоварването на мрежата. Кеширането се извършва и чрез 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(), которая начнет копирование файлов.
Основни настройки на възела
Запуская узел хранилища, можно указать все необходимые настройки.
Ще опиша най-основните, останалите могат да бъдат намерени в Github.
- storage.dataSize — размер на папката с файлове
- съхранение.tempSize — размер на временната папка
- storage.autoCleanSize — минималният размер за съхранение, който трябва да се съхранява. Ако посочите този параметър, веднага щом мястото започне да свършва, най-малко използваните файлове ще бъдат изтрити.
- file.maxSize — максимален размер на файла
- file.minSize — минимален размер на файла
- file.preferredDuplicates — предпочитан брой дублирани файлове в мрежата
- file.mimeWhitelist - валидни типове файлове
- file.mimeBlacklist - невалидни типове файлове
- file.extWhitelist — допустимые расширения файла
- file.extBlacklist - невалидни файлови разширения
- file.linkCache - различни настройки за кеширане на връзки
Почти всички параметри, свързани с размерите, могат да бъдат въведени както в абсолютни, така и в относителни стойности.
Работа чрез командния ред
Библиотеката може да се използва чрез командния ред. За да направите това, трябва да го инсталирате глобално: npm i -g хранилище. После этого можно запускать нужные экшены из директории с проектом, где узел. Например, storacle -a storeFile -f ./file.txt -c ./config.js, чтобы добавить файл. Все экшены можно найти в
Защо може да имате нужда от това?
- Ако искате да създадете някакъв вид децентрализиран проект, в който планирате да съхранявате и работите с файлове, като използвате удобни методи. Например музикалният проект, описан във връзката в началото на статията, използва хранилище.
- Ако работите върху други проекти, където трябва да съхранявате файлове по разпределен начин. Можете лесно да изградите вашата затворена мрежа, гъвкаво да конфигурирате възли и да добавяте нови, когато е необходимо.
- Ако просто трябва да съхранявате файловете на уебсайта си някъде и е твърде много за вас да напишете всичко сами. Може би тази библиотека е по-подходяща от другите във вашия случай.
- Ако имате проект, в който работите с файлове, но искате да извършвате всички манипулации от браузъра. Можете да избегнете писането на сървърен код.
Моите контакти:
Източник: www.habr.com