Эфектыўнае захоўванне сотняў мільёнаў маленькіх файлаў. 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 (яшчэ не вырашана патрэбен ён ці не).

Хто пакапаецца ў зыходным кодзе, выявіць там ірыску, яе не ўсё кахаюць, але я не прывязваў асноўны код да функцый вэб фрэймворка, акрамя апрацоўшчыка перапыненняў, так што ў наступным магу перапісаць хутка амаль на любы рухавічок.

Рабіць:

  • Распрацоўка ўласнага рэплікатара і дыстрыбутара + гео для магчымасці выкарыстання ў вялікіх сістэмах без кластарных ФС (Усё па даросламу)
  • Магчымасць поўнага рэверсіўнага аднаўлення метададзеных пры іх поўнай страце(у выпадку выкарыстання дыстрыбутара)
  • Натыўны пратакол для магчымасці выкарыстання пастаянных сеткавых злучэнняў і драйверы да розных моў праграмавання
  • Пашыраныя магчымасці выкарыстання NoSQL складніку
  • Кампрэсіі розных тыпаў (gzip, zstd, snappy) для файлаў ці значэнняў усярэдзіне Bolt архіваў і для звычайных файлаў
  • Шыфраванне розных тыпаў для файлаў ці значэнняў усярэдзіне Bolt архіваў і для звычайных файлаў
  • Адкладзеная серверная відэа канвертацыя, у тым ліку і на GPU

У мяне ўсё, спадзяюся гэты сервер каму-небудзь спатрэбіцца, ліцэнзія BSD-3, капірайт падвойны, бо не было б кампаніі дзе я працую, не напісаў бы і сервер. Распрацоўнік я ў адзіным ліку. Буду ўдзячны за знойдзеныя багі і фіч рэквесты.

Крыніца: habr.com

Дадаць каментар