Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение

Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение

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

Затова за тази цел написах собствен специализиран сървър.
По време на реализацията на задачата успях да реша основния проблем, като в същото време постигнах икономия на дисково пространство и оперативна памет, които безмилостно поглъщаше нашата кластерна файловата система. Такова количество файлове е вредно за всяка кластерна файлова система.

Идеята е следната:

Простичко казано, чрез сървъра се качват малки файлове, те се съхраняват директно в архив и така също се четат от него, а големите файлове се поставят наблизо. Схемата е: 1 папка = 1 архив, следователно имаме няколко милиона архива с малки файлове, а не няколко стотин милиона файлове. И всичко това е реализирано напълно, без всякакви скриптове и разпиляване на файлове в tar/zip архива.

Ще се постарая да изложа покороче, предварително се извинявам ако постът стане дълъг.

Всичко започна с това, че не можах да намеря подходящ сървър в света, който да може да съхранява данни, получени чрез HTTP протокол директно в архиви, така че да не имат недостатъците, присъщи за обикновените архиви и обектни хранилища. Причината за търсенето стана разширилият се до големи мащаби Origin кластер от 10 сървъра, в който се натрупаха вече 250,000,000 малки файла, а тенденцията за растеж не се предвиждаше да спира.

На тези, които не обичат да четат статии и предпочитат да имат по-кратка документация:

тук и тук.

И docker заедно, в момента има вариант само заедно с nginx вътре за всеки случай:

docker run -d --restart=always -e host=localhost -e root=\/var\/storage -v \/var\/storage:\/var\/storage --name wzd -p 80:80 eltaline\/wzd

След това:

Ако файловете са много, са необходими значителни ресурси, и най-обидното е, че част от тях се губят напразно. Например, при използване на клъстерна файлова система (в разглеждания случай — MooseFS) файлът, независимо от фактическия си размер, заема винаги минимум 64 KB. Тоест за файлове с размер 3, 10 или 30 KB на диска се изискват по 64 KB. Ако файловете са четвърт милиард, губим от 2 до 10 терабайта. До безкрайност не можем да създаваме нови файлове, тъй като в същата MooseFS има ограничение: не повече от 1 милиард с една реплика на всеки файл.

С увеличаването на броя на файловете, е необходима голяма оперативна памет за метаданните. Също така, честите големи дампове на метаданни водят до износване на SSD-накопителите.

Сървър wZD. Подреждаме дисковете.

Сървърът е написан на езика Go. Първо, трябваше да намаля броя на файловете. Как да направя това? Чрез архивиране, но в този случай без компресия, тъй като моите файлове са само компресирани изображения. На помощ дойде BoltDB, от която се наложи да отстраня недостатъците, отразени в документацията.

Вместо четвърт милиард файлове, в моя случай останаха само 10 милиона архиви Bolt. Ако имам възможност да променя текущата структура на запълване на директориите с файлове, би било възможно да намаля около до 1 милион файлове.

Всички малки файлове се опаковат в архиви Bolt, автоматично получаващи имената на директорите, в които се намират, а всички големи файлове остават до архивите, няма смисъл да ги опаковаме, това е конфигурируемо. Малките — архивираме, големите — оставяме без промяна. Сървърът работи прозрачно и с едните, и с другите.

Архитектурата и особеностите на сървъра wZD.

Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение

Сървърът функционира под управлението на операционни системи Linux, BSD, Solaris и OSX. Тествах само за архитектура AMD64 под Linux, но той трябва да подхожда и за ARM64, PPC64, MIPS64.

Основни характеристики:

  • Многопоточност;
  • Мултисерверност, осигуряваща отказоустойчивост и балансиране на натоварването;
  • Максимална прозрачност за потребителя или разработчика;
  • Поддържани HTTP методи: GET, HEAD, PUT и DELETE;
  • Управление на поведението при четене и запис чрез клиентски заглавия;
  • Поддръжка на гъвкаво конфигурируеми виртуални хостове;
  • Поддръжка на CRC за целостта на данните при запис/четене;
  • Полудинамични буфери за минимално потребление на памет и оптимална настройка на мрежовата производителност;
  • Отложена компакция на данните;
  • В допълнение се предлага многопоточен архиватор wZA за миграция на файлове без спиране на услугата.

Реален опит:

Разработвал и тестирах сървър и архиватор на живи данни доста дълго време, сега той успешно функционира в клъстер, включващ 250,000,000 малки файла (снимки), разположени в 15,000,000 директории на отделни SATA-дискове. Клъстерът от 10 сървъра представлява Origin-сървър, инсталиран зад CDN-мрежата. За обслужването му се използват 2 сървъра Nginx + 2 сървъра wZD.

На тези, които решат да използват този сървър, има смисъл да планират структурата на директорите преди използването, ако това е приложимо. Веднага уточнявам, че сървърът не е предназначен да натъпка всичко в 1 Bolt архив.

Тестиране на производителността:

Колкото по-малък е размерът на архивирания файл, толкова по-бързо се изпълняват операциите GET и PUT с него. Сравняваме общото време за запис от HTTP клиента в обикновени файлове и в Bolt архиви, както и четене. Сравнява се работата с файлове с размер 32 KB, 256 KB, 1024 KB, 4096 KB и 32768 KB.

При работа с Bolt архиви се проверява целостта на данните на всеки файл (използва се CRC), преди запис и също след запис става четене на етап и преизчисляване, което естествено внася закъснения, но основното — безопасност на данните.

Тестовете за производителност провеждах на SSD-дискове, тъй като на SATA-дискове тестовете не показват ясна разлика.

Графики от резултатите от тестовете:

Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение
Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение

Както се вижда, за малките файлове разликата във времето за четене и запис между архивираните и не архивираните файлове е незначителна.

Съвсем различна картина получаваме при теста за четене и запис на файлове с размер 32 MB:

Ефективно съхранение на стотици милиони малки файлове. Self-Hosted решение

Разликата във времето между четенето на файловете е в рамките на 5-25 мс. С записването нещата стоят по-зле, разликата е около 150 мс. Но в този случай не е необходимо да се качват големи файлове, в това просто няма смисъл, те могат да съществуват отделно от архивите.

*Технически е възможно да се използва този сървър и за задачи, изискващи NoSQL.

Основни методи за работа с wZD сървъра:

Качване на обикновен файл:

curl -X PUT --data-binary @test.jpg http://localhost/test/test.jpg

Качване на файл в Bolt архив (ако не е надвишен параметърът на сървъра fmaxsize, определящ максималния размер на файла, който може да бъде включен в архива, ако е надвишен, файлът ще се качи нормално до архива):

curl -X PUT -H "Archive: 1" --data-binary @test.jpg http://localhost/test/test.jpg

Сваляне на файла (ако на диска и в архива има файлове с еднакви имена, по време на свалянето се отдава предимство на неархивирания файл):

curl -o test.jpg http://localhost/test/test.jpg

Сваляне на файл от Bolt архив (принудително):

curl -o test.jpg -H "FromArchive: 1" http://localhost/test/test.jpg

Описание на други методи има в документацията.

Документация wZD
Документация wZA

Сървърът засега поддържа само протокола HTTP, с HTTPS все още не работи. Също така не се поддържа метод POST (още не е решено дали е необходим или не).

Който се задълбочи в изходния код, ще открие там ириска, не всички я харесват, но не свързах основния код с функциите на уеб фреймворка, освен обработчика на прекъсвания, така че в бъдеще мога бързо да пренапиша почти на всеки движок.

ToDo:

  • Разработка на собствен репликатор и дистрибутор + гео за възможността да се използва в големи системи без клъстерни ФС (Всичко по възрастен начин)
  • Възможност за пълно обратно възстановяване на метаданни при тяхна пълна загуба (в случай на използване на дистрибутор)
  • Нативен протокол за възможността за използване на постоянни мрежови връзки и драйвери за различни програмни езици
  • Разширени възможности за използване на NoSQL компонент
  • Компресия на различни типове (gzip, zstd, snappy) за файлове или стойности вътре в Bolt архиви и за обикновени файлове
  • Шифроване на различни типове за файлове или стойности вътре в Bolt архиви и за обикновени файлове
  • Отложена сървърна видео конверсия, включително и на GPU

От мен е всичко, надявам се този сървър да е полезен на някого, лицензия BSD-3, авторските права са двойни, тъй като ако не беше компанията, в която работя, нямаше да пиша и сървъра. Разработчик съм в единствено число. Ще бъда благодарен за откритите бъгове и искания за нови функции.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster