Лирика
На горизонте новый buzzword: Software defined $thing. Мы уже имеем состоявшийся и сформировавшийся круг всего, относящегося к software defined networks (SDN), пришла очередь и storage (SDS). Видимо, дальше у нас будет software defined computing или ещё что-то подобное, потом резко всполошатся и подтянутся HP/VMWare и предложат (private) «software defined enterprise», который будет означать всё тоже, что было, но ещё моднее и актуальнее.
Впрочем, рассказ не про баззворды. За каждым таким странным названием (grid, elastic, cloud) стоит дальнейшее развитие технологий — построение дальнейших слоёв взаимодействия компонент (эм… взаимодействия участников взаимодействия, иначе не скажешь), основным мотивом которых является уход от гранулированности компьютерной системы, так, чтобы вся терминология, вся предметная область ушла от «межпроцессного взаимодействия» и стала автономной. В более-менее приличном виде мы это (в виде уже свершившегося факта) мы видим в
Это взаимодействие выглядит очень соблазнительным, так что его распространяют на все остальные области, по мере возможности.
Перед рассказом про SDS, посмотрим на уже состоявшееся: SDN (software defined network).
В SDN всё сетевое оборудование (реальное железо или виртуальные свичи на хостах виртуализации) используются в качестве тупых исполнителей, а вся интеллектуальная работа по построению реальной сети делегируется приложению, которое тем или иным методом «понимает» что нужно и изготавливает топологию сети по необходимости. Я опускаю все названия конкретных технологий (openflow, big switch, floodlight, Nicra), так как главное в SDN идея о формировании конфигурации сети с помощью софта, а не детали реализации.
Так вот, что же такое тогда Software Defined Storage (SDS)? По аналогии мы можем сказать, что это такая система хранения данных, в которой вся интеллектуальная работа по построению системы хранения данных делегируется программе, а железо и «локальный софт» (уровня хостов) работает в качестве тупых исполнителей.
Наверное, самым успешным и образцово-показательным решением тут выступает Openstack's Swift, который создаёт устойчивое и масштабируемое хранилище блобов с помощью тупых дисков и xfs на них, от которых ничего-ничего не требуется — только capacity и немножко performance. Всё остальное делает софт.
Но swift — это не совсем «storage», это «object storage». То есть хранилка для файликов. Без возможности писать в середину файла, и уж точно не обеспечивающая десятки тысяч IOPS'ов на запись с микросекундными задержками.
А общественность жаждет именно этого. Надёжно, дёшево, с произвольной и гарантированной избыточностью, fault tolerance, high availability, geo replication, auto ballanced, self healing, из коммодити железа (то есть ещё раз дёшево), высокопроизводительно, с неограниченным масштабированием производительности и емкости по мере роста числа нод, muti tentant, accountable (тут клиент не выдержал возбуждения и начал, упав на ковёр, сучить ножками). Всё это, да ещё и ложкой.
В реальности
Аналогия SDN-SDS обладает одним маленьким нюансом, который всё делает сложным. В SDN от сетевого оборудования (того, что тупое и просто слушается командного центра) требовалось одно — перекладывать байтики. В SDS от тупых устройств хранения требуется не только взять байтики и донести до/от клиента, но ещё и хранить их.
В этом месте кроется самая большая, сложная и неприятная проблема. Мы можем взять и выкинуть сдыхающий свитч. Мы можем это сделать даже программно. Никто ничего не заметит.
Но мы не можем просто так взять и выкинуть работающее «тупое» хранилище. До того, как другое хранилище сможет продолжать работу, кто-то должен пойти и скопировать к себе его данные.
Да-да, всё дело в хранении. Если бы у нас были write-only хоронилища для информации, то их реализация была бы тривиальной. Не можем писать сюда? Поднять ещё одну ноду, начать писать туда.
Но ведь нам со сдохшей ноды надо было бы ещё и прочитать, что было записано… А нода умерла. Ой?
Таким образом, модель SDS полностью совпадает с SDN с точки зрения процесса IO. А вот хранение — совсем новая, отдельная проблема. Которая называется CAP-теорема. И решения там не видно.
В чём же проблема? Если задача не может быть решена, значит надо менять условия задачи.
И вот тут вот начинается самое интересное — если верхи не могут, а низы не хотят — это же начало революции, правда? Смена задачи — это же смена модели, по которой идёт работа с блочными устройствами. Вся чехарда вокруг SDS — это же, в конце-концов, про файловую систему на блочном устройстве, на которую можно положить SQL-базу и работать с ней очень-очень быстро, надёжно, дешёво, консистентно (опять клиент зашёлся в счастливой истерике...).
Добрый TCP и злая файловая система
Если вам кто-то предоставит сеть, в которой будет теряться 1 из 10000 пакетов, вы будете считать, что у вас идеальная сеть. Все сетевые приложения без исключения готовы к потере пакетов, и проблемы начинают появляться, когда потери поднимаются к десяткам процентов.
Добрый-добый TCP прощает почти всё — повторы, потери, джиттеринг (резкое изменение latency), изменение пропускной полосы, порчу данных внутри пакета… Если становится совсем плохо, то и TCP начинает работать медленно и вяло. Но работать! Более того, даже если условия работы становятся невыносимыми даже для TCP (например, 70-80% потери пакетов), то большая часть сетевых приложений готова к ситуации обрыва сетевого соединения, и она просто переподключается заново, без далеко идущих последствий.
Сравним это с блочными устройствами. Что будет, если вам продадут дисковое устройство, которое теряет 1 из 1000000 запросов? Злая файловая система этого не простит. Что будет, если вы улучшите качество в 100 раз, и у вас будет ломаться 1 из 100000000 запросов? Файловая система это не простит. И не просто не простит, но отомстит самым ужасным образом. Если файловая система обнаружит, что 1 из триллиона запросов на запись не удался, то она откажется работать с таким позорным блочным устройством. В лучшем случае она перейдёт в режим read only, в худшем — просто перестанет работать.
А что произойдёт с программой, у которой файловая система выкинула такую вещь? Никто не знает. Может быть, она просто завершится. А может быть, начнёт плохо работать. Или зависнет. Если на этом блочном устройстве был файл подкачки, то некоторые операционные системы запаникуют. Особенно, если там были какие-то важные данные (например, кусочек файлового буфера на чтение у программы cat — и весь сервер со всеми своими тысячами клиентов идёт мигать тремя светодиодами на клавиатуре).
Что же сделает, например, база данных, если мы поменяем в результате ошибки один-единственный из миллиарда блоков? (один 4к-сектор на 4Тб диске). Во-первых, она этого не заметит. Во-вторых, если она заметит (ей что-то не понравится в прочитанном) — объявит базу данных неполноценной, подвергнет апартеиду, обрезанию, лишению гражданских прав и объявит basa non granta в системе.
Другими словами, от дискового стека ожидают бесконечной надёжности.
Весь блочный стек беспощаден к ошибкам. Вендоры просят десятки и сотни миллионов рублей за системы, которые почти никогда не делают ошибок. Но даже их системы делают ошибки. Реже, чем коммодити железо. Но кому от этого легче, если вам не прощают даже одной ошибки на квадриллион операций? (1 сбойный блок на 4 Еб записанного/прочитанного, 4к блоки).
Разумеется, решением на это будет повышение надёжности. Рейды, кластерные системы, мейнфреймы… Где-то мы это уже видели. Получается не дорого, а запредельно дорого. Если бы ноутбуки делали по технологиям мейнфреймов, то они бы ломались в тысячу раз реже, а стоили бы в миллион раз дороже.
Кто-то шепчет что-то про RAID'ы. Что ж, давайте разберём, что делают рейды. Рейд берёт несколько блочных устройств и собирает из них новое блочное устройство. С повышенной надёжностью (а быть может, и производительностью). При этом он предъявляет ровно такие же требования к качеству устройств снизу — ошибка — и диск объявляется плохим. Навсегда. Дальше там ребилд той или иной степени культурности.
Наиболее продвинутые проприентарные решения позволяют дискам иногда делать ошибки и бракуют их после превышения некоторого порога.
Но при этом, случись какая-то проблема, любая ошибка рейда (например, таймаут на IO) приведёт к такому же объявлению всего рейда «плохим». С такими же последствиями для приложений, использующих данные на файловой системе на этом рейде. Другими словами, от рейда требуется из нескольких ненадёжных устройств сделать… опять, бесконечную надёжность (нулевую вероятность отказа). Теорвер негодуэ.
… А добрый, всепрощающий TCP, взирает на заблудшие души с состраданием и любовью.
Что же делать?
Во-первых, надо признать, что не бывает идеальных вещей. Если DNA с миллиардолетней эволюцией не сумела защитить себя от ошибок, то надеяться на пару лет (десятилетий) инженерной мысли, мягко говоря, не разумно. Ошибки могут быть. И главное, что нужно научиться делать с этими ошибками — не устраивать истерики из-за мельчайшего несовершенства.
Нам вернули ошибку? Попытаться повторить, не удалось повторить — вернуть выше по стеку. Файловая система молча идёт и кладёт метаданные другое место, если не удалось записать в это (а не устраивает истерику размером во весь сервер). СУБД, получив ошибку записи (чтения) в/из журнал(а) не объявляет базу одержимой, и не проклинает до седьмого колена все приложения, с этой базой работающие, а просто достаёт резервную копию, нет резервной копии, аккуратно помечает данные как повреждённые, возвращает ошибку или пометку о повреждении. Приложение, работающее с базой данных, получив подобное, не делает глупостей, а спокойно работает с тем, что есть, стараясь минимизировать повреждения и честно говоря о размере повреждений тому, кто с этими данными работает. И каждый из уровней полностью проверяет правильность данных с нижележащего уровня, не полагаясь на слова «да, я сумел прочитать число пи из файла, его значение 0x0000000000000».
Да, у нас повредилась одна банковская транзакция по вашей карте. Да, мы не знаем точно, сколько у вас было списано денег. Но у нас есть промежуточные балансы, так что вы можете продолжать пользоваться картой, а повреждённые данные мы либо спишем за старостью лет, либо восстановим на следующей неделе. Это вместо «Неизвестная ошибка. Операция по карте невозможна, обратитесь в службу поддержки карт вашего банка».
Отъедание малого кусочка данных не должно приводить к порче большего куска данных. В древнееврейской мифологии описан один случай, когда из-за надкусанного яблока выбраковали целое человечество, разогнали весь рай, ободрали змее все ноги и, вообще, повели себя так, как ведёт себя современная файловая система при обнаружении надкусанного жёсткого диска. Насколько я знаю, это событие считается трагичной ошибкой. Не надо так больше делать. Надкусили яблоко — выкиньте яблоко, и не более.
Таким образом, главное изменение, которое должны принести за собой SDS — это изменение отношения к ошибкам блочных устройств. Так, чтобы 1% дисковых ошибок считался не очень хорошим, но терпимым показателем. А 0.01% — просто замечательным сервисом.
В этих условиях появится возможность делать сервисы без ожидания бесконечной надёжности — разумные ожидания за разумные деньги.
Блочные устройства будущего
И как тогда выглядит software defined storage будущего? Если мы позволяем себе иногда делать ошибки, то нашей задачей становится не их предотвращение, а уменьшение их числа.
Например, мы можем сильно распараллелить операции. Если за хранение данных отвечает 1000 узлов, то отказ одного или двух из них для нас всего лишь означает 0.1% или 0.2% ошибок чтения или записи. Нам не надо изгаляться с гарантированно синхронными репликациями. Ну да, «вылетела нода, выкинули из сервиса, добавили новую». В принципе, это не очень хорошая ситуация (т.к. если потом вылетит ещё парочка, то мы подползём аж к 0.4% потерь, что снизит качество хранения данных). Но мы можем поднять ноду из бэкапа. Да, там будут устаревшие на сутки данные, и мы для части данных будем нещадно врать (возвращать не то, что записали). Но ведь вышестоящий уровень готов к этому, правда? А за счёт того, что поменялось всего 2-3% от данных с ноды, то мы вместо 0.1% отказов в чтении (и почти 0% отказов в записи — ведь мы пишем на другие ноды) мы получим 0.002% ложных данных на чтении.
0.002% — это ведь 99.998% надёжность. Мечта? Если к такому готовы — да.
И получающаяся конструкция оказывается невероятно простой: свифтоподобная система хранения блоков, размазанных по куче серверов и куче дисков. Без особых требований к обязательной целостности данных — если мы иногда отдаём устаревшие данные, то это всего лишь «брехня при чтении», и если мы это делаем не слишком часто, то всех всё устраивает. Мы можем в любой момент времени «потерять» запрос клиента и быть уверенным, что он его, если надо, несколько раз пришлёт. Мы можем работать не в революционно-героическом режиме "СХД бы делать из этих людей: Надёжнее бы не было в мире СХД", а в комфортном режиме, когда прилежность и исполнительность в большую часть времени, вполне компенсирует редкие ошибки.
А где тут SDS?
Во всём предыдущем не было ни слова про SDS. Где тут 'software defined'?
В описанной выше схеме «ноды-исполнители» будут всего лишь выполнять то, что им командует ПО. ПО же в свою очередь будет формировать описание того, где и что читать и куда писать. В принципе, это всё уже есть. Кластерные файловые системы предыдущего поколения, CEPH, возможно, чуть-чуть переразвившаяся до сетевого уровня BTRFS, может быть, подоспевший elliptics — оно, практически, готово. Остаётся написать нормальную multi-tenancy, конвертацию из логической топологии клиентского представления в команды «тупому железу» (контроллер для SDN) — и всё готово.
Итог
Основной вывод: ключевой проблемой в развитии блочных устройств в настоящий момент являются чрезмерно завышенные (бесконечные) ожидания по надёжности и достоверности работы блочных устройств, а так же существующая дурная традиция раздувать ошибки блочных устройств, увеличивая размер домена повреждений до домена задачи (а иногда и за его пределы). Отказ от 100% надёжности всегда и везде позволит с куда меньшими усилиями (т.е. с меньшей стоимостью) обеспечить условия для создания (или даже применения существующих) решений для SDN.
Комментарии (96)
noonesshadow
09.01.2014 11:00В любом случае где-то там будет блочное устройство, разве нет?
amarao Автор
09.01.2014 11:00Если там будет блочное устройство в текущем понимании — это будет плохо.
Сами блочные устройства (на уровне /dev/sd*) чаще всего ведут себя адекватно. Не работает сектор — остальные продолжают работать. А вот если ошибка проскакивает выше — это становится фатальной проблемой для всей файловой системы, базы данных и т.д.
norguhtar
09.01.2014 11:00Про zfs и btrfs я так полагаю автор не слышал? :)
amarao Автор
09.01.2014 11:00У меня на btrfs (в режиме мирроринга силами btrfs) моя медиа-коллекция. Это как-то меняет описанную проблему? (Все ожидают бесконечной надёжности от файловой системы, да и файловые системы тоже хотят от блочных устройств бесконечности).
norguhtar
09.01.2014 11:00файловая система с контролем четности не ожидает бесконечной надежности от накопителя. Как и RAID массив не ожидает надежности от накопителя.
amarao Автор
09.01.2014 11:00Когда ожидаемое качество не выполнено для блока (чексумма не помогла, кусочек файла превратился в тыкву) что происходит дальше? Как ОС объясняет приложению, какая часть файла не годна к употреблению и как на это реагирует, например, расположенная на этой ФС база данных на сообщение о том, что кусочек системной таблицы больше не кусочек системной таблицы?
norguhtar
09.01.2014 11:00Как ОС объясняет приложению, какая часть файла не годна к употреблению и как на это реагирует, например, расположенная на этой ФС база данных на сообщение о том, что кусочек системной таблицы больше не кусочек системной таблицы?
В случае RAID идет восстановление с других живых дисков, после чего сбойный диск помечается как «оно сдохло» и идет алярма, что к нему возможно пришел пушной зверек. Файловая система же этого не видит. Я реально восстанавливал раз RAID6 с двумя сдохшими дисками и ничего.amarao Автор
09.01.2014 11:00А я видел сдохшие рейды без сдохших дисков. Софтовые рейды. Дедлоки, баги ядра и т.д. В очередной раз предполагается, что уж у рейда-то точно ошибок не будет и будет бесконечная надёжность.
Всё, о чём я говорю — лишь утверждение, что такого не бывает, и весь софт всех уровней должен делаться с рассчётом на более-менее регулярные не очень значительные мелкие отказы.norguhtar
09.01.2014 11:00А я видел сдохшие рейды без сдохших дисков. Софтовые рейды. Дедлоки, баги ядра и т.д. В очередной раз предполагается, что уж у рейда-то точно ошибок не будет и будет бесконечная надёжность.
Я тоже видел, но как правило их можно оживить с потерей информации. Но да то что работает по верх RAID считает что он надежен.
и весь софт всех уровней должен делаться с рассчётом на более-менее регулярные не очень значительные мелкие отказы.
Не получится. У вас возникнет проблема с железом вспоминаем про проблемы функционирования железа в открытом космосе.amarao Автор
09.01.2014 11:00Я и не говорю, что это пара sysctl'ов поправить.
Изменения должны начинаться где-то с СУБД, постепенно переползая в фрейморки/orm'ы. Когда какая-то часть софта сможет переживать малые глюки, а какая-то нет, тут же появится водораздельная линия «старый rigid софт» и «новый agile софт».
В ходе дискуссии я сумел для себя поймать пару важных мыслей. Мы, предполагая бесконечную надёжность блочного уровня (как с точки зрения безотказности на выполнение запроса, так и с точки зрения сохранности данных) просто отказываемся думать о том, что будет, если это обещание будет нарушено.
Sad path — это когда «ошибка, и мы знаем что делать».
happy (good) path — это когда ошибки нет и мы знаем, что делать.
bad path — это когда ошибка, и мы не знаем, что делать (или знаем, но неконструктивно, например, «паниковать и падать»).
Так вот, все приложения, полагающиеся на бесконечную надёжность нижележащего уровня просто игнорируют существование sad path, превращая его весь в bad path.
И это не даёт возможности пошевелиться дисковому уровню, потому что у него есть единственная ниша — «супернадёжный». Без компромиссов.
Кто знает, какими были бы диски сейчас, если бы им разрешали иногда делать ошибки и/или читать/писать неверно…norguhtar
09.01.2014 11:00Изменения должны начинаться где-то с СУБД, постепенно переползая в фрейморки/orm'ы. Когда какая-то часть софта сможет переживать малые глюки, а какая-то нет, тут же появится водораздельная линия «старый rigid софт» и «новый agile софт».
Проблема в том что софт априори считает что железо надежно. Даже если вы в софте приложите все возможные усилия к проверке данных и корректности работы, это все можно будет выкинуть в трубу при глюках железа. К примеру глюк железа может привести к тому что корректные данные могут посчитаться не верными. Как раз таки блочные устройства и CPU память это нижний уровень который считается «всегда рабочим».
В ходе дискуссии я сумел для себя поймать пару важных мыслей. Мы, предполагая бесконечную надёжность блочного уровня (как с точки зрения безотказности на выполнение запроса, так и с точки зрения сохранности данных) просто отказываемся думать о том, что будет, если это обещание будет нарушено.
Не совсем так. Тот же RAID был как раз придуман из-за их не надежности. В том числе для этого введен контроль четности у блоков RAID. Как раз таки из ситуации у меня рассыпался RAID выйти можно только благодаря этому.
Так вот, все приложения, полагающиеся на бесконечную надёжность нижележащего уровня просто игнорируют существование sad path, превращая его весь в bad path.
Еще раз напоминаю есть еще такая вещь как CPU и она тоже может глючить. И к примеру в случае жестких условий эксплуатации программно-аппаратные комплексы строятся с учетом багов в том числе и в CPU и в софте. Такую вещь как watchdog не от хорошей жизни придумали.
klvov
09.01.2014 11:00Один коллега-программист, как-то, задумавшись над задачей, сказал: «нам нужно придумать способ универсального хранения любых взаимосвязей...»
Но это так, вспомнилось при виде словосочетания «весь софт всех уровней...».
А если серьезнее, то действительно обработка ошибок, и как ее делать правильно — серьезный стратегический вопрос во всем конструировании ПО. Я вот для себя до сих пор так единственно правильного универсального решения не нашел. Ну вот есть централизованный способ — единственный обработчик исключений близко к входу программы, и любая ошибка вызывает raise, передающее управление этому обработчику. Но получается неудобно — ведь не каждая нештатная ситуация должна прерывать всю программу — иногда более правильно повторить попытку несколько раз (чтение из сокета TCP — может сетевое соединение к энной попытке отвиснет), а иногда лучше даже просто продолжить исполнение, но написать в лог «фигня какая-то случилась, едем дальше, но хорошо бы разобраться, как будет время, что это было такое». Именно это и происходит на практике, причем на проектах совершенно разного масштаба — от утилит под Windows до довольно больших гетерогенных систем. И тоже получается неудобно — потому что в дереве, которое образуют пути исполнения кода, образуются локальные узлы обработки ошибок (любой try… catch или аналогичная конструкция фактически образуют такой узел), образуются они хаотически, сколько их получится, предсказать невозможно, и до какого размера каждый узел разрастется, тоже заранее непонятно, и вся централизация, о которой иногда мечтают программисты в порыве энтузиазма борьбы с багами («я хочу КАЖДУЮ ошибку писать в ЛОГ») перестает работать — потому что в каждом блоке try… catch мы можем решить, что с этой ошибкой мы справимся, так сказать, «на местном уровне», а наверх, «к федералам», которые хотят «писать в лог», не будем ее передавать. Типа «им там и незачем знать, что у нас тут иногда бывают такие ошибки».
Плюс, возвращаясь к теме, даже в индустрии приняты полярно противоположные подходы — от парадигмы «let it fail», принятой в Erlang и хорошо, вроде бы, работающей в телекоммуникациях до противоположной ей по смыслу «всегда сообщай об ошибках», «никогда не глуши ошибки в секции catch» — а то ты, мол, их никогда в жизни не отловишь, потому что они будут происходить, а ты об этом даже не узнаешь — что, вроде как лучше работает при системном и низкоуровневом прикладном программировании под ОС.
В общем, интересный вопрос, наверное даже фундаментальный.
Pilat
09.01.2014 11:00Проблема не в том, что файловая система что-то ожидает, а в том, что приложение что-то ожидает от файловой системы. То есть автор пишет не о том, что хранилище должно стать надёжней или ещё что-то сделать, а о том, что приложения должны научиться обрабатывать проблемные ситуации, не только учитывать ошибки, но и адекватно их обрабатывать.
phprus
09.01.2014 11:00А что zfs?
Я лично сталкивался с ситуацией, когда zfs в solaris 10 рассыпалась (часть файлов пустые, часть с мусором, возможно часть пропала) из-за внезапно возникших проблем с дисками.norguhtar
09.01.2014 11:00Блоки имеют контроль четности, эта фича правда жрет довольно много процессора и памяти, но как раз позволяет избегать таких проблем. На данный момент zfs и btrfs наиболее близкие к описанному поведению. Так-как эти файловые системы знают что у них там дальше есть блочное устройство в том числе и такой фичей как сбойные блоки.
phprus
09.01.2014 11:00Те рассыпавшаяся у меня ZFS на самом деле мне привиделась?
Нет Я не отрицаю, что эти механизмы там есть, но спасают они не всегда.norguhtar
09.01.2014 11:00Механизм вообще-то может быть не включен. Это так к слову.
phprus
09.01.2014 11:00На сколько я помню, он был включен, а данные жили на двух дисках (маленький сервер был).
К слову диски практически окончательно почили в бозе на попытке сделать полный дамп для последующего анализа и доставания того, что появилось после последнего бекапа, так что может быть полярный лис был слишком велик, чтобы быть как-то скомпенсирован.norguhtar
09.01.2014 11:00Если полярный лис был велик то конечно такой механизм там не поможет. Как и механизмы встроенные в tcp не помогут в случае бульдезириста перебившего оптический кабель.
amarao Автор
09.01.2014 11:00Однако, сравните результаты — если кабель порвали, то как только кабель появится, всё продолжит работать. Если резервирование переключится достаточно быстро и потеряется не очень много пакетов, то даже tcp-сессии не порвутся.
norguhtar
09.01.2014 11:00Однако, сравните результаты — если кабель порвали, то как только кабель появится, всё продолжит работать.
Но данные которые передавались в тот момент могут потеряться. Ну в RAID опять же вы диск замените и все продолжит работать.
phprus
09.01.2014 11:00Полярный лис был достаточно велик, но я надеялся получить какую-то диагностику о том, что случилась какая-то нехорошая вещь прямо вот сразу, а не после того, как увидел, что случилось с системой. Так как приход пушного зверя сопровождался аварией на чистом питании (КЗ), то была перезагрузка, а после нее solaris при загрузке начал ругаться на битость библиотек и исполняемых файлов и загрузиться не смог. Согласитесь, это не является ожидаемой диагностикой повреждения ФС? Я бы предпочел чтобы сервер не загрузился ругаясь на консоль страшными словами о повреждении ФС с предложением что-нибудь сделать или грузиться на свой страх и риск.
TCP в случае бульдозериста не выдал бы мусор и можно было-бы отследить таймаут приема/передачи или разрыв соединения.norguhtar
09.01.2014 11:00но я надеялся получить какую-то диагностику о том, что случилась какая-то нехорошая вещь прямо вот сразу, а не после того, как увидел, что случилось с системой. Так как приход пушного зверя сопровождался аварией на чистом питании (КЗ)
Это как раз полярный зверь с порванным кабелем. Но обще описанное вами встречается крайне редко и говорит о том что фактически при КЗ в буфере диска образовался мусор который и был записан в итоге на диск. Вам крупно повезло что вообще хоть что-то читалось.
Я бы предпочел чтобы сервер не загрузился ругаясь на консоль страшными словами о повреждении ФС с предложением
что-нибудь сделать или грузиться на свой страх и риск.
Ну к примеру CentOS или другом linux дистрибутиве такое может быть. Там есть initrd который во многих случаях позволяет загрузиться в rescue mode и как-то починить. Но вообще сравнивать tcp и блочные устройства это тоже самое что сравнить tcp и ethernet.phprus
09.01.2014 11:00при КЗ в буфере диска образовался мусор который и был записан в итоге на диск
Судя по объему поврежденных данных буфер диска (это который в диске или RAM? Если второй, то он вряд-ли бы успел куда либо записаться) должен был измеряться гигабайтами, что в том железе было невозможно :) Так что я все-же склонен считать, что посыпались не самые новые диски, а ZFS видимо таким образом «восстановилась» увидев местами битые данные, ну а суммарно — звезды так сошлись (Не часто N-лет работающие PDU вдруг коротят где-то внутри)… Хотя кто его знает. Это сейчас уже не проверишь. Уж пара лет минула с тех пор и нет в тех краях никаких Solaris.
Если бы оно не прочиталось — это было бы значительно лучше, так как проблема была бы сразу видна, а не куча сообщений о битых библиотеках и бинариках.norguhtar
09.01.2014 11:00Судя по объему поврежденных данных буфер диска (это который в диске или RAM? Если второй, то он вряд-ли бы успел куда либо записаться) должен был измеряться гигабайтами, что в том железе было невозможно
Повреждается как правило не сами данные, а метаданные файловой системы. Обычно помогает ручной прогон восстановления, при этом старые данные берутся из копии, почему оно автоматом не умеет остается загадкой. Видимо боятся безвозвратного повреждения данных.
amarao Автор
09.01.2014 11:00Известно ли, что в побитых файлах мусор? То есть есть ли механизм, которым ОС может сказать «вот вам данные, но хрен знает, правда это или нет»?
norguhtar
09.01.2014 11:00Конечно. Контрольная сумма у каждого блока. ZFS вам может сказать насколько бита файловая система. Легче от этого вам стало?
t13s
09.01.2014 11:00Мне кажется, что автор, говоря в целом здравые вещи, путает теплое с мягким.
TCP — унифицирован (одинаково работает с данными). SDS в каждом конкретном случае должно понимать, что именно сломалось (ошибка в банковской транзакции, скорее всего, должна обрабатываться иначе, чем ошибка картинки с котиком), и как это чинить.
TCP занимается передачей «того, что где-то есть», поэтому в случае проблем не страшно — мы знаем, где взять еще. Сторадж может хранить то, чего больше в мире нет, поэтому хочется, чтобы он был надежным.amarao Автор
09.01.2014 11:00Пример с TCP — это для контраста. Я хотел показать, что в сетевом стеке все всегда готовы к ошибкам. Код, который не ожидает ошибок не доживает до продакшена.
С блочными устройствами это не так. То есть продакшен код работает с диском, и максимум что может сделать в случае ошибки — свернуться в трубочку. Без обработки, гуманного восстановления и т.д.
Чтобы SDS смогли напоминать SDN нужно, чтобы отношение к блочным устройствам было такое же, как к сетевым.t13s
09.01.2014 11:00Я понимаю. Но здесь уже вступает в игру вопрос целесообразности: а готов ли покупатель ПО платить за разбухший в 10 раз код, который умеет восстанавливаться из любой невероятной ситуации? Может, дешевле бэкапиться и ставить более надежные винты в параноидально зеркальные рэйды?
А каковы возможные побочные эффекты подобного интеллектуального поведения? Даже если рассматривать ваше предложение с картами («Да, у нас повредилась одна банковская транзакция по вашей карте...»): а что, если этой транзакцией списывались ВСЕ деньги со счета. Неужели банк должен рисковать и позволить снять их еще раз?
Отношение к блочным устройствам не может быть таким же, как к сетевым. Равно как отношение к подлиннику Моны Лизы не может быть таким же, как к любым ее репродукциям.amarao Автор
09.01.2014 11:00То есть вы хотите предполагать, что блочные устройства имеют бесконечную надёжность и никогда не ломаются, то есть не писать sad path, а сразу считать его bad path? Тогда, по мере роста сложности и масштабности проектов, отказы будут становиться всё более болезенными, ставя на колени целые компании.
В моём примере говорилось, что не смотря на то, что транзакция потеряна, сумма по счёту известна. Если же повредится текущая сума по счёту, то её можно высчитать по транзацкциям и предыдущему зафиксированному итогу. Если же и транзакции и зафиксированный остаток повреждены, то да, эта конкретная карта не доступна для обслуживания. Она одна, а не все 20 миллионов, которые были в БД.t13s
09.01.2014 11:00Ломается всё. Даже сервера Гугла, порой, бывают недоступны. (:
В любом случае нам приходится опираться на надежность каких-то базовых вещей. Уйду в лирику, но вспоминается фраза: «в трезвом уме (CPU) и здравой памяти (RAM, HDD)». И если что-то не работает, не надо это скрывать, нужно звать санитаров.
Особенность блочного устройства в том, что наличие проблемы, как правило, говорит о его скорой смерти. Поэтому как раз в ответственных системах лучше говорить о проблеме сразу, не маскируя ее. Вылетел из RAID винт? Заменить его немедленно, т.к. его стоимость в 10^X раз меньше ценности данных, которые он хранит.
Не совсем понятен тогда пример: откуда известна сумма, если транзакция, в которой эта сумма менялась, запоролась? Или же у нас есть дублирование: сумма отдельно, лог операций (транзакции) отдельно? Если так, то чем такое дублирование, в котором каждое из хранилищ ненадежно, лучше универсального RAID 1, в котором такие же ненадежные стораджи?
Можно подойти к вопросу с другой стороны: вы пишите, допустим, статью в Word и сохраняете в «ненадежное» хранилище, которое запарывает, пусть, 0.01% всех данных. Как мы можем гарантировать, что сможем эту статью прочесть в том виде, в котором вы ее написали?
foxkeys
09.01.2014 11:00Минусую выводы статьи.
Хранение данных — не та область, где допустимы какие-бы то ни было потери.
В теории — 1 убитый байт может сделать все данные (единицы хранения) полностью негодными к использованию. Причем «без вариантов» исправления (на существующем уровне всего стека технологий).
Согласитесь, даже один битый байт в системном файле ОС «живущей» в таком облачном хранилище может привести к чему угодно, включая полный фатальный выход из строя системы в целом.
Ведь все дело в том, какой слой абстракции ответственен за целостность данных. Сейчас за него отвечает устройство хранения — просто потому, что нереально (и экономически не обосновано, в первую очередь) перекладывать этот контроль на уровень приложения. Вы вообще себе представляете контроль целостности всех структур данных всех приложений? И обработку всех возможных повреждений?
К слову, существующий уровень работы с устройствами хранения, кстати, отнюдь не подразумевает бесконечной надежности. И отказ чтения одиночного сектора может (но не обязан) обрабатываться на прикладном уровне.
И задача подсистемы хранения или выполнить команду и доложить об успехе — или честно сообщить, что вышел облом. А никак не строить предположения на тему «а может приложение обойдется без этих ХХ байт?», «А может ему сойдут эти байты их прошлого бэкапа?»
foxkeys
09.01.2014 11:00Вы путаете надежность и честность.
Никто не требует от подсистемы хранения 100% сохранности и правильности данных. Но требуют 100% информации о факте сохранности и правильности данных.
Это не дно и то же!
Если узел недоступен или поврежден — задача подсистемы хранения информировать об этом приложение, возможно, опционально, предложив запрошенную информацию в виде «что смогла — то нашла».
Таким образом, приложения готовые работать с неполными данными — смогут продолжить работу. А не готовые — сообщат о фатальном сбое.
То, что вы предлагаете может стать расширением протокола обмена.
Но вот «тихая» подмена данных (или информации о состоянии данных — при записи например) в рамках существующих протоколов IO никак не допустима.amarao Автор
09.01.2014 11:00Но ведь любой жёсткий диск может давать ошибочные данные. Даже известна вероятность — её пишут в техспеках (что-то порядка 10-20). То есть когда это происходит — мы имеем bad path вместо sad path, потому что софт предполагает, что ошибок нет и быть не может. Более того, даже если энтерпрайз использует 520-байтные сектора, то всё равно есть вероятность расхождения контрольной суммы. И никто к этому не готов.
То есть все утверждают «СХД должна быть надёжной, мы полагаемся на её надёжность на 100%». Что не правда, по факту. И от этого возникают всякие чрезмерно гротескные аварии.
Я же предлагаю во-первых признать, что это может случаться, во-вторых превратить из bad path в sad path. В этом случае качество из «всё отлично» и «получили ложные данные с СХД — всё пропало» превратится в плавную характеристику, которую можно будет менять под задачу.foxkeys
09.01.2014 11:00А как по вашему софт «может полагать что в данных есть ошибка»?
Как вы себе представляете обработку на прикладном уровне ответа подсистемы хранения вида «вот вам данные, содержащие ошибку с вероятностью 0,0005%»?
Какова степень полезности такого ответа подсистемы хранения для прикладного уровня?amarao Автор
09.01.2014 11:00итого, у нас два сценария: либо бесконечная надежность и bad path, если не получилось, либо sad path, когда мы предполагаем вероятность отказа.
Больше вариантов нет.
Если мы работаем с поддержкой sad path, но на идеальном железе, то это второй случай, только в режиме 《пока не случилось》.
Какой из вариантов рассматриваем?
qw1
09.01.2014 11:00В системах хранения данные проверяются, как и в TCP. Если блок передался неверно по SATA-шине, он прозрачно для пользователя передаётся повторно. Правильная аналогия того, что хочет автор, перенесённая на сетевой стек, выглядит так: «youtube недоступен? давайте покажем юзеру rutube. авось, не заметит»
amarao Автор
09.01.2014 11:00Эти проверки базируются на совпадении чексуммы. Вероятность ошибки очень мала, но она изящно компенсируется петабайтами, которые переливаются с/в СХД. Когда эта ошибка происходит — аналогично, выше по уровню никто к этому не готов. При том, что вероятность есть и она не нулевая.
Насчёт рутуба аналогия неверна. Верная — «не удалось отдать содержимое странички, давайте ему отдадим другую страничку с кодом 500». И даже если на сервере случилась беда и он стал отдавать пустые странички с кодом 200, любое уважающее себя http-приложение (тот же aptitude) это прекрасно обработает.qw1
09.01.2014 11:00Давайте на примере аудиоплеера. Если не читается mp3-файл, плеер выкидывает message box с ошибкой. Чем это отличается от страницы с кодом 500?
crrr
09.01.2014 11:00Поправьте меня если я не прав: Смысл статьи сводится к тому, что система в целом должна переваривать ошибки работы с хранилищем и преподносить пользователю результат — «Ваш баланс на нуле, но не беспокойтесь это, возможно, временно :)»? Нет, в целом, если приложение не падает с ошибкой — «Не удалось прочитать данные по адресу 0xЛяЛяЛя» а продолжает работать, то, возможно, это где-то приемлемо…
Все остальные рассуждения сводятся к репликации контролю за ошибками итп, что, собственно, велосипед. Я работал с системами EMC Symmetrics, там надежность зависит от вложенной суммы денег. И это всегда и везде так. Имейте 2,3,4,… дата центра в разных городах, имейте 2,3,4,… оптических линка на каждый, в итоге вы упретесь в надежность вашей ближайшей АЭС, ГЭС, ТЭЦ…amarao Автор
09.01.2014 11:00Суть статьи сводится к следующему: перестать полагаться на нижележащие уровни как на идеальные устройства с 100% надёжностью и гарантиями. Как только вместо good path/bad path в IO появится sad path, у IO появится значительная свобода манёвра, а последствия отказа в IO будут не такими разрушительными и массивными.
crrr
09.01.2014 11:00Это понятно, ноо… И… Может это для нубов?.. Вот пример: Есть некое распределенное хранилище данных, есть некий кластер серверов, и есть некое пользовательское ПО на терминалах. В каком месте и что именно не должно рассчитывать на надежность нижестоящей системы?
Формализирую. Есть, допустим Java EE кластер на котором крутится сервер приложений, который работает с ораклом, который работает с хранилищем. Сервер приложений делает транзакционные запросы к БД и корректно их обрабатывает, оракл делает запросы к хранилищу и тоже корректно ждет успеха или неудачи без паники. Хранилище, в свою очередь, так же работает с физ накопителями. И это реальную существующую систему я описываю. Где профит?
Или это туториал как писать отказоустойчивые приложения?amarao Автор
09.01.2014 11:00Вы хотите «как бы мне новые идеи под старый лад приделать».
Скорее схема будет выглядеть так:
Хранение — некая система, обещающая 99.98% аптайма, 99.97% успешного завершения операций IO, 99.998% достоверность прочитанных данных и 99.997% сохранения записанных.
Это означает, что примерно каждый 5000-10000ый запрос превращается в тыкву. (тривиальность с «ошибка — повторить попытку» я пропускаю).
Над этим блочным устройством находится субд (не оракл — забудьте про интеграцию идеи в существующие решения). СУБД в курсе потенциальных проблем. В её схеме (sql это, граф, или ещё что-то — не важно) отражено то, насколько важны данные. Например, индексы помечены как неважные, данные в разных колонках помечены разным уровнем критичности. Метаданные самой БД крайне важны и имеют высокий показатель устойчивости.
Приходящие запросы к БД так же имеют показатель требований к точности ответа (с экспоненциально возрастающей стоимостью по мере роста точности, то есть 1 условный тик для 99.98% надёжности, 10 тиков для 99.985%, 100 тиков для 99.99%, 1000 тиков для 99.992 и т.д.).
Например, запрос select count (*) from… может иметь требования низкой надёжности (надо примерно знать сколько записей) — и он будет выполняться быстро. Какой-то важный запрос будет иметь высокие требования по надёжности — и он будет выполняться долго и медленно.
При получении запроса СУБД для чтения:
* Проверяет, может ли быть запрос выполнен (выполнены ли обещания по надёжности полей). Если да — в соответствии с запросом данные читаются из нескольких мест, сравниваются. Если все совпали, возвращается ответ с посчитанной вероятностью достоверности. Если различаются — проверяется, можно ли восстановить данные (дублированные данные, пересчёт индекса и т.д.) — и они возвращаются с опять же посчитанной вероятностью достоверности. Если достоверно посчитать не удалось, то данные возвращаются в приложение, но с очень низкой вероятностью достоверности (Ответ: число детей у Иванова — 3e+30, достоверность ответа 0.1%).
* При получении записи: учитываются требования полей схемы (по избыточности) и требования приложения по избыточности. (В каком-то случае это может быть рассчёт контрольной суммы, в каком-то — дублирование и т.д.).
Приложение, получив ответ, смотрит на его достоверность (раньше достоверность была «да»/«нет», теперь — вещественное число) и принимает решение о том, что делать дальше.
Например, попытаться снова. Или спросить данные из другого источника. Или обработать их, но передать информацию о недостоверности (сумма штрафов — 3000 рублей, достоверность — 99.9997%, сумма пени — 200 рублей, достоверность 85%).
norguhtar
09.01.2014 11:00Хранение — некая система, обещающая 99.98% аптайма, 99.97% успешного завершения операций IO, 99.998% достоверность прочитанных данных и 99.997% сохранения записанных.
Это означает, что примерно каждый 5000-10000ый запрос превращается в тыкву. (тривиальность с «ошибка — повторить попытку» я пропускаю).
Вообще говоря любой жесткий диск и обычный CD и DVD диск из себя такую систему и представляет. Для коррекции ошибок там используется CRC в различных его проявлениях. Если бы не использовались то показатель их надежности были бы существенно ниже.
СУБД в курсе потенциальных проблем. В её схеме (sql это, граф, или ещё что-то — не важно) отражено то, насколько важны данные. Например, индексы помечены как неважные, данные в разных колонках помечены разным уровнем критичности. Метаданные самой БД крайне важны и имеют высокий показатель устойчивости.
Эм. Как вам сказать в случае tcp это не так. tcp вообще ничего не знает о надежности среды. Фактически предполагается что среда надежна. Как только ВНЕЗАПНО выясняется что среда не надежна, возникли ошибки и т.п. подключаются алгоритмы компенсации ошибок. Как вы себе это представляете на уровне СУБД?phprus
09.01.2014 11:00Эм. Как вам сказать в случае tcp это не так. tcp вообще ничего не знает о надежности среды. Фактически предполагается что среда надежна.
Это не верно.
TCP изначально создавался как протокол, обеспечивающий надежность передачи или выявление ошибки (возможно, по таймауту) по среде с принципиальной ненадежностью.norguhtar
09.01.2014 11:00Возможность выявления ошибок, а не их исправления. Работоспособность там обеспечивается банальной повторной передачей пакета и изменением алгоритма отправки. О том что у него там за среда передачи он ничего не знает. К примеру контроль четности у блоков ZFS работает по тому же принципу.
phprus
09.01.2014 11:00Извините, а Вы сейчас точно мне отвечали?
О том что у него там за среда передачи он ничего не знает.
Ошибаетесь. TCP точно и однозначно знает, что нижележащая среда принципиально ненадежна. В противном случае TCP был бы не нужен.
Дублирование передачи — тоже метод исправления ошибки, по этому TCP имеет функциональность и выявления ошибок, и их исправления, а также механизм предсказания поведения среды, который основываясь на особенностях поведения сетей позволяет так менять свое поведение, чтобы попытаться уменьшить вероятность возникновения ошибки в будущем (контроль перегрузки).norguhtar
09.01.2014 11:00Извините, а Вы сейчас точно мне отвечали?
Да тут просто есть одна вещь. Начали скатываться на достоверность данных у хранилища. Чего как раз таки нет у TCP.
Ошибаетесь. TCP точно и однозначно знает, что нижележащая среда принципиально ненадежна. В противном случае TCP был бы не нужен.
Возможно не надежна. Иначе бы избыточности закладывали больше в том числе и CRC
Дублирование передачи — тоже метод исправления ошибки, по этому TCP имеет функциональность и выявления ошибок, и их исправления, а также механизм предсказания поведения среды, который основываясь на особенностях поведения сетей позволяет так менять свое поведение, чтобы попытаться уменьшить вероятность возникновения ошибки в будущем (контроль перегрузки).
Фишка как раз в том что ни черта он не знает как выяснилось из-за этого начали городить новые алгоритмы работы tcp в случае перегрузки и потерь.phprus
09.01.2014 11:00Начали скатываться на достоверность данных у хранилища. Чего как раз таки нет у TCP.
Если данные доставлены получателю, они достоверны с вероятностью отсутствия коллизии контрольной суммы.
Возможно не надежна. Иначе бы избыточности закладывали больше в том числе и CRC
Гарантировано ненадежна. Да, обычно данные доходят, но мы гарантировано знаем, что они могут и не дойти (совсем, а не прийти битые).
Избыточность увеличивает накладные расходы и никак не спасает от повторных передач. Кроме того, в сетях, в отличие от дисков основной процент отказов — недоставка пакета, а любой уровень избыточности кодирования пакета бесполезен, если пакет не был доставлен (даже контрольную сумму у него не посчитать).
Фишка как раз в том что ни черта он не знает как выяснилось из-за этого начали городить новые алгоритмы работы tcp в случае перегрузки и потерь.
Все эти алгоритмы направлена на лучшее предсказание поведения среды, а не на базовые принципы обеспечения надежности.norguhtar
09.01.2014 11:00Если данные доставлены получателю, они достоверны с вероятностью отсутствия коллизии контрольной суммы.
В случае жесткого диска тоже самое.
Гарантировано ненадежна. Да, обычно данные доходят, но мы гарантировано знаем, что они могут и не дойти
При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.
Избыточность увеличивает накладные расходы и никак не спасает от повторных передач. Кроме того, в сетях, в отличие от дисков основной процент отказов — недоставка пакета, а любой уровень избыточности кодирования пакета бесполезен, если пакет не был доставлен (даже контрольную сумму у него не посчитать).
Если пакет дошел битым, то спасает. То что вероятность того что он вообще не дойдет это да.
grossws
09.01.2014 11:00При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.
Всё-таки не битовый CRC, а коды Рида-Соломона, чтобы получить нужный уровень избыточности и возможность восстановления.
phprus
09.01.2014 11:00При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.
Если CD или DVD в момент между извлечением диска из коробки и установкой в привод может бесследно исчезнуть, то да, его можно сравнивать с TCP. Но раз диск есть всегда и нужно только убедиться правильная ли информация считалась или нет, то механизмы типа CRC подойдут, а с учетом того, что диск все-же обычно не исчезает, то я бы его отнес к возможно ненадежным системам (данные в каком-то виде есть, а не может быть есть, а может быть и нет).
norguhtar
09.01.2014 11:00Проблема у CD или DVD в том что один и тот же сектор может считываться по разному.
t13s
09.01.2014 11:00сумма пени — 200 рублей, достоверность 85%
И что должно прикладное приложение делать с этой информацией? Что должен делать пользователь системы, который хотел внести оплату?
Варианта все равно два: либо система работает и мы платим, либо она выдает вот такую хрень (т.е. не работает) и мы не платим (потому что хз — переплачу я или недоплачу с вероятностью 15%).
Если же вы говорите, что в случае низкой вероятности прикладное приложение должно искать в другом месте, то чем это предложение отличается от текущих реализаций дублирования данных (RAID, репликация в удаленное хранилище)?
crrr
09.01.2014 11:00И да, как выше уже упомянули, куча ошибок не на стороне хранилища а на стороне системы в него пишущей, в этом случае все сводится к транзакциям, надежности пишущей системы и теории вероятности. Для этого и придумали журналируемые ФС. Если мы даже представим себе 100% надежную систему хранения и ФС, остается пользовательское приложение, которое в последний миг своего существования перед полным крахом по питанию итп, хочет записать куда-то псевдоправдивую информацию. Опять теория вероятности…
essential55
09.01.2014 11:00Я уважаю автора, но статья похожа на какие-то фантазии. Давайте еще CPU и Память будут вести себя как захотят, иногда правильно, иногда нет. Как приложение может относится к неверным данным и как оно узнает, что они неверные? Возможно для какого то узкого круга данных — это возможно. В моем понимании файловая система должна делать попытки читать данные с реплики если они где-то недоступны. Все остальное похоже на космические технологии.
amarao Автор
09.01.2014 11:00Я не очень люблю эрланг, но его модель с супервизорами всего — это очень и очень правильный ответ на вопрос «а что нам делать, если процессор сделал что-то не так, как мы хотели».
Вообще, всё-таки между IO и процессором+памятью есть большая разница. IO — это периферия. Её ошибки можно обрабатывать (собственно, на уровне контроллера всё обрабатывается правильно). Ошибки процессора совсем другие (т.к. это начинается история класса «кто сторожит сторожей»). В отношении IO следует просто перестать предполагать бесконечную надёжность. Такого не бывает.vsespb
09.01.2014 11:00Вообще, всё-таки между IO и процессором+памятью есть большая разница.
Так же как и между IO и TCP — большая разница.
TCP — реально может порваться в любой момент.
IO — если сломался, пусть юзер сначала починит, потом продолжит пользоваться машиной.amarao Автор
09.01.2014 11:00Вы изложили текущее положение вещей.
А я предлагаю подумать о такой системе, в которой бы «IO может порваться в любой момент». У неё были бы минусы, но были бы и плюсы.essential55
09.01.2014 11:00Тоесть вы хотите такое IO для узкого круга данных? А не для всего в целом? Я более чем уверен такие вещи существуют.
essential55
09.01.2014 11:00Обьясните мне, что должен делать процесс если вместо 4 он прочитал 5. И откуда он может знать, что он хотел получить 4? систему хранения вообще очень сложно сравнить с сетевым стеком, но вы как-то пытаетесь это сделать. Все очень просто, если нет интернета браузер бесполезен, он не выполняет своих функций. Вы хотите чтобы DB зависала, когда не могла читать данные и все спокойно ждали пока данные появятся? Зачем такие подсистемы?
crrr
09.01.2014 11:00Была еще фраза про повторы чтения, записи, так это есть даже в мало-мальски серьезных системах хранения информации. И хотя там те же рейды, но там и память и ОС своя, и кэши всех уровней и железо. На курсах по EMC Symmetrics, американец препод заикнулся, что они для NASA поставляли железки с сотнями ГБ оперативки. А учитывая их технологии по репликации и восстановлению этого может оказаться достаточно, чтобы заменить ноду целиком без даунтайма.
ЗЫ
Не реклама. Опыт работы 4 года.
ЗЗЫ
Не успел на минуту :)amarao Автор
09.01.2014 11:00С EMC не имел дела в боевых режимах, по некоторым их конкурентам могу сказать, что сыпятся они. Саппорт крутит ушки трубочкой и просит «собрать дополнительные данные, когда это случится снова». Такие аварии происходят реже, чем commodities, но в силу того, что на них кладутся большие объёмы данных и нагрузки, последствия оказываются куда более болезненными (чем в случае распределённых решений с easy fall).
crrr
09.01.2014 11:00У нас вылетало по несколько дисков из массива за раз. Это расплата за нагрузки. Но тут как заплачено так и
за..работает.amarao Автор
09.01.2014 11:00Не, в тех случаях это было исключительно и только долбо… на софте вендора.
Но главное — не бывает бесконечной надёжности. А существующий софт на это закладывается, обещая устроить армагеддон в случае мельчайшего отклонения от этого).
vsespb
09.01.2014 11:00Не согласен с этой идеей.
Система с данными — маленькая (конечная по размеру и маленькая) — ОС, файлы, критически важные данные в БД. Хотите бесконечной надёжности — делайте бесконечное дублирование. То что математически бесконечной надёжности не бывает — это спекуляции — всё равно есть вероятность что все сотрудники фирмы умрут в один час от синдрома «внезапной смерти», на континент упадёт метеорит, а во всех процессорах всех компьютеров системы будет сбой.
Если у системы есть какой-то огромный объём данных, сохранность которых не важна — храните их на отдельных устройствах, в специальных файловых системах, в специальных СУБД, API которых позволят ответить «этой записи больше нет и не будет» и не упасть.
Зачем сюда приплетать весь стек существующих технологий, стандартов, POSIX API, файловые системы и СУБД?amarao Автор
09.01.2014 11:00Затем, что если бы из «синдрома внезапной смерти» небольшие ошибки в большом массиве данных обрабатывались бы с небольшими последствиями, то вместо «либо пан, либо пропал» мы бы получили плавный показатель «качества» (частоты ошибок), который бы открыл массу возможностей по построению «чаще всего хорошего» сервиса.
Предполагая любой отказ СХД как аварийный, мы автоматически закладываемся на какое-то количество аварий (которых не ждём) и предотвратить которые можно только «бесконечным дублированием».crrr
09.01.2014 11:00Не бывает небольших последствий в серьезных проектах. Лучше какой-то краткий даунтайм и гарантия достоверности и полноты данных, чем сообщение бухгалтеру, что его платежка на $1млн, «скорее сохранилась чем нет»
amarao Автор
09.01.2014 11:00… После того, как даунтайм станет долгим, дирекция может прийти к выводу, что 90% вероятность успеха платёжки на 1% от дневного оборота фирмы не такая уж большая расплата за продолжение работы.
Кстати, гарантий достоверности всё равно нет. Повторю снова, ни один вендор не гарантирует сохранения данных в неизменном виде. Просто потому, что данные могут побиться так, что пройдут через чексуммы. Так что некоторая вероятность ошибки в системе уже есть, а вот её обработки — нет.qw1
09.01.2014 11:00Так подождите. Известно, что чексумма в ip-пакете занимает 16 бит. Это существенно (на 16 двоичных порядков) ниже, чем типичная CRC32, которой защищены сектора на диске (не говоря уже об экзотике с 520-байтными секторами, где под восстановление отводится 64 бита).
Если вы утвердаете, что вероятности незамеченного сбоя на дисках недопустимо велики, придётся признать, что сеть в таком случае чудовищно неустойчива, на несколько порядков хуже себя ведёт.
vsespb
09.01.2014 11:00У любой системы есть некоторое количество данных, которые критически важны (код программы, учётные записи пользователей итд),
работать с ними через API, которое может ответить что данных больше нет — нецелесообразно, так как обработка такой ошибки всегда будет одинаковая — завершение программы.
Их всё равно нужно дублировать.
Я считаю что:
— Большинство сущностей в программе приходится на эти данные (90% сущностей занимает 10% данных по объёму — звучит правдоподобно?).
— Большая часть кода программы обрабатывает эти данные (на каждую сущность нужно написать одинаковое количество кода)
— Размер этих данных мал (в нашем примере 10%)
Уменьшение размера таких данных с гигабайта до мегабайта (к примеру) ничего не принесёт (вплане экономии на дублировании).
Т.к. переписывать 90% кода программы, на новый API, таким образом что оно интелектуально пытается обрабатывать ситуации «запись о юзере уничтожена»,
«файлы программы уничтожены» ради экономии на дублировании гигабайта данных не целесообразно.
Если речь идёт о системе с огромным количеством данных — то большая часть этих данных (по объёму) обрабатывается очень маленькой частью программы.amarao Автор
09.01.2014 11:00Вы предлагаете «в новой версии сделать так, чтобы данные снова были достоверными на 100% и работать ка работали». А я хочу сказать, что надо учиться работать в условиях заданной достоверности.
Как я уже говорил, даже в существующих системах вероятность молчаливого искажения данных не нулевая. Но на это все забивают, потому что «редко бывает». А вместо «забивать» — надо научиться обрабатывать без завершения программы.
В этом случае СХД с пониженными показателями надёжности могут открыть целые новые пласты применяемости.vsespb
09.01.2014 11:00Я говорю что в 90% кода не может быть никакой другой обработки ошибок кроме как завершить программу, либо такая обработка там экономически не целесообразна (т.к. дублирование гораздо проще).
amarao Автор
09.01.2014 11:00Блин, у меня ощущение, что аргументы не слышат. Дублированная информация всё равно не даёт 100% гарантии неизменности. То есть проблема всё равно остаётся и её невозможно решить, по крайней мере в рамках существующих технологий и существующей квантовой физики.
Насчёт «не может быть никакой другой обработки» — не верю. Допустим, почтовый клиент (оффлайновый). Да, данные для доступа — критические. Остальное? Ну да, показываем письмо с пометкой «содержимое письма доступно с достоверностью 99.9%, что ниже порога в 99.99%, ожидаемого для этих данных». Это же лучше, чем сказать, что письмо недоступно, или вообще, объявить всю почтовую базу к чёрту нерабочей? Даже данные для доступа — лучше попытаться с логином и паролем у которых 30% достоверность, чем сразу же сказать «нету паролей и логинов, и вообще, файла конфигурации нет, ничего нет».
Другой пример — шелл (юниксовый). Он читает history, там часть данных с низким процентом достоверности. Что делать? Можно эти данные показывать с пометкой о недостоверности. Или исключить из автоподстановки. Или вообще, игнорировать.
(Я специально пропускаю вкусные случаи с мультимедиа).vsespb
09.01.2014 11:00Дублированная информация всё равно не даёт 100% гарантии неизменности
Я написал выше про синдром внезапной смерти — исчезающе малые вероятности вообще неинтересны никому. Т.к. вероятность отказа всёго остального гораздо больше.
Это же лучше, чем сказать, что письмо недоступно, или вообще, объявить всю почтовую базу к чёрту нерабочей?
Храните отдельно огромное колво писем, в отдельной СУБД, на отдельном устройстве. А всё остальное что относится к программе (метаданные писем) не трогайте, храните по старому и дублируйте.
Другой пример — шелл (юниксовый). Он читает history, там часть данных с низким процентом достоверности.
history очень мало занимает, гораздо проще дублировать её, чем менять весь POSIX API. Или даже, чем просто писать новый shell. И даже, если писать новый shell, по другим причинам, проще дублировать, чем обрабатывать такие ошибки.amarao Автор
09.01.2014 11:00Ок, я вашу позицию понял. Всё хорошо, нам надо использовать супернадёжные супердорогие суперсхд, а если они навернутся, то саппорт объяснит, как в следующий раз собрать статистику.
В индустрии СХД всё хорошо и никаких проблем нет, а если и есть, то можно приписать два нуля и на ближайшие пол-года проблем снова не будет.
Всё интересное я уже услышал, дальше мы будем просто спорить о том, «надо или нет».
vsespb
09.01.2014 11:00Взать, например, твиттер.
Там большие данные — твиты, и, наверное юзеры. Всё.
Как Вы думаете сколько таблиц в БД у твиттера? Две? Врядли. Я думаю 100 (или больше)
Как Вы думаете, сколько по объёму данных занимают оставшиеся 98+ таблиц? Я думаю очень, очень мало.
Как Вы думаете, что делает 99.9% кода твиттера. Читает твиты/юзеров из БД и решает что делать если твит не прочитался?
Очень сомневаюсь, скорее всего он имеют дело с твитом который уже прочитался. А чтение твита из базы происходит только в одном месте.
Или этот код имеет делао с 98 остальными таблицами и уже прочитанным твитом.
Так зачем эти 99.9% кода и БД переписывать на новый, «отказоустойчивый» API?
realbtr
09.01.2014 11:00По сути, вопрос сводится к степени зрелости технологии хранения данных, по отношению к технологии их передачи. То есть, можем ли мы более высокую степень зрелости софта в области коммуникаций революционно проецировать в проектирование софта в области хранения и обработки данных.
А это уже, на мой взгляд, вопросмконкретных спецификаций. На уровне парадигмы трудно даже доказать или опровергнуть большую зрелость коммуникаций перед хранением и обработкой.
Но, направление исследований, на мой взгляд, задано весьма точно и ясно. Возможно, смена сквозной парадигмы хранения и обработки данных с концепции «все данные особенные и сохраняются по умолчанию на века, пока я не затребую их перемещение илииудаление» на концепцию «интеллектуальное распознавание степени важности каждого фрагмента информации» приведет к более значительным изменениям архитектуры систем обработки и хранения с фунционально-ориентированных на инфраструктурно-ориентированные.
В конечном итоге, мне проще использовать одну команду «найти данные», когда потоки передачи определяют и место и способ их сохранения и обработки, с учетом их ожидаемой доступности и производительности (а так же изменчивости и в доступности, и в производительности).
Мне кажется более разумным специфировать востребованность данных при каждой их передаче, чтобы система хранения выбирала место для их хранения, а так же получать информацию о процессе поиска данных, асинхронно.
Вроде как это показывают в кино про хакеров. По запросу система определяет приоритеты и направления поиска, предоставляет сведения о готовности и загруженности, при необходимости подключает даже людей (хоть администратора с запросом на решение технической проблемы, хоть эксперта, вероятно, знающего ответ на поисковой запрос или способ оптимального поиска ответа)
То есть, я полагаю, что типизировать данные в целях их интеллектуального хранения и обработки — можно, но не столько по их содержанию, сколько по их связанности, востребованности, вариабельности, актуальности, формализованности и т.п.
achekalin
09.01.2014 11:00> Это вместо «Неизвестная ошибка. Операция по карте невозможна, обратитесь в службу поддержки карт вашего банка».
Вот он, момент истины. Теперь смотрим глазами со стороны банка: была команда, которая написала некий банковский софт. Точнее, некую часть софта в «большом» понимании этого слова: баланс ведь не считается как самоцель, он встроен в некую цепочку операций.
Однажды банк обнаруживает, что софт тормозит/глючит в мере, которая уже не позволяет старый с любыми костылями использовать (ибо, если костыли есть еще куда ставить, проще поставить именно их — минимизируем число потенциальных точек возникновения новых гемороев, т.к. старый софт, худо-бедно, уже известно, где и как может глючить). Кому поручают разработку? Правильно, той же команде, которая написала предыдущий (да, как раз тормозящий/глючащий) софт. Команда же берется за дело, неся в себе старые наработки и старые свои шоры, так что получаем что-то, в чем опять нет революционных изменений (что, для банка, даже и неплохо).
Теперь представим, что будет, если команде этой дали задачу переписать их ПО под SDS. В лучшем случае, если они никогда SDS не использовали, они просто перелинкуют с новой lib-ой, SDS обеспечивающей, и повесят взятый из документации хук вида «если что-то не так в любом месте работы с SDS -> выкидываем табличку „приплыли!“»
По уму, конечно, эксепшены надо ловить и обрабатывать в зависимости от серьезности ситуации («ошибка при чтении файла -> пробуем перечитать; если N попыток перечитать дают ошибку, думаем, как восстановить данные и полагаем себе вернуться к этому файлу для восстановления данных в нем позже», «ошибка при записи временного файла с выборкой из БД -> создаем другой файл; если M таких попыток не удалось, пробуем другой алгоритм расчета, без временных файлов» — смысл в том, что от ФС логика должна перейти к работе именно с данными, и логика хранения и восстановления должна поменяться в сторону «что бы ни случилось, мы знаем, по каким следам восстановим то же, или предыдущее состояние данных»). Но чтобы переписать прикладное ПО под такие изменения, нужно а) быть достаточно умным, чего в in-house командах может и не случиться (они уже показали свой уровень, написав само ПО — с чего вдруг будет прыжок на порядок-другой в сложности подхода?), и б) нужно понимать, как извлечь из SDS максимум, не сведя работу с ним к очередной эмуляции DAS (в лучшем случае — NAS).
И что-то мне кажется, что написанного выше вполне хватит рук-ву банка, чтобы сказать — «раз есть риск потери данных именно из-за изменений в схеме, то ну его, это изменение». Ибо для банка ввод SDS (а также ЖК-мониторов вместо ЭЛТ, ввод ядерного реактора вместо генератора во дворе — тут можно любое «новшество» указать) не самоцель, а лишний геморой в уже отлаженном процессе жизни, с потенциально высокой ценой ошибки. Не все на такое пойдут легко, а «тяжело» идти… Так кто сказал, что SDS не сдуется через пяток лет, вытесненный очередным порождением голов маркетологов?amarao Автор
09.01.2014 11:00SDS не сдуется, просто потому, что «сдуться» софт не может. Вы хоть раз видели проект, в котором от релиза к релизу число строк уменьшается?
Например, виртуализация — сколько лет баззворду? И где она сейчас?
DarkboodZed
09.01.2014 11:00Какая классная реклама Нетапа и Оракла :)
Но учитывая что присутствуют жалобы на Неттап, получается невольная пропаганда технологического превосходства Оракла :)
Амаро, а к вам еще Nutanix в гости не ездил? Впечатлениями не поделитесь?amarao Автор
09.01.2014 11:00Реклама нетаппа? Очень смешно. Их хоронилища данных к реальной нагрузке близко подпускать нельзя. Уютненькое болотце мелкого энтерпрайза — всегда пожалуйста. Хайлоад и нетапп несовместимы.
Насчёт Nutanix — «к нам», это на Кипр?DarkboodZed
09.01.2014 11:00А что из нетаппа вам давали на погонять? Если не тайна.
Насчёт Nutanix — «к нам», это на Кипр?
Не, это к вам в Селектел. Если че я про этих граждан www.nutanix.com/
izimbra
09.01.2014 11:00Длинный текст, полный поэтических оборотов, которые, на мой взгляд, мешают восприятию. По крайней мере, я не смог составить по его прочтении четкого представления о незнакомом термине software defined storage.
Если речь идет о построении распределенных и масштабируемых хранилищ данных, то «самая большая, сложная и неприятная проблема» — это, если я правильно понял, «смерть» отдельного узла — не кажется мне проблемой. Если мы позволяем софту решать, где и что хранить, то он же может отслеживать состояние узлов и давать сигнал о нарушениях в их работе или даже падениях.
Осенью слушал доклад о том, как организовано хранение вложений на outlook.com: они как раз используют commodity-серверы в нескольких разбросанных по миру дата-центрах, хранят по несколько копий каждого файла, создают новые копии при падении узлов и т.п.
Точно так же можно реализовать софтом «возможность писать в середину файла» — если мы говорим о самой идее, а не о конкретной реализации в форме Swift.
По поводу «от дискового стека ожидают бесконечной надёжности», то наивно ожидать её от чего-либо. Правильнее, на мой взгляд, поступать как это принято в упомянутых Вами Erlang/OTP, когда упор делается не на предотвращение ошибки любой ценой, а на скорейшее восстановление работоспособности.
qw1
09.01.2014 11:00Я попытался обдумать поднятный вопрос с другой стороны.
Почему сложно сравнивать сетевую среду и среду хранения? Потому что сравнивая, предполагается, что сбои в сетевой среде локальны и после прекращения помехи данные всё-таки пройдут. А вот диски такие, что если умерло, то уже навсегда.
Поэтому справедливо рассматривать такую сеть, где сбой — это обрыв провода, без возможности восстановления в разумное время. И тут у сетей есть что предложить — делаем петли и IP находит альтернативный маршрут. Самое главное, что эта фича доступна в любой системе, не требует подключения прикладных программистов и решается без особых усилий, все технологии и протоколы давно известны.
Но в хранении есть отличная аналогия — торренты, и протокол DHT. Аналогично можно сопоставить ID ноды и вероятность нахождения на ней информации с хешем H. Любая нода может хранить некоторую информацию с ненулевой вероятностью, но на некоторых нодах вероятность нахождения искомого блока близка к 100%. Есть конечно проблемы с латентностью и согласованностью данных при репликации, но последние некоторым образом решены в bitcoin. Вот и ответ! Достаточно разработать протокол DHT-хранилища, и пусть кому нужна надёжность, пользуются готовыми реализациями.
Понятно, что в реальности мало кто делает избыточные сети, большинство сетей — звезда (дерево), обрыв провода фатален и автоматическому восстановлению не подлежит (как и сдохший диск). Аналогично и с хранилищами. Кому надо — заморочится с DHT.
scarab
09.01.2014 11:00Когда я только начинал работать в банковском IT, старшие товарищи мне очень доходчиво объяснили, что в этой сфере лучше получить втрое больший даунтайм, чем рисковать потерей целостности данных. Т.е. лучше честно сказать «чуваки, с момента X — перезавести всё по-новой», чем допускать шанс расхождения хотя бы в одну копейку, потери хотя бы одной операции.
В примере с карточкой — это не только обслуживание клиента. Это возможно неправильная итоговая сумма, которая выгрузится из процессинга в АБС, это возможно неправильные внешние платежи, которые может не удаться вернуть, это возможно неправильная отчётность, за которую у банка могут отобрать лицензию.
И не зря в СУБД есть всего два состояния — consistent и inconsistent. Т.е. — мы либо верим тому, что нам дали, либо не верим. Промежуточные случаи должны быть доступны только в maintenance-режиме, когда специалист может руками проверить и решить — верны данные или нет.
И сравнение с процессом передачи данных тут, на мой взгляд, некорректно. Критичная разница: передаваемые данные всегда можно передать повторно; потерянные при сохранении (незаписанные, нечитаемые etc) данные — потеряны навсегда.
umraf
09.01.2014 11:00Amarao прав, хотя и другие доводы верны. С трудом поймал мысль, которая крутилась в голове при прочтении поста + комментариев.
Собственно, текущая парадигма со 100% надежностью — эта наша реальность и в ней есть диски, блочные устройства, файловые системы. Не надо пытаться изменить существующую реальность, оставьте её как есть. Как и приводили в примерах, множество данных правильно хранить именно в такой парадигме.
Просто в новой парадигме не надо использовать старые понятия. Называйте в новой парадигме СХД — вероятностная система хранения данных. Не файл, а объект или документ. Не блочное устройство, а «узел хранения». Тогда уйдет непонимание «зачем это» и придет понимание «нужен новый софт».
Ещё один момент не был озвучен в слух. В новой парадигме, программа записывая данные должна указать с какой надежностью необходимо хранить именно этот объект. Что тоже невозможно в нашей реальности.
Aquahawk
Люто бешено плюсую. Не только дисков касается, но вообще всего. Гораздо лучше работают устойчивые системы нежели попытки устроить окружение так чтобы ошибки не случались. И в бизнес процессах и в программинге, и в жизни везде.