Системы хранения данных: как выбирать?!

    imageПроект любой сложности, как ни крути, сталкивается с задачей хранения данных. Таким хранилищем могут быть разные системы: Block storage, File storage, Object storage и Key-value storage. В любом вменяемом проекте перед покупкой того или иного storage-решения проводятся тесты для проверки определённых параметров в определённых условиях. Вспомнив, сколько хороших, сделанных правильно растущими руками проектов прокололись на том, что забыли про масштабируемость, мы решили разобраться:

    • Какие характеристики Block storage и File storage нужно учитывать, если хотите, чтобы при росте проекта система хранения выросла вслед за ним
    • Почему отказоустойчивость на software уровне надежнее и дешевле, чем на hardware уровне
    • Как правильно проводить тестирование, чтобы сравнивать «яблоки с яблоками»
    • Как получить на порядок больше/меньше IOPS, поменяв всего один параметр

    В процессе тестирования мы применяли RAID–системы и распределенную систему хранения данных Parallels Cloud Storage (PStorage). PStorage входит в продукт Parallels Cloud Server.


    Начнем с того, что определим основные характеристики, на которые нужно обратить внимание при выборе системы хранения. Они же будут определять структуру поста.
    1. Отказоустойчивость
    2. Скорость восстановления данных
    3. Производительность, соответствующая вашим запросам.
    4. Консистентность данных


    Отказоустойчивость


    Самая важное свойство системы хранения данных – это то, что система призвана СОХРАНЯТЬ данные без каких-либо компромиссов, то есть обеспечивать максимальную доступность и ни в коем случае не потерять даже малой их части. Почему-то очень многие задумываются о производительности, цене, но мало внимания уделяют надежности хранения данных.

    Для обеспечения отказоустойчивости в случае сбоя существует одна-единственная техника – резервирование. Вопрос в том, на каком уровне применяется резервирование. С некоторым грубым упрощением, можно сказать, что уровня два: Hardware и Software.

    imageРезервирование на уровне Hardware давно зарекомендовало себя в Enterprise-системах. SAN/NAS коробки имеют двойное резервирование всех модулей (два, а то и три блока питания, пара плат «мозгов») и сохраняют данные одновременно на нескольких дисках внутри одной коробки. Лично я метафорически представляю это себе как очень безопасную кружку: максимально надежную для сохранения жидкости внутри, с толстыми стенками и обязательно с двумя ручками на случай, если одна из них сломается.

    imageРезервирование на уровне Software только начинает проникать в Enterprise-системы, но с каждым годом отъедает все больший и больший кусок у HW решений. Принцип тут прост. Такие системы не полагаются на надежность железа. Они считают, что оно априори ненадежно, и решают задачи резервирования на уровне ПО, создавая копии (реплики) данных и храня их на физически разном железе. Продолжая аналогию с чашками, это — когда есть несколько совершенно обычных чашек, и ты разлил чай в обе, вдруг одна разобьется.

    Таким образом, SW решения не требуют дорогостоящего оборудования, как правило, более выгодны, но при этом обеспечивают ровно такую же отказоустойчивость, хотя и на другом уровне. Их также легче оптимизировать, например, разносить данные на разные сайты, выполнять балансировку, менять уровень отказоустойчивости, линейно масштабировать при росте кластера.

    Расскажу, как решается вопрос резервирования на примере Parallels Cloud Storage (PStorage). PStorage не имеет привязки к какому-либо вендору железа и способен работать на совершенно обычных машинах, вплоть до настольных PC. Мы не доверяем железу, поэтому архитектура PStorage рассчитана на потерю любого физического сервера целиком (а не только отдельного диска). Все данные в Parallels Cloud Storage хранятся в нескольких копиях (репликах). При этом PStorage никогда не хранит более одной копии на физическом сервере/стойке/комнате (как захотите). Мы рекомендуем хранить 3 копии данных, чтобы быть защищенным от одновременного сбоя сразу двух серверов/стоек.

    image
    Комментарий: на рисунке показан пример кластера, хранящего данные в двух копиях.
    image



    Скорость восстановления данных


    Что происходит, если один из дисков выходит из строя?

    Для начала рассмотрим обычный HW RAID1 (mirror) из двух дисков. В случае выпадения одного диска, RAID продолжает работать с оставшимся, ожидая момента замены сломавшегося диска. Т.е. в это время RAID уязвим: оставшийся диск хранит единственную копию данных. У одного из наших клиентов был случай, когда в их дата-центре проводили ремонт и пилили металл. Стружки летели прямо на работающие сервера, и в течение нескольких часов диски в них стали вылетать один за другим. Тогда система была организована на обычных RAID, и в результате провайдер потерял часть данных.

    Сколько времени система находится в уязвимом состоянии — зависит от времени восстановления. Эту зависимость описывает следующая формула:
    MTTDL ~= 1 / T^2 * С, где T – это время восстановления, а the mean time to data loss (MTTDL) — среднее время наработки до потери данных, С — некий коэффициент.
    Итак, чем быстрее система восстановит необходимое количество копий данных, тем меньше вероятность потерять данные. Здесь мы даже опустим тот факт, что для начала процесса восстановления HW RAID администратору нужно заменить дохлый диск на новый, а на это тоже нужно время, особенно если диск нужно заказывать.

    Для RAID1 время восстановления – это время, за которое RAID контроллер перельет данные с рабочего диска на новый. Как легко догадаться, скорость копирования будет равна скорости чтения/записи HDD, то есть примерно 100 MB/s, если RAID контроллер совершенно не нагружен. А если в это время RAID котроллер грузят извне, то скорость будет в несколько раз ниже. Вдумчивый читатель проведет аналогичные расчёты для RAID10, RAID5, RAID6 и придет к выводу, что любой HW RAID восстанавливается со скоростью не выше скорости одного диска.

    SAN/NAS системы почти всегда используют аналогичный обычному RAID подход. Они группируют диски и собирают из них RAID. Собственно, скорость восстановления такая же.

    На Software уровне гораздо больше возможностей для оптимизации. Например, в PStorage данные распределяются по всему кластеру и по всем дискам кластера, и в случае выхода из строя одного из дисков репликация начинается автоматически. Здесь не нужно ждать, когда администратор заменит диск. Кроме того, в репликации участвуют все диски кластера, поэтому скорость восстановления данных намного выше. Мы записывали данные в кластер, отключали один сервер из кластера и замеряли время, за которое кластер восстановит недостающее количество реплик. На графике результат для кластера из 7/14/21 физической ноды с двумя SATA дисками по 1TB. Кластер собран на 1GB сети.

    image

    Если использовать 10Gbit сеть, то скорость будет еще выше.

    image

    Комментарий: Здесь нет ошибки в том, что на 1Gbit сети скорость восстановления кластера из 21 сервера — почти гигабайт в секунду. Дело в том, что данные, сохранённые в Parallels Cloud Storage, распределены по дискам кластера (некий stripe в масштабе кластера), таким образом, мы получаем возможность параллельно производить копирование данных с разных дисков на разные. То есть нет единой точки владения данными, которая могла бы быть узким местом теста.

    Полный сценарий теста можно найти в этом документе, при желании вы сможете его повторить самостоятельно.



    Как правильно тестировать производительность — советы


    Основываясь на нашем опыте тестирования систем хранения данных, я бы выделил основные правила:
    1. Надо «определиться с хотелками». Что именно хочется получить от системы и сколько. Наши клиенты в большинстве случаев используют Parallels Cloud Storage для построения кластера высокой доступности для виртуальных машин и контейнеров. То есть каждая из машин кластера одновременно предоставляет и storage, и исполняет виртуальные машины. Таким образом, в кластере не требуется выделенной внешней «хранилки данных». В терминах производительности это значит, что кластер получает нагрузку от каждого сервера. Поэтому в примере мы будем всегда нагружать кластер параллельно со всех физических серверов кластера.
    2. Не нужно использование хорошо сжимаемые шаблоны данных. Многие HDDs/SSDs диски, системы хранения данных, а также виртуальные машины иногда имеют специальные Low-level оптимизации для обработки нулевых-данных. В таких ситуациях легко заметить, что запись нулей на диск происходит несколько быстрее, чем запись случайных данных. Типичным примером такой ошибки служит всем известный тест:
      dd if=/dev/zero of=/dev/sda size=1M
      
      Лучше использовать случайные данные при тестировании. При этом генерация этих данных не должна влиять на сам тест. Т.е. лучше сгенерировать случайные данные заранее, например в файл. В противном случае тест упрется в генерацию данных, как в следующем примере:
      dd if=/dev/random of=/dev/sda size=1M
      
    3. Учитывайте расстояние между компонентами, разнесенными друг от друга. Естественно, что коммуникация между распределёнными компонентами может содержать задержки. Стоит помнить об этом возможном узком месте при нагрузках. Особенно сетевых задержках и пропускной способности сети.
    4. Отведите не меньше минуты на проведение теста. Время теста должно быть продолжительным.
    5. Проводите один тест несколько раз, чтобы сгладить отклонения.
    6. Используйте большой объем данных для нагрузки (working set). Working set – это очень важный параметр, так как он сильно влияет на производительность. Именно он может изменить результат тестирования в десятки раз. Например, с RAID контроллером Adaptec 71605, random I/O на 512M файле показывает 100K iops, а на 2GB файле — всего 3К IOPS. Разница в производительности в 30 раз обусловлена RAID-кешем (попаданием и не попаданием в кеш в зависимости от объема нагрузки). Если вы собираетесь работать с данными больше, чем объем кэша вашей системы хранения (в данном примере 512M), то используйте именно такие объемы. Для виртуальных машин мы используем 16GB.
    7. И конечно, всегда сравнивайте только «яблоки с яблоками». Необходимо сравнивать системы с одинаковой отказоустойчивостью на одинаковом железе. Например, нельзя сравнивать RAID0 c PStorage, так как PStorage обеспечивает отказоустойчивость при вылете дисков/серверов, а RAID0 нет. Правильно в этом случае будет сравнивать RAID1/6/10 c PStorage.

    Ниже приведу результаты тестирования по описанной методологии. Мы сравниваем производительность локального RAID1 («host RAID 1») с кластером PStorage («PCS»). Те самые «яблоки с яблоками». Следует обратить внимание, что необходимо сравнивать системы с одинаковым уровнем избыточности. PStorage в этих тестах хранил информацию в двух копиях (replicas=2) вместо рекомендованных трех, чтобы уровень отказоустойчивости быть одинаковый для обоих систем. Иначе сравнение было бы нечестным: PStorage (replicas=3) позволяет потерять 2 любых диска/сервера одновременно, когда RAID1 из 2 дисков — всего 1. Мы используем одинаковое железо для всех тестов: 1,10,21 одинаковых физических серверов с двумя 1TB SATA дисками, 1Gbit сетью, core i5 CPU, 16GB RAM. Если кластер состоит из 21 сервера, то его производительность сравнивается с суммарной производительностью 21 локального RAID. Нагрузка производилась в 16 потоков на каждой физической ноде одновременно. Каждая нода имела working set в 16GB, то есть, например, для RANDOM 4K теста в целом на кластере нагрузчики случайно ходили по 336GB данным. Время нагрузки — 1 минута, каждый тест проводился 3 раза.

    Колонки «PCS+SSD» показывают производительность того же кластера, но с SSD-кешированием. PStorage имеет встроенную возможность использовать локальные SSD для write-журналирования, read-кеширования, что позволяет в несколько раз превзойти производительность локальных вращающихся дисков. Также SSD диски могут быть использованы для создания отдельного слоя (tier) с большей производительностью.

    image


    Выводы


    Коротко резюмирую:
    1. Выбирая тип резервирования, склоняемся к «уровню ПО». Software уровень предоставляет больше возможностей для оптимизации и позволяет снизить требования к железу и удешевить систему в целом.
    2. Тесты проводим на определенных условиях (см. наши советы)
    3. Обращаем внимание на скорость восстановления – очень важный параметр, который при недостаточной эффективности может попросту погубить часть бизнеса.

    Также вы можете протестировать и наше собственное решение, тем более что мы даем это сделать бесплатно. По крайней мере, на наших собственных тестах Parallels Cloud Storage показывает наибольшую скорость восстановления данных в случае потери диска (больше, чем в RAID системах, включая SAN) и производительность как минимум не хуже локального RAID, а с SSD-кешированием – и выше.

    О консистентности данных мы планируем поговорить подробнее в отдельном посте.


    Как попробовать Parallels Cloud Storage


    Официальная страничка продукта тут. Чтобы бесплатно попробовать, заполните анкету.
    Также PStorage доступен для проекта OpenVZ.
    Почитать о том, как PCS работает в FastVPS можно в этом посте.
    Что показывают ваши тесты, плюсы-минусы – можем подробно обсудить в комментариях.
    Parallels
    139,50
    Мировой лидер на рынке межплатформенных решений
    Поделиться публикацией

    Комментарии 32

      +2
      Да, Parallels Cloud Storage — это рулез в быстром и надежном хранении данных :) Спасибо!
        0
        А есть ли в планах коммерческая лицензия без првиязки к PCS? Чтобы, например, к OpenVZ можно было прицепить или просто к машине смонтировать.
          +1
          Да. К OpenVZ можно и сейчас подцепить (ссылка в конце поста). К обычной Ubuntu, RHEL и CentOS можно будет с января 2015.
            0
            Можно, но там лимит на 100 гб. Это мало :(
              +1
              100ГБ — это лимит для PStorage без лицензии. Мы можем продать лицензию, чтобы этот лимит приодолеть.
                +2
                прЕодолеть. Простите конечно.
          0
          Было бы круто, если бы Вы еще про ploop написали, без него картина не получается полной — ведь это дам компонента одной системы :)
            +1
            Вам не кажется, что тестовый файл в 16 Gb на одну ноду слишком мал? Учитывая количество оперативной памяти даже в современных десктопах (8Gb ОЗУ уже норма, 16 тоже не редкость), не говоря уже про сервера. C такими маленькими тестовыми файлами на ноду в итоге вы тестируете производительность ОЗУ в каждой ноде кластера.

            Так же не понятен выбор времени теста в одну минуту. Я думаю гораздо интереснее как решение себя ведет под продолжительной интенсивной нагрузкой. Когда кэши насыщаются или просто уже не могут справляться с потоком данных и на сцену выходит она самая :) — производительность шпиндельных дисков.

            По поводу энтерпрайз СХД — там давно многие производители пришли к использованию именно софтовых Raid и дисковых пулов. Циклы разработки короче, чем для железячных контроллеров. Разработчиков найти/вырастить проще, баги править удобнее и опять же быстрее. Нет узкого места в виде железных контроллеров. Платформа x86 на данный момент победила, соответственно меняем железо на новое поколение и все. Софт можно использовать старый, а производительность уже выросла. Искусственные ограничения типа: «новая прошивка» не устанавливается на «старое» железо и т.п. сейчас не рассматриваем.

            Мне всегда интересно в подобных кластерных решениях в какой момент приложение или VM получает ack о том что запрошенная запись данных произведена. Когда нода получила блок данных в свой кэш? Тогда что будет если в этот момент нода «умрет»? Если ack идет приложению или VM когда блок данных скопирован на другие ноды, то мне кажется проблемой могут стать каналы в 1Gbit/s между нодами и время задержки в самой сети Ethernet между ними. Особенно если кластер физически подключается в общую сеть с потребителями (пользователями или VM).

            Единственное с чем полностью и безоговорочно согласен :), так это с тем что файл для теста забитый «мусорными» данными нужно генерировать заранее.
              +2
              Консистентность будет подробнее описана в следующем посте, так как это отдельная глубокая тема: как её достичь и сохранить производительность. Забегая вперед, скажу, что PStorage возвращает ack, когда записал все три копии на разные машины.
              Кстати, у нас даже специальный процесс тестирования для этого построен, когда пишем данные и зовём sync, затем вырубаем всю или часть системы, и проверяем, что данные действительно записались.

              16ГБ — это примерный объем данных, с которыми работают виртуальные машины на ноде.
              Я понимаю ваши опасения насчет OС-кешей, но эти кеши легко отключаемы почти в любой I/O тестилке. И по-моему, все уже меряют aio или directio. Кстати, в приведенных результатах OS writeback в принципе не мог работать ни на каком уровне, еще и потому, что в операциях записи после каждого write() зовелся fdatasync(). А sync в PStorage гарантирует, что данные реально записаны на дисках на разных машинах.

              Время теста должно быть продолжительным — сколько хотите. Просто в регулярном тестировании сложно ждать бесконечность (что было бы идеальным), чтобы промерять все сценарии.
                0
                Про недостижимые идеалы речи не идет. Тест от получаса до пары часов вполне информативен. Тестирование с отключением кэша или с direct io не интерестно, так как совсем уж далеко от жизни получается. Все равно кэши использоваться будут, поэтому и интерестны ситуации когда они используется, но не справляется со всей нагрузкой.

                По поводу 16Gb, у вас же соотношение не одна VM на одну ноду обычно? Значит и тестировать корректнее или несколько нагружаемых файлов по 16Gb на ноду, или один большой файл размером 16Gb*X VM.

                Ну и уж если совсем «придираться» :-) нагрузка блоками по 4K не совсем типична для VM. Даже транзакционные базы данных оперируют страницами по 8K. Другие приложения обычно более крупными блоками оперируют. Кроме того не плохо бы понимать соотношение операци чтения и операций записи в тестируемом профиле нагрузки.
                  0
                  16GB это средний working set на VM с ноды. Он разделен на 16 файлов по 1GB (1GB горячих данных на VM), чтобы каждый поток грузил свой файл. Один нагрузочный поток — VM.
                  4K — это минимальная дискретизация данных, она показывает IOPS системы. Тесты с большим блоком показывает пропускную способность.
                  8K тоже мереть можно, если для вашей системы актуально. Вообще стоит мереть именно актуальную нагрузку для конкретной системы. Идеально — вообще снять дамп IO запросов c рабочей системы и прогнать. :)
                  Обычно у VM гораздо больше записи чем чтения, больше случайного I/O чем последовательного. И обычно случайное I/O это запросы до 32K.
                    0
                    Еще раз. Может я плохо объясняю :-). Я имел в виду что нагрузку на каждую ноду дает обычно не одна VM, а несколько. VM работает не только с одним Gb горячих даных, которые в итоге и попадают в кэш. Имеет смысл все таки тестировать бОльшие объемы даных на одну ноду. По хорошему раза в 3-5 больше чем ОЗУ ноды.
                      0
                      Да, можно будет попробовать и такой сценарий. К сожалению, полного сета измерений для разного объема данных не могу сейчас привести. Мы выбирали 16GB из статистики и компромисса времени работа теста, чтобы успеть измерить все сценарии. Но еще раз подчеркну, что PStorage обеспечивает строгую консистентность данных, а значит в тесте write()+fdatasync() RAM кэш не влияет.
                      В следующий раз по-тестируем с большим объемом данных, почему бы и нет. :)

                      Кстати, о кэшах. Да, тест с полностью отключенными кэшами имеет смысл. Но, ведь в реальной жизни вы ими пользуетесь! Вопрос в том работают ли они для вашей именно задачи.
                        0
                        Я как раз подводил вас к мысли, что даже синтетические тесты по возможности лучше подводить ближе к реалиям жизни. В том числе и для того что бы не создавать неоправданных завышенных ожиданий у ваших клиентов :-). В этом ракурсе как раз отключение кэша на время тестирования смысла не имеет. В моей практике были ситуации когда включенный кэш (алгоритмы кэширования) приводили к снижению производительности устройства или решения :-).

                        Ну и никто не отменял утверждения, что тестирование синтетическими тестами -это тестирование «сферического коня в вакууме». Все зависит от конкретных сценариев нагрузки, настроек софта и оборудования. У того же линукса есть минимум 4 интегрированных io шедулера и дефолтный не всегда бывает оптимальным выбором :-). Ну и в любом случае тесты дают пищу к размышлениям, а иногда и в прямую влияют на выбор конкретным заказчиком конкретного решения/оборудования.
              +1
              Я правильно понимаю, Parallels Cloud Storage это аналог Distributed File System (вроде MooseFS, Ceph, Lustre, GlusterFS и т.д)?
                0
                Да.
                Только Parallels Cloud Storage архитектурно ориентирован на хранение больших файлов (>256MB), таких как образы виртуальных машин, базы данных, video, backup, log и прочее. Благодаря такой архитектуре он показывает отличную производительность. Максимальный объем одного кластера — до 8000 ТБ.

                Хочу отметить, что PStorage сейчас может хранить файлы вообще любого объема (как большие так и маленькие). Но если записать миллионы-миллирды мелких(!) файлов, то производительность будет уже совсем не такой. Мелкие файлы эффективнее хранить как объекты (Object Storage), а не как файлы. Это уже будущая фича PStorage. NAS сценарий для мелких файлов мы обязательно покроем в следующих релизах. Пока только NAS для больших файлов…

                Также PStorage гарантирует строгую консистентность данных, которая очень нужна для виртуализации и БД.
                  0
                  Есть уже какие-нибудь тесты и сравнения? Цифры все же интереснее описаний :-)
                    0
                    Могу еще одно сравнение пошарить. Это такие же тесты, на PStorage и CEPH на одинаковых нодах. Но только кластер маленький — всего 5 нод.
                    PStorage vs. CEPH
                      0
                      Спасибо, выглядит интересно
                        0
                        Конфигурация: сеть — 10Gbit (увидел ошибку в описании и решил описать подробно), 5 нод, на каждой Core i5, 16G Mem, 3 диска SATA 7200 RPM + один 100G SSD, который использовался для кеширования/журналирования (osd-journals, monitors, write-back) в CEPH и в PStorage.
                        OC одна — RHEL 7, в обоих случаях ;)
                          0
                          Про сеть лучше в статье исправить, в таком случае.
                            0
                            Минутку! В статье все правильно.
                            Я про картинку в комментах, там в правом нижнем углу красным подчеркнуто 1Gbit. Должно быть 10.
                          0
                          Не понимаю, почему и в посте и у ceph на этой картинке IOPS-ы при переходе от случайного чтения к случайной записи падают в разы (107k -> 19k, 204k -> 31k, 1.5k -> 0.6k), но только у PCS на этой картинке они растут (3k -> 5k). Это не ошибка? Тогда за счет чего такой прирост?
                            +1
                            Вы сравниваете не «яблоки с яблоками». :) В посте показана масштабируемость IOPS с ростом кластра. Сравнивается 16 поточная нагрузка на кластере из одной, 10 и 21 ноды. В комментах картинка показывает производительность с ростом нагрузки (1, 4 и 16 потоков) на кластере фиксированного размера.
                              0
                              Наверное, я несколько запутал… Посмотрите, пожалуйста, на графики в этом документе. Там они разделены на горизонтальную и вертикальную масштабируемость.
                                0
                                Наверное, вы меня не поняли. Я для простоты рассматиривал только нагрузку в 16 потоков (и все цифры привёл именно для неё). И именно для неё на этой картинке из комментария внезапно наблюдается сильный рост IOPS-ов.

                                В приведённом документе для 16-ти потоков также видно падение IOPS-ов в вертикальном тесте (9k -> 4k). И я не вижу там нигде роста IOPS-ов при переходе от чтения к записи (при сохранений количества нод кластера и числа потоков). Поэтому и говорю: не ошибка ли в картинке.
                                  0
                                  Проверил логи. Ошибки нет. Это — предмет для исследований. Спасибо, что заметили.
                                  В приведённом документе тесты были на PCS6 (Это Linux kernel 2.6.32) и версии PStorage 6.0.0-789, а в комментах RHEL7 (Это Linux kernel 3.10) и версии PStorage 6.0.7-32. Что-то могло в это время поменяться. Сейчас не могу сказать что именно привело к улучшению — нужно исследовать.
                                    0
                                    Улучшение на запись в полтора-два раза это прям чудо :-)
                                    Буду следить за новостями.
                    0
                    Как это будет работать в Linux?
                      0
                      PStorage монтируется через FUSE. Сейчас работает на PCS и OpenVZ, с января будет на CentOS 7, RHEL 7, Ubuntu 14+.
                        0
                        Сейчас набегут линуксоиды и скажут, что через FUSE все будет медленно работать…
                          0
                          :) Я думаю, что они посмотрят на картинку с графиками в комментах. Посмотрят и оценят у кого медленнее. :)
                          А если серьезно. Да, в FUSE есть проблемы, мы их справили. Parallels довольно много сделала патчей в mainstream чтобы сделать FUSE быстрым.

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое