
Привет, наскоро попаднах на интересна задача да настроя хранилище за архивиране на голямо количество блокови устройства.
Всяка седмица извършваме резервно копиране на всички виртуални машини в нашето облако, така че трябва да можем да управляваме хиляди резервни копия и да го правим максимално бързо и ефективно.
За съжаление, стандартните конфигурации RAID5, RAID6 в този случай не ни подхождат, тъй като процесът на възстановяване на толкова големи дискове, каквито са нашите, ще бъде мъчително дълъг и вероятно никога няма да завърши.
Нека разгледаме какви алтернативи съществуват:
— Аналог на RAID5, RAID6, но с настраиваемо ниво на паритет. При това резервирането се извършва не на блокове, а за всеки обект поотделно. Най-простият начин да опитате erasure coding е да разположите .
— това е в момента все още неиздадена възможност на ZFS. За разлика от RAIDZ, DRAID има разпределен паритетен блок и при възстановяване участва веднага всичките дискове в масива, благодарение на което по-добре понася откази на дисковете и по-бързо се възстановява след срив.


Разполагаме със сървър Fujitsu Primergy RX300 S7 с процесор Intel Xeon CPU E5-2650L 0 @ 1.80GHz, девет плочки оперативна памет Samsung DDR3-1333 8Gb PC3L-10600R ECC Registered (M393B1K70DH0-YH9), дискова кутия Supermicro SuperChassis 847E26-RJBOD1, свързана чрез Dual LSI SAS2X36 Expander и 45 диска Seagage ST6000NM0115-1YZ110 по 6TB всеки.
Преди да вземем решение, първо трябва да тестваме всичко правилно.
За целта се подготвих и проведох тестове на различни конфигурации. Използвах minio, който служеше като S3-бекенд и го стартирах в различни режими с различен брой цели.
Основно се тестваше случаят minio в erasure coding срещу софтуерен RAID с идентично количество дискове и паритетни дискове, а именно: RAID6, RAIDZ2 и DRAID2.
За справка: когато стартирате minio с единствена цел, minio работи в режим на S3-шлюз, предоставяйки вашата локална файлова система под формата на S3-хранилище. В случай, че стартирате minio, указвайки няколко цели, автоматично ще се включи режимът Erasure Coding, който ще разпределя данните между вашите цели, осигурявайки отказоустойчивост.
По подразбиране, minio разделя таргетите на групи по 16 диска, като на всяка група се падат по 2 паритета. Тоест, едновременно могат да излязат от строя два диска без загуба на данни.
За тестване на производителността използвах 16 диска по 6TB всеки и записвах върху тях малки обекти с размер 1MB, което максимално точно описваше нашето бъдещо натоварване, тъй като всички съвременни инструменти за резервно копиране разделят данните на блокове с размер няколко мегабайта и ги записват по този начин.
За провеждане на бенчмарк се използваше утилитата s3bench, стартирана на отдалечен сървър и изпращаща в minio десетки хиляди такива обекти в сто потока. След което по същия начин се опитваше да ги запита обратно.
Резултатите от бенчмарка са представени в следната таблица:

Както виждаме, minio в режим на собствен erasure coding работи значително по-зле при запис, отколкото minio, стартиран върху софтуерен RAID6, RAIDZ2 и DRAID2 в същата конфигурация.
Отделно мен да тествам minio на ext4 срещу XFS. Учудващо, но за моя тип натоварване XFS се оказа значително по-бавна от ext4.
В първата порция тестове Mdadm показа предимство над ZFS, но по-късно , че може да се подобри производителността на ZFS, като се инсталират следните опции:
xattr=sa atime=off recordsize=1Mи след това тестовете с ZFS станаха много по-добре.
Също така, може да се забележи, че DRAID не дава особено предимство в производителността пред RAIDZ, но теоретично трябва да бъде значително по-безопасен.
В последните два теста също се опитах да изнеса метаданните (special) и ZIL (log) на огледало от SSD. Но изнасянето на метаданните не даде особено предимство в скоростта на запис, а при изнасяне на ZIL моите се упънаха в таван със 100%_utilизация, така че считам, че този тест е провален. Не изключвам, че ако имах по-бързи SSD дискове, може да е подобрило значително моите резултати, но за съжаление нямаше такива.
В крайна сметка реших да се спра на използването на DRAID и въпреки своя бета статус, той е най-бързото и ефективно решение за съхранение в нашия случай.
Създадох прост DRAID2 в конфигурация с три групи и две разпределени резервни дискове:
# zpool status data
pool: data
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
data ONLINE 0 0 0
draid2:3g:2s-0 ONLINE 0 0 0
sdy ONLINE 0 0 0
sdam ONLINE 0 0 0
sdf ONLINE 0 0 0
sdau ONLINE 0 0 0
sdab ONLINE 0 0 0
sdo ONLINE 0 0 0
sdw ONLINE 0 0 0
sdak ONLINE 0 0 0
sdd ONLINE 0 0 0
sdas ONLINE 0 0 0
sdm ONLINE 0 0 0
sdu ONLINE 0 0 0
sdai ONLINE 0 0 0
sdaq ONLINE 0 0 0
sdk ONLINE 0 0 0
sds ONLINE 0 0 0
sdag ONLINE 0 0 0
sdi ONLINE 0 0 0
sdq ONLINE 0 0 0
sdae ONLINE 0 0 0
sdz ONLINE 0 0 0
sdan ONLINE 0 0 0
sdg ONLINE 0 0 0
sdac ONLINE 0 0 0
sdx ONLINE 0 0 0
sdal ONLINE 0 0 0
sde ONLINE 0 0 0
sdat ONLINE 0 0 0
sdaa ONLINE 0 0 0
sdn ONLINE 0 0 0
sdv ONLINE 0 0 0
sdaj ONLINE 0 0 0
sdc ONLINE 0 0 0
sdar ONLINE 0 0 0
sdl ONLINE 0 0 0
sdt ONLINE 0 0 0
sdah ONLINE 0 0 0
sdap ONLINE 0 0 0
sdj ONLINE 0 0 0
sdr ONLINE 0 0 0
sdaf ONLINE 0 0 0
sdao ONLINE 0 0 0
sdh ONLINE 0 0 0
sdp ONLINE 0 0 0
sdad ONLINE 0 0 0
spares
s0-draid2:3g:2s-0 AVAIL
s1-draid2:3g:2s-0 AVAIL
errors: No known data errorsДобре, с хранилището се разбрахме, сега за това с какво ще резервираме. Тук искам веднага да разкажа за три решения, които успях да опитам, а именно:
— форк , специализирано решение за архивиране на блокови устройства, има тясна интеграция с Ceph. Може да взима разлики между снимките и да формира инкрементално архивиране от тях. Поддържа голямо количество бекендове за съхранение, сред които има както локални, така и S3. Изисква отделна база данни за съхранение на хеш-таблицата за дедупликация. От недостатъците: написан е на Python, има малко неотзивчивно CLI.
— форк , отдавна известно и доказано средство за архивиране, може да архивира данни и добре дедуплицира. Може да съхранява архиви както локално, така и на отдалечен сървър чрез scp. Може да архивира блокови устройства, ако бъде стартиран с флага --special, от недостатъците: при създаването на архив, репозиторият е напълно блокиран, затова е препоръчително да се създаде отделен репозиторий за всяка виртуална машина, но това не е проблем, защото те се създават много лесно.
— активно развиващ се проект, написан на Go, доста бърз и поддържа голямо количество бекендове за съхранение, сред които са както локално хранилище, така и scp, S3 и много други. Особено искам да спомена, че има специално създаден за restic, който позволява най-бързото експортиране на хранилището за използване отдалеч. От всички изброени, това ми хареса най-много. Може да архивира от stdin. Почти няма забележими недостатъци, но има няколко особености:
На първо място, опитах да го използвам в режим на общ репозитория за всички виртуални машини (като Benji) и работеше доста добре, но операциите по възстановяване отнемаха доста време, тъй като всеки път преди възстановяване restic се опитва да чете метаданните на всички архиви. Този проблем беше лесно решен, както при borg, чрез създаването на отделен репозиторий за всяка виртуална машина. Този подход се оказа много ефективен и за управлението на архивните копия. Отделените репозитории могат да имат отделна парола за достъп до данните, а също така можем да не се страхуваме, че глобалният репозиторий може така или иначе да се повреди. Създаването на нови репозитории също е толкова просто, колкото и в borg backup.
Във всеки случай дедупликацията се извършва само по отношение на предишната версия на резервното копие, а предишното резервно копие се определя по пътя за указаното резервно копие, така че ако правите резервни копия на различни обекти от stdin в общ хранилище, не забравяйте да посочите опцията
--stdin-filename, или да посочите опцията всеки път изрично--parent.
На второ място, възстановяването в stdout отнема значително повече време от възстановяването в файловата система поради своята паралелност. В бъдеще се планира да се добави по-тясна поддръжка на резервни копия за блокови устройства.
На трето място, в момента се препоръчва да използвате , тъй като версия 0.9.6 има бъг с бавно възстановяване на големи файлове.
За да тествам ефективността на резервното копие и скоростта на запис / възстановяване от резервното копие, създадох отделно хранилище и опитах да направя резервно копие на малък образ на виртуална машина (21 GB). Извърших две резервни копия без промяна на оригинала, използвайки всяко от изброените решения, за да проверя колко по-бързо / по-бавно се копират дедуплицираните данни.

Както можем да видим, Borg Backup има най-добър коефициент на ефективност за начален резервен копия, но губи по отношение на скоростта както на записването, така и на възстановяването.
Restic се оказа по-бърз от Benji Backup, но възстановява по-дълго в stdout, а за съжаление все още не може да записва директно в блоково устройство.
След като прецених всичките плюсове и минуси, реших да се спра на restic с rest-server като най-удобно и перспективно решение за резервно копие.
В това скринкаст можете да видите как 10-гигабитният канал е напълно използван при няколко simultanно стартирали операции на резервно копие. Струва си да се отбележи, че използването на дисковете не надминава 30%.
Полученото решение ми донесе повече от удовлетворение!
Източник: habr.com
