- PVSM.RU - https://www.pvsm.ru -
Доклад мой называется «Бинарные, они же файловые, хранилища», но, на самом деле, мы имеем дело со страшной сказкой. Проблема в том (и это тезис моего доклада), что сейчас не существует не то что хорошей, а хотя бы приемлемой системы хранения файлов.
Что такое файл? Файл – это кусок данных с именем. Что важно? Почему файл – это не строка в базе данных?
Файл слишком большой, чтоб можно было обращаться с ним как с одним куском. Почему? Есть у вас сервис, раз у нас HighLoad конференция, у вас сервис, который держит одновременно 100 тыс. соединений. Это не так уж много, если по каждому из соединений мы отдаем файл в 1 Мбайт размером, но нам нужно примерно 100 Гбайт памяти для буферов под эти файлы.
Мы не можем себе этого позволить. Обычно, во всяком случае. Соответственно, нам приходится делить эти куски данных на кусочки поменьше, которые именуются чанками. Довольно часто, а иногда блоками. И обращаться с блоками, а не с файлом целиком. Соответственно, у нас появляется еще один уровень адресации, и чуть позже станет понятно, почему это так сильно влияет на качество бинарных хранилищ.
Тем не менее, несмотря на то, что хороших бинарных хранилищ на свете нет, файловый обмен – это краеугольный камень современного массового обмена данными. Т.е. что угодно, что передается по сети Интернет, оформляется в виде файла – начиная от html страничек и заканчивая потоковым видео, потому что на той стороне мы имеем файл с потоковым видео и на этой стороне. На этой стороне часто – нет, но, тем не менее, это все равно файл.
Почему так? Почему мы основываем наш массовый обмен данными на файловом обмене? Потому что еще 10 лет назад каналы были медленными, еще 10 лет назад мы не могли себе позволить JSON интерфейсов, мы не могли все время запрашивать сервер, у нас слишком большая была latency, нам надо было все данные, которые требуются для показа пользователю, сначала закачать, а потом уже предоставлять пользователю возможность взаимодействовать с этими данными… Потому что иначе оно все так немножечко лагало.
Файловые хранилища. На самом деле термин «хранилища» крайне неудачный, потому что надо бы их называть «отдавалищами».
Еще 20-30 лет назад это были действительно хранилища – вы обрабатывали данные, вы их складывали на ленту, эту ленту сдавали в архив. Это и есть хранилища. Сегодня это никому не нужно. Сегодня, если у вас есть 450 млн. файлов, это значит, что они все должны быть в горячей доступности. Если у вас есть 20 Тбайт данных, это значит, что какой-нибудь 1 байт из этих 20-ти Тбайт, любой из них, обязательно потребуется в самое ближайшее время какому-нибудь из ваших пользователей. Если только вы не работаете в корпоративной среде, но если вы работаете в корпоративной среде, слово HighLoad к корпоративным средам редко применяют.
В бизнес требованиях никогда не написано «хранить файлы», даже когда написано… То, что называется системой резервного копирования – нет, это не система резервного копирования, это система аварийного восстановления, никому не нужно хранить файлы, всем нужно читать файлы – это важно.
Почему файлы все-таки приходится хранить? Потому что их надо отдавать, а для того, чтобы их можно было отдавать, они должны быть у вас. А, надо сказать, что это не всегда так, т.е. очень многие проекты, например, не хранят html странички, а генерят их налету, потому что хранение большого количества страничек представляет собой проблему, а генерение большого количества html страничек не представляет собой проблемы, это хорошо масштабируемая задача.
Файловые системы бывают старого типа и журналируемые. Что такое файловае система старого типа? Мы отписали на нее данные, она более-менее немедленно отправила эти данные на диск в нужное место.
Что такое журналируемая файловая система? Это файловая система, которая пишет данные на диск в два этапа: сначала мы пишем данные в специальную область диска, именуемую «журнал», а потом, когда у нас есть свободное время, или когда журнал заполнится, перекладываем из этого журнала данные туда, где они должны лежать на файловой системе. Это было придумано для того чтобы ускорить старт. Мы знаем, что у нас всегда файловая система консистентна, поэтому нам не надо проверять файловую систему, если у нас был неудачный аварийный рестарт, например, сервера, а надо проверить только небольшой журнал. Это будет важно.
Файловые системы бывали плоские и иерархические.
Все современные файловые системы поддерживают контроль доступа и расширенные атрибуты, кроме FAT. FAT, как ни странно, до сих пор используется и никакого контроля доступа и никаких расширенных атрибутов не поддерживает. Почему это я сюда написал? Потому что это очень важный для меня момент. Страшная сказка, связанная с файловыми системами, началась для меня в 1996 году, когда я внимательно изучил, как устроен контроль доступа в традиционном UNIX’e. Вы помните о маске прав? Хозяин, группа хозяина, все остальные. У меня возникла задача, мне нужно было создать группу, которая может читать и писать в файл, группу, которая может читать файл, и все остальные не должны были с этим файлом уметь делать ничего. И тут я понял, что традиционная маска прав у UNIX’a не поддерживает такой паттерн.
Еще чуть-чуть теории. POSIX – это фактический стандарт, его поддерживают сейчас все операционные системы, которыми мы пользуемся. В реальности – это просто список вызовов, которые файловая система должна поддерживать. Для нас во всем этом важно что? Open. Дело в том, что работа с файлом в POSIX происходит не по имени файла, а по некоторому файл-хэндлеру, который вы можете у файловой системы запросить по имени файла. После этого вы должны для всех операций пользоваться этим самым хэндлером. Операции могут быть простые типа read, write и операции seek, которая делает невозможным создание распределенной файловой системой стандарта POSIX.
Почему? Потому что seek – это случайное перемещение в случайную позицию файла, т.е. в реальности мы не знаем, что мы читаем, и мы не знаем, куда мы пишем. Для того чтобы понять, что мы делаем, нам требуется хэндлер, который нам вернула операция open, и нам требуется текущая позиция в файле – это та самая вторая адресация. То, что файловая система POSIX поддерживает случайную вторую адресацию, а не просто последовательную типа «открыли и давайте читать файлы от начала до конца», или например, «открыли и давайте писать его, и каждый новый записываемый блок добавляется в конец файла». То, что POSIX требует, чтоб это не было так, не позволяет (об этом позже) создать хорошую распределенную POSIX файловую систему.
Что еще существует на файловых системах POSIX. На самом деле, совсем не все POSIX поддерживают одинаковый набор атомарных операций, но в любом случае, некоторое количество операций должны быть атомарными. Атомарная операция – это операция, которая происходит или не происходит за один раз. Напоминает чем-то транзакции в базах данных, но на самом деле только напоминает. Например, на файловой системе ext4, с которой мы все должны быть знакомы, раз мы собрались на этой конференции, создание каталога является атомарной операцией.
Последнее про теорию. Разные вещи, которые на самом деле для функционирования файловой системы не нужны, но бывают иногда полезны.
На сегодняшний день снэпшоты поддерживаются на уровне блочных устройств в LVM, и там они поддерживаются омерзительно. Смотрите, мы создаем LVM снэпшот, и наше линейное чтение превращается в случайное, потому что мы должны почитать в снэпшоте, почитать на базовом блочном устройстве. С записью все еще хуже – мы должны почитать на базовом томе, мы должны отписать в снэпшоты, мы должны снова прочитать со снэпшота. В реальности снэпшоты на LVM бесполезны.
На ZFS есть хорошие снэпшоты, их там может быть много, их можно передавать по сети, если вы, например, сделали копию файловой системы, то вы можете передать снэпшот. В общем, снэпшот не обязательный для файлового хранилища функционал, но очень полезный, а чуть позже выясниться, что обязательный.
Самое последнее, но может быть самое важное во всей этой теории.
Кэширование чтения. Когда-то, когда инсталлятор NT4 запускался из под MS DOS, инсталляция NT4 без запущенного смартдрайва (это кэш чтения в MS DOS) занимала 6 часов, а с запущенным смартдрайвом – 40 минут. Почему? Потому что, если мы не кэшируем в памяти содержимое директорий, мы вынуждены всякий раз делать вот те самые 10 шагов.
Кэширование записи. На самом деле, еще до недавнего времени считалось, что это очень плохой тон, что единственный случай, когда вы можете включить кэширование записи на устройстве – это если у вас есть трейдконтроллер с батарейкой. Почему? Потому что эта батарейка позволяет сохранить в памяти данные, не попавшие на сервер, выключившийся в случайный момент. Когда сервер будет включен, можно дописать эти данные на диск.
Понятно, что операционная система ничего такого поддерживать не может, это надо делать на уровне контроллера. Сегодня актуальность этого хода резко упала, потому что сегодня мы можем использовать очень дешевую оперативную память, которая называется SSD диск. Сегодня кэширование записи на SSD диск – это один из самых простых и эффективных способов повысить производительность локальной файловой системы.
Это все было про файловые системы, локальные для вашего компьютера.
High Load – это сеть. Это сеть и в том смысле, что к вам приходят по сети ваши посетители, и это означает, что вам требуется горизонтальное масштабирование. Соответственно, сетевые протоколы доступа к файлам делятся на две группы: stateless – это NFS, WebDAV и еще некоторое количество протоколов.
Stateless – это значит, что каждая следующая операция самостоятельна в том смысле, что ее результат не зависит от результата предыдущей. С файловой системой POSIX стандарта это не так. У нас результаты read’a и write’a зависят от результатов seek’a, а он, в свою очередь, от результатов open’a. Тем не менее, поверх POSIX файловых систем существуют stateless протоколы передачи NFS, например, и это его главная проблема. Почему NFS такое дерьмо? Потому что он stateless поверх statefull.
Statefull. Сегодня все чаще используются statefull протоколы в сетевом обмене. Это очень плохо. Statefull протокол для интернета очень плохо подходит, потому что у нас непредсказуемые задержки, но, тем не менее, все чаще какой-нибудь JSON javascript’ный интерфейс все чаще помнит о том, чем закончилось предыдущее его общение с сервером, и заказывает очередной JSON, основываясь на том, чем закончилась предыдущая операция. Из сетевых файловых систем со statefull протоколом надо отметить CIFS она же samba.
Двуличная сука отказоустойчивость. Дело в том, что традиционные файловые системы упирают на целостность данных, потому что их создатели были заворожены словом «хранилище». Они думали, что самое важное в данных – это хранить их и защищать. Сегодня мы знаем, что это не так. Мы слушали на RootConf’е е доклад человека, который занимается защитой данных в датацентрах, он твердо нам сказал, что они отказываются не только от хардварных дисковых массивов, но и от софтварных дисковых массивов. Они используют каждый диск отдельно и какую-то систему, которая следит за расположением данных на этих дисках, за репликацией этих данных. Почему? Потому что, если у вас есть дисковый массив из, например, пяти 4-х Тбайтных дисков, то он содержит 20 Тбайт. Для того чтобы после случайного сбоя, например, один из дисков вылетел, его надо восстановить, в реальности надо прочесть все 16 Тбайт. 16 Тбайт читаются по Тбайту в час. Т.е. у нас вылетел всего один диск, но для того, чтобы снова запустить массив в работу нам требуется 16 часов – это неприемлемо в сегодняшней ситуации.
На сегодня отказоустойчивость бинарного хранилища – это, в первую очередь, бесперебойное чтение и, как ни странно, запись. Т.е. ваше хранилище не должно по первому чиху превращаться в тыкву, которая занята только сохранением спрятанных внутри данных. Если уж данные потерялись, бог с ними, они потерялись, главное, чтобы шоу продолжалось.
Что еще важно сказать про сетевые бинарные хранилища? Та самая CAP-теорема, т.е. выбираете любые два из этих трех:
CAP-теорема – это всего-навсего теорема, ее никто не доказал, но по факту это действительно так. Не удается. Попытки предпринимаются постоянно, например, OCFS2 (Oracle Cluster Filesystem версии 2), о которой я упомяну чуть позже, – это попытка доказать ничтожность CAP-теоремы.
Это все про файловые системы. Про бинарные хранилища, в чем проблема? Давайте разберемся.
Самый простой способ, который приходит в голову каждому системному администратору, которому надо хранить Тбайты данных и миллионы файлов – это просто купить большую СХД (система хранения данных).
Почему большая СХД – это не выход? Потому что если у вас большая СХД и один сервер, который с ней общается, или вы смогли разбить ваши данные на куски, и с вашими файлами общается с каждым куском один сервер, то у вас нет никаких проблем.
Если у вас горизонтальное масштабирование, если вы постоянно добавляете сервера, которые должны эти файлы отдавать или, не дай бог, сначала обрабатывать, только потом отдавать, вы столкнетесь с тем, что на большую СХД нельзя просто положить какую-то файловую систему.
Когда мне в первый раз попал в руки DRBD, я подумал: вот отлично, у меня будет два сервера, между ними будет репликация, основанная на DRBD, и у меня будут сервера, которые будут читать с одного, с другого. Очень быстро выяснилось, что все сервера кэшируют чтение – это значит, что если даже мы что-то втихаря поменяли на блочном устройстве, компьютер, который сам этого не менял и знал, какой кэш инвалидировать, ни за что об этом не узнает, и будет продолжать читать данные совсем не из тех мест, где они на самом деле уже лежат.
Для того чтобы преодолеть эту проблему, существуют разные файловые системы, которые обеспечивают инвалидацию кэша. Фактически они заняты этим на всех компьютерах, которые смонтировали в общее хранилище.
Еще с этим OCFS2 есть такая проблема – тормоза при конкурентной записи. Помните, мы говорили про атомарные операции – это операции, которые атомарны, которые одним куском происходят. В случае с распределенной файловой системой, даже если все наши данные лежат на одной единственной большой СХД, атомарная операция по набору читателей и писателей требует, чтобы они все пришли к консенсусу.
Консенсус в сети – это сетевые задержки, т.е. реально писать на OCFS2 – это боль. На самом деле, Oracle – не такой идиот, они сделали неплохую файловую систему, просто они сделали ее под совсем другую задачу. Они ее сделали под расшаривание одних и тех же файлов базы данных между несколькими своими Oracle серверами. У файлов базы данных Oracle такой паттерн работы, что они прекрасно на этой OCFS2 работают. Для файлового хранилища она оказалась непригодна, мы пробовали еще в 2008 году. Еще с OCFS2 оказалось неприятно, что из-за таймджитеринга, т.е. из-за того, что время немножко различается на всех виртуалках, какие у нас запущены даже на одном хосте, у нас нормально не работает OCFS2, т.е. в какой-то момент обязательно случается, что время на этом сервере обеспечения консистентности пошло назад, он на этом месте падает и т.д. И почему так медленно, я уже объяснил.
А еще большую-пребольшую СХД довольно сложно будет получить в собственное пользование, т.е. например, в Хеснере никакой большой СХД вам не дадут. Есть у меня такое подозрение, что идея, что большое СХД – это очень надежно, очень хорошо, очень высокопроизводительно, связана просто с правильным расчетом потребных ресурсов. Вы же не можете просто так купить большую СХД, их не продают в магазине. Вы должны пойти к авторизованному вендеру и поговорить с ним. Он покивает головой, скажет: «It will cost you». И посчитает вам тысяч на 50-100 одно шасси, т.е. еще его надо будет набить дисками, но он посчитает правильно. Загружено это СХД будет процентов на 5-10, а если окажется, что ваша нагрузка выросла, они посоветуют поставить вам еще одну такую. Это про жизнь.
Ладно, пусть. Большая СХД – это не выход, это мы выяснили потом и кровью.
Берем какую-нибудь кластерную файловую систему. Мы попробовали несколько: CEPH/Lustre/LeoFS.
Во-первых, почему так медленно? Понятно почему – потому что синхронные операции по всему кластеру. Что значит «ребалансинг»? На HDFS нет автоматического ребалансинга для уже лежащих на них данных. Почему ее там нет? Потому что в тот момент, когда на CEF’е случается ребалансинг, мы теряем возможность с ним работать. Ребалансинг – это хорошо отлаженная процедура, которая поедает примерно 100% полосы дискового обмена. Т.е. диск сатурейшн – 100%. Иногда ребалансинг, он же на каждый чих его делает, длится часов 10, т.е. первое, что делают люди, работающие с CEF’ом – это научаются прикручивать интенсивность ребалансинга.
В любом случае, на том самом кластере, который мы сейчас используем в том проекте, где у нас много файлов и много данных, мы вынуждены были выкрутить ребалансинг вверх, и там у нас действительно диск сатурейшн 100%. Диски выходят из строя при такой нагрузке очень быстро.
Почему ребалансинг такой? Почему он случается на каждый чих? Все эти «почему» у меня остались без ответа до сих пор.
И та самая проблема – атомарные операции, которые должны пройти по всему кластеру синхронно. До тех пор, пока у вас в кластере две машины, у вас все в порядке, когда у вас в кластере 40 машин, вы обнаруживаете, что все эти 40 машин… Мы имеем 402– количество сетевых пакетов, которые мы должны послать. Протоколы ребалансинга и протоколы обеспечения консистентности пытаются с этим бороться, но пока не очень успешно. Пока в этом смысле системы с единой точкой отказа с неймнодой немножко лидируют, но тоже не очень сильно.
Почему нельзя просто сложить все файлы в базу? С моей точки зрения, именно так и надо поступить, потому что если у нас лежат файлы в базе, у нас есть большой пакет хороших средств работы с такими вещами. Мы умеем работать с базами и в миллиард строк, и на петабайты, мы умеем работать с базами и на несколько миллиардов строк, на несколько десятков петабайт, это у нас все хорошо получается. Хотите, возьмите Oracle, хотите – возьмите какой-нибудь DB2, хотите – возьмите какой-нибудь NoSQL. Почему? Потому что файл – это файл. С файлом невозможно обращаться как с атомарной сущностью, поэтому распределенные файловые системы существуют плохо, а распределенные базы данных существуют нормально.
А еще крест на всяких ACFS, Lustre’ах и пр. ставит то, что нам требуется резервное копирование файлов. Как вы себе представляете резервное копирование 20 Тбайт? Напоминаю, Тбайт в час. И главное – куда, как часто, как обеспечить консистентность на таком количестве, если у нас не единая файловая система, и мы не можем снять снэпшот. Единственный выход, который я лично вижу из этой ситуации – это файловые системы с версионированием, когда вы пишете новый файл, и старый никуда не пропадает и можно до него добраться, указав время, на которое вы ходите посмотреть состояние файловой системы. Еще должна быть какая-то сборка мусора.
Microsoft обещал нам такую файловую систему еще в 90-ых, но так и выдал. Да, была распределенная файловая система для Windows, они ее даже анонсировали для Longhorn, но потом не случилось ни Longhorn’а, ни этой файловой системы.
Почему резервное копирование – это важно? Резервное копирование – это не отказоустойчивость – это защита от ошибок оператора. Мне самому случалось перепутать source и destination в команде rsync и получить (волшебная история!) сервер, на котором работает 16 виртуалок, но файлов с их образами нет, потому что я их удалил. Пришлось их вынимать с помощью команды DD из самих виртуалок. Тогда обошлось. Но, тем не менее, мы обязаны в наших бинарных хранилищах обеспечить версионирование, и никакой файловой системы, которая нормально бы обеспечивала версионирование, кроме ZFS, которая при этом не кластерная и, соответственно, нам не подходит, нет на свете.
Что же делать? Для начала, изучать собственную задачу.
Для некоторых сочетаний требований, для некоторых задач, решение есть прям вот существующее, а для некоторых сочетаний – нет, и его действительно нет. Если вы поискали и не нашли – это означает, что его нет.
Что же все-таки делать? Вот то, с чего следует начать:
Этот доклад — расшифровка одного из лучших выступлений на обучающей конференции разработчиков высоконагруженных систем HighLoad++ Junior [1]. Сейчас мы активно готовим взрослого братика — конференцию 2016 года — в этом году HighLoad++ пройдёт в Сколково, 7 и 8 ноября.
В этом году много интересного по теме хранилищ данных, вот самые спорные и зубодробительные доклады:
- Велосипед уже изобретен. Что умеют промышленные СХД? [2] / Антон Жбанков;
- Archival Disc на смену Blu-ray: построение архивного хранилища на оптических технологиях [3] / Александр Васильев, Герман Гаврилов;
- Архитектура хранения и отдачи фотографий в Badoo [4] / Артем Денисов.
Также некоторые из этих материалов используются нами в обучающем онлайн-курсе по разработке высоконагруженных систем HighLoad.Guide [5] — это цепочка специально подобранных писем, статей, материалов, видео. Уже сейчас в нашем учебнике более 30 уникальных материалов. Подключайтесь!
Кстати, завтра в нашем блоге продолжение — расшифровка ещё одного доклада Даниила Подольского «Опыт построения и эксплуатации большого файлового хранилища». Подписывайтесь [6], чего уж там :)
Автор:
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/sistemnoe-administrirovanie/201587
Ссылки в тексте:
[1] HighLoad++ Junior: http://junior.highload.ru/?utm_source=habr&utm_medium=media&utm_campaign=past.articles&utm_content=common
[2] Велосипед уже изобретен. Что умеют промышленные СХД?: http://www.highload.ru/2016/abstracts/2321.html
[3] Archival Disc на смену Blu-ray: построение архивного хранилища на оптических технологиях: http://www.highload.ru/2016/abstracts/2355.html
[4] Архитектура хранения и отдачи фотографий в Badoo: http://www.highload.ru/2016/abstracts/2280.html
[5] HighLoad.Guide: http://highload.guide/?utm_source=habr&utm_medium=media&utm_campaign=past.articles&utm_content=common
[6] Подписывайтесь: https://habrahabr.ru/company/oleg-bunin/profile/
[7] Источник: https://habrahabr.ru/post/313330/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.