Как стать автором
Обновить

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

Люто бешено плюсую. Не только дисков касается, но вообще всего. Гораздо лучше работают устойчивые системы нежели попытки устроить окружение так чтобы ошибки не случались. И в бизнес процессах и в программинге, и в жизни везде.
В любом случае где-то там будет блочное устройство, разве нет?
Если там будет блочное устройство в текущем понимании — это будет плохо.

Сами блочные устройства (на уровне /dev/sd*) чаще всего ведут себя адекватно. Не работает сектор — остальные продолжают работать. А вот если ошибка проскакивает выше — это становится фатальной проблемой для всей файловой системы, базы данных и т.д.
Про zfs и btrfs я так полагаю автор не слышал? :)
У меня на btrfs (в режиме мирроринга силами btrfs) моя медиа-коллекция. Это как-то меняет описанную проблему? (Все ожидают бесконечной надёжности от файловой системы, да и файловые системы тоже хотят от блочных устройств бесконечности).
файловая система с контролем четности не ожидает бесконечной надежности от накопителя. Как и RAID массив не ожидает надежности от накопителя.
Когда ожидаемое качество не выполнено для блока (чексумма не помогла, кусочек файла превратился в тыкву) что происходит дальше? Как ОС объясняет приложению, какая часть файла не годна к употреблению и как на это реагирует, например, расположенная на этой ФС база данных на сообщение о том, что кусочек системной таблицы больше не кусочек системной таблицы?
Как ОС объясняет приложению, какая часть файла не годна к употреблению и как на это реагирует, например, расположенная на этой ФС база данных на сообщение о том, что кусочек системной таблицы больше не кусочек системной таблицы?

В случае RAID идет восстановление с других живых дисков, после чего сбойный диск помечается как «оно сдохло» и идет алярма, что к нему возможно пришел пушной зверек. Файловая система же этого не видит. Я реально восстанавливал раз RAID6 с двумя сдохшими дисками и ничего.
А я видел сдохшие рейды без сдохших дисков. Софтовые рейды. Дедлоки, баги ядра и т.д. В очередной раз предполагается, что уж у рейда-то точно ошибок не будет и будет бесконечная надёжность.

Всё, о чём я говорю — лишь утверждение, что такого не бывает, и весь софт всех уровней должен делаться с рассчётом на более-менее регулярные не очень значительные мелкие отказы.
А я видел сдохшие рейды без сдохших дисков. Софтовые рейды. Дедлоки, баги ядра и т.д. В очередной раз предполагается, что уж у рейда-то точно ошибок не будет и будет бесконечная надёжность.

Я тоже видел, но как правило их можно оживить с потерей информации. Но да то что работает по верх RAID считает что он надежен.

и весь софт всех уровней должен делаться с рассчётом на более-менее регулярные не очень значительные мелкие отказы.

Не получится. У вас возникнет проблема с железом вспоминаем про проблемы функционирования железа в открытом космосе.
Я и не говорю, что это пара sysctl'ов поправить.

Изменения должны начинаться где-то с СУБД, постепенно переползая в фрейморки/orm'ы. Когда какая-то часть софта сможет переживать малые глюки, а какая-то нет, тут же появится водораздельная линия «старый rigid софт» и «новый agile софт».

В ходе дискуссии я сумел для себя поймать пару важных мыслей. Мы, предполагая бесконечную надёжность блочного уровня (как с точки зрения безотказности на выполнение запроса, так и с точки зрения сохранности данных) просто отказываемся думать о том, что будет, если это обещание будет нарушено.

Sad path — это когда «ошибка, и мы знаем что делать».
happy (good) path — это когда ошибки нет и мы знаем, что делать.
bad path — это когда ошибка, и мы не знаем, что делать (или знаем, но неконструктивно, например, «паниковать и падать»).

Так вот, все приложения, полагающиеся на бесконечную надёжность нижележащего уровня просто игнорируют существование sad path, превращая его весь в bad path.

И это не даёт возможности пошевелиться дисковому уровню, потому что у него есть единственная ниша — «супернадёжный». Без компромиссов.

Кто знает, какими были бы диски сейчас, если бы им разрешали иногда делать ошибки и/или читать/писать неверно…
Изменения должны начинаться где-то с СУБД, постепенно переползая в фрейморки/orm'ы. Когда какая-то часть софта сможет переживать малые глюки, а какая-то нет, тут же появится водораздельная линия «старый rigid софт» и «новый agile софт».

Проблема в том что софт априори считает что железо надежно. Даже если вы в софте приложите все возможные усилия к проверке данных и корректности работы, это все можно будет выкинуть в трубу при глюках железа. К примеру глюк железа может привести к тому что корректные данные могут посчитаться не верными. Как раз таки блочные устройства и CPU память это нижний уровень который считается «всегда рабочим».

В ходе дискуссии я сумел для себя поймать пару важных мыслей. Мы, предполагая бесконечную надёжность блочного уровня (как с точки зрения безотказности на выполнение запроса, так и с точки зрения сохранности данных) просто отказываемся думать о том, что будет, если это обещание будет нарушено.

Не совсем так. Тот же RAID был как раз придуман из-за их не надежности. В том числе для этого введен контроль четности у блоков RAID. Как раз таки из ситуации у меня рассыпался RAID выйти можно только благодаря этому.

Так вот, все приложения, полагающиеся на бесконечную надёжность нижележащего уровня просто игнорируют существование sad path, превращая его весь в bad path.

Еще раз напоминаю есть еще такая вещь как CPU и она тоже может глючить. И к примеру в случае жестких условий эксплуатации программно-аппаратные комплексы строятся с учетом багов в том числе и в CPU и в софте. Такую вещь как watchdog не от хорошей жизни придумали.
Один коллега-программист, как-то, задумавшись над задачей, сказал: «нам нужно придумать способ универсального хранения любых взаимосвязей...»

Но это так, вспомнилось при виде словосочетания «весь софт всех уровней...».

А если серьезнее, то действительно обработка ошибок, и как ее делать правильно — серьезный стратегический вопрос во всем конструировании ПО. Я вот для себя до сих пор так единственно правильного универсального решения не нашел. Ну вот есть централизованный способ — единственный обработчик исключений близко к входу программы, и любая ошибка вызывает raise, передающее управление этому обработчику. Но получается неудобно — ведь не каждая нештатная ситуация должна прерывать всю программу — иногда более правильно повторить попытку несколько раз (чтение из сокета TCP — может сетевое соединение к энной попытке отвиснет), а иногда лучше даже просто продолжить исполнение, но написать в лог «фигня какая-то случилась, едем дальше, но хорошо бы разобраться, как будет время, что это было такое». Именно это и происходит на практике, причем на проектах совершенно разного масштаба — от утилит под Windows до довольно больших гетерогенных систем. И тоже получается неудобно — потому что в дереве, которое образуют пути исполнения кода, образуются локальные узлы обработки ошибок (любой try… catch или аналогичная конструкция фактически образуют такой узел), образуются они хаотически, сколько их получится, предсказать невозможно, и до какого размера каждый узел разрастется, тоже заранее непонятно, и вся централизация, о которой иногда мечтают программисты в порыве энтузиазма борьбы с багами («я хочу КАЖДУЮ ошибку писать в ЛОГ») перестает работать — потому что в каждом блоке try… catch мы можем решить, что с этой ошибкой мы справимся, так сказать, «на местном уровне», а наверх, «к федералам», которые хотят «писать в лог», не будем ее передавать. Типа «им там и незачем знать, что у нас тут иногда бывают такие ошибки».

Плюс, возвращаясь к теме, даже в индустрии приняты полярно противоположные подходы — от парадигмы «let it fail», принятой в Erlang и хорошо, вроде бы, работающей в телекоммуникациях до противоположной ей по смыслу «всегда сообщай об ошибках», «никогда не глуши ошибки в секции catch» — а то ты, мол, их никогда в жизни не отловишь, потому что они будут происходить, а ты об этом даже не узнаешь — что, вроде как лучше работает при системном и низкоуровневом прикладном программировании под ОС.

В общем, интересный вопрос, наверное даже фундаментальный.
Проблема не в том, что файловая система что-то ожидает, а в том, что приложение что-то ожидает от файловой системы. То есть автор пишет не о том, что хранилище должно стать надёжней или ещё что-то сделать, а о том, что приложения должны научиться обрабатывать проблемные ситуации, не только учитывать ошибки, но и адекватно их обрабатывать.
А что zfs?
Я лично сталкивался с ситуацией, когда zfs в solaris 10 рассыпалась (часть файлов пустые, часть с мусором, возможно часть пропала) из-за внезапно возникших проблем с дисками.
Блоки имеют контроль четности, эта фича правда жрет довольно много процессора и памяти, но как раз позволяет избегать таких проблем. На данный момент zfs и btrfs наиболее близкие к описанному поведению. Так-как эти файловые системы знают что у них там дальше есть блочное устройство в том числе и такой фичей как сбойные блоки.
Те рассыпавшаяся у меня ZFS на самом деле мне привиделась?
Нет Я не отрицаю, что эти механизмы там есть, но спасают они не всегда.
Механизм вообще-то может быть не включен. Это так к слову.
На сколько я помню, он был включен, а данные жили на двух дисках (маленький сервер был).
К слову диски практически окончательно почили в бозе на попытке сделать полный дамп для последующего анализа и доставания того, что появилось после последнего бекапа, так что может быть полярный лис был слишком велик, чтобы быть как-то скомпенсирован.
Если полярный лис был велик то конечно такой механизм там не поможет. Как и механизмы встроенные в tcp не помогут в случае бульдезириста перебившего оптический кабель.
Однако, сравните результаты — если кабель порвали, то как только кабель появится, всё продолжит работать. Если резервирование переключится достаточно быстро и потеряется не очень много пакетов, то даже tcp-сессии не порвутся.
Однако, сравните результаты — если кабель порвали, то как только кабель появится, всё продолжит работать.

Но данные которые передавались в тот момент могут потеряться. Ну в RAID опять же вы диск замените и все продолжит работать.
Полярный лис был достаточно велик, но я надеялся получить какую-то диагностику о том, что случилась какая-то нехорошая вещь прямо вот сразу, а не после того, как увидел, что случилось с системой. Так как приход пушного зверя сопровождался аварией на чистом питании (КЗ), то была перезагрузка, а после нее solaris при загрузке начал ругаться на битость библиотек и исполняемых файлов и загрузиться не смог. Согласитесь, это не является ожидаемой диагностикой повреждения ФС? Я бы предпочел чтобы сервер не загрузился ругаясь на консоль страшными словами о повреждении ФС с предложением что-нибудь сделать или грузиться на свой страх и риск.

TCP в случае бульдозериста не выдал бы мусор и можно было-бы отследить таймаут приема/передачи или разрыв соединения.
но я надеялся получить какую-то диагностику о том, что случилась какая-то нехорошая вещь прямо вот сразу, а не после того, как увидел, что случилось с системой. Так как приход пушного зверя сопровождался аварией на чистом питании (КЗ)

Это как раз полярный зверь с порванным кабелем. Но обще описанное вами встречается крайне редко и говорит о том что фактически при КЗ в буфере диска образовался мусор который и был записан в итоге на диск. Вам крупно повезло что вообще хоть что-то читалось.

Я бы предпочел чтобы сервер не загрузился ругаясь на консоль страшными словами о повреждении ФС с предложением
что-нибудь сделать или грузиться на свой страх и риск.

Ну к примеру CentOS или другом linux дистрибутиве такое может быть. Там есть initrd который во многих случаях позволяет загрузиться в rescue mode и как-то починить. Но вообще сравнивать tcp и блочные устройства это тоже самое что сравнить tcp и ethernet.
при КЗ в буфере диска образовался мусор который и был записан в итоге на диск

Судя по объему поврежденных данных буфер диска (это который в диске или RAM? Если второй, то он вряд-ли бы успел куда либо записаться) должен был измеряться гигабайтами, что в том железе было невозможно :) Так что я все-же склонен считать, что посыпались не самые новые диски, а ZFS видимо таким образом «восстановилась» увидев местами битые данные, ну а суммарно — звезды так сошлись (Не часто N-лет работающие PDU вдруг коротят где-то внутри)… Хотя кто его знает. Это сейчас уже не проверишь. Уж пара лет минула с тех пор и нет в тех краях никаких Solaris.

Если бы оно не прочиталось — это было бы значительно лучше, так как проблема была бы сразу видна, а не куча сообщений о битых библиотеках и бинариках.
Судя по объему поврежденных данных буфер диска (это который в диске или RAM? Если второй, то он вряд-ли бы успел куда либо записаться) должен был измеряться гигабайтами, что в том железе было невозможно

Повреждается как правило не сами данные, а метаданные файловой системы. Обычно помогает ручной прогон восстановления, при этом старые данные берутся из копии, почему оно автоматом не умеет остается загадкой. Видимо боятся безвозвратного повреждения данных.

Если было КЗ, железо компа могло не правильно функционировать (та же память), а когда 2+2 может оказаться равно 5 — о какой целостности данных может идти речь?
КЗ убивает намертво. Диск вылетел к черту на компьютеры, не восстановимо из-за КЗ…
Известно ли, что в побитых файлах мусор? То есть есть ли механизм, которым ОС может сказать «вот вам данные, но хрен знает, правда это или нет»?
Конечно. Контрольная сумма у каждого блока. ZFS вам может сказать насколько бита файловая система. Легче от этого вам стало?
Мне кажется, что автор, говоря в целом здравые вещи, путает теплое с мягким.
TCP — унифицирован (одинаково работает с данными). SDS в каждом конкретном случае должно понимать, что именно сломалось (ошибка в банковской транзакции, скорее всего, должна обрабатываться иначе, чем ошибка картинки с котиком), и как это чинить.
TCP занимается передачей «того, что где-то есть», поэтому в случае проблем не страшно — мы знаем, где взять еще. Сторадж может хранить то, чего больше в мире нет, поэтому хочется, чтобы он был надежным.
Пример с TCP — это для контраста. Я хотел показать, что в сетевом стеке все всегда готовы к ошибкам. Код, который не ожидает ошибок не доживает до продакшена.

С блочными устройствами это не так. То есть продакшен код работает с диском, и максимум что может сделать в случае ошибки — свернуться в трубочку. Без обработки, гуманного восстановления и т.д.

Чтобы SDS смогли напоминать SDN нужно, чтобы отношение к блочным устройствам было такое же, как к сетевым.
Я понимаю. Но здесь уже вступает в игру вопрос целесообразности: а готов ли покупатель ПО платить за разбухший в 10 раз код, который умеет восстанавливаться из любой невероятной ситуации? Может, дешевле бэкапиться и ставить более надежные винты в параноидально зеркальные рэйды?
А каковы возможные побочные эффекты подобного интеллектуального поведения? Даже если рассматривать ваше предложение с картами («Да, у нас повредилась одна банковская транзакция по вашей карте...»): а что, если этой транзакцией списывались ВСЕ деньги со счета. Неужели банк должен рисковать и позволить снять их еще раз?

Отношение к блочным устройствам не может быть таким же, как к сетевым. Равно как отношение к подлиннику Моны Лизы не может быть таким же, как к любым ее репродукциям.
То есть вы хотите предполагать, что блочные устройства имеют бесконечную надёжность и никогда не ломаются, то есть не писать sad path, а сразу считать его bad path? Тогда, по мере роста сложности и масштабности проектов, отказы будут становиться всё более болезенными, ставя на колени целые компании.

В моём примере говорилось, что не смотря на то, что транзакция потеряна, сумма по счёту известна. Если же повредится текущая сума по счёту, то её можно высчитать по транзацкциям и предыдущему зафиксированному итогу. Если же и транзакции и зафиксированный остаток повреждены, то да, эта конкретная карта не доступна для обслуживания. Она одна, а не все 20 миллионов, которые были в БД.
Ломается всё. Даже сервера Гугла, порой, бывают недоступны. (:

В любом случае нам приходится опираться на надежность каких-то базовых вещей. Уйду в лирику, но вспоминается фраза: «в трезвом уме (CPU) и здравой памяти (RAM, HDD)». И если что-то не работает, не надо это скрывать, нужно звать санитаров.

Особенность блочного устройства в том, что наличие проблемы, как правило, говорит о его скорой смерти. Поэтому как раз в ответственных системах лучше говорить о проблеме сразу, не маскируя ее. Вылетел из RAID винт? Заменить его немедленно, т.к. его стоимость в 10^X раз меньше ценности данных, которые он хранит.

Не совсем понятен тогда пример: откуда известна сумма, если транзакция, в которой эта сумма менялась, запоролась? Или же у нас есть дублирование: сумма отдельно, лог операций (транзакции) отдельно? Если так, то чем такое дублирование, в котором каждое из хранилищ ненадежно, лучше универсального RAID 1, в котором такие же ненадежные стораджи?

Можно подойти к вопросу с другой стороны: вы пишите, допустим, статью в Word и сохраняете в «ненадежное» хранилище, которое запарывает, пусть, 0.01% всех данных. Как мы можем гарантировать, что сможем эту статью прочесть в том виде, в котором вы ее написали?
Минусую выводы статьи.

Хранение данных — не та область, где допустимы какие-бы то ни было потери.

В теории — 1 убитый байт может сделать все данные (единицы хранения) полностью негодными к использованию. Причем «без вариантов» исправления (на существующем уровне всего стека технологий).

Согласитесь, даже один битый байт в системном файле ОС «живущей» в таком облачном хранилище может привести к чему угодно, включая полный фатальный выход из строя системы в целом.

Ведь все дело в том, какой слой абстракции ответственен за целостность данных. Сейчас за него отвечает устройство хранения — просто потому, что нереально (и экономически не обосновано, в первую очередь) перекладывать этот контроль на уровень приложения. Вы вообще себе представляете контроль целостности всех структур данных всех приложений? И обработку всех возможных повреждений?

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

И задача подсистемы хранения или выполнить команду и доложить об успехе — или честно сообщить, что вышел облом. А никак не строить предположения на тему «а может приложение обойдется без этих ХХ байт?», «А может ему сойдут эти байты их прошлого бэкапа?»
Таким образом, от системы хранения данных требуется бесконечная надёжность?
Прошу прощения, «промахнулся» — ответ ниже в основной ветке.
Вы путаете надежность и честность.

Никто не требует от подсистемы хранения 100% сохранности и правильности данных. Но требуют 100% информации о факте сохранности и правильности данных.

Это не дно и то же!

Если узел недоступен или поврежден — задача подсистемы хранения информировать об этом приложение, возможно, опционально, предложив запрошенную информацию в виде «что смогла — то нашла».

Таким образом, приложения готовые работать с неполными данными — смогут продолжить работу. А не готовые — сообщат о фатальном сбое.

То, что вы предлагаете может стать расширением протокола обмена.
Но вот «тихая» подмена данных (или информации о состоянии данных — при записи например) в рамках существующих протоколов IO никак не допустима.
Но ведь любой жёсткий диск может давать ошибочные данные. Даже известна вероятность — её пишут в техспеках (что-то порядка 10-20). То есть когда это происходит — мы имеем bad path вместо sad path, потому что софт предполагает, что ошибок нет и быть не может. Более того, даже если энтерпрайз использует 520-байтные сектора, то всё равно есть вероятность расхождения контрольной суммы. И никто к этому не готов.

То есть все утверждают «СХД должна быть надёжной, мы полагаемся на её надёжность на 100%». Что не правда, по факту. И от этого возникают всякие чрезмерно гротескные аварии.

Я же предлагаю во-первых признать, что это может случаться, во-вторых превратить из bad path в sad path. В этом случае качество из «всё отлично» и «получили ложные данные с СХД — всё пропало» превратится в плавную характеристику, которую можно будет менять под задачу.
А как по вашему софт «может полагать что в данных есть ошибка»?

Как вы себе представляете обработку на прикладном уровне ответа подсистемы хранения вида «вот вам данные, содержащие ошибку с вероятностью 0,0005%»?

Какова степень полезности такого ответа подсистемы хранения для прикладного уровня?
итого, у нас два сценария: либо бесконечная надежность и bad path, если не получилось, либо sad path, когда мы предполагаем вероятность отказа.

Больше вариантов нет.

Если мы работаем с поддержкой sad path, но на идеальном железе, то это второй случай, только в режиме 《пока не случилось》.

Какой из вариантов рассматриваем?
В системах хранения данные проверяются, как и в TCP. Если блок передался неверно по SATA-шине, он прозрачно для пользователя передаётся повторно. Правильная аналогия того, что хочет автор, перенесённая на сетевой стек, выглядит так: «youtube недоступен? давайте покажем юзеру rutube. авось, не заметит»
Эти проверки базируются на совпадении чексуммы. Вероятность ошибки очень мала, но она изящно компенсируется петабайтами, которые переливаются с/в СХД. Когда эта ошибка происходит — аналогично, выше по уровню никто к этому не готов. При том, что вероятность есть и она не нулевая.

Насчёт рутуба аналогия неверна. Верная — «не удалось отдать содержимое странички, давайте ему отдадим другую страничку с кодом 500». И даже если на сервере случилась беда и он стал отдавать пустые странички с кодом 200, любое уважающее себя http-приложение (тот же aptitude) это прекрасно обработает.
Давайте на примере аудиоплеера. Если не читается mp3-файл, плеер выкидывает message box с ошибкой. Чем это отличается от страницы с кодом 500?
Поправьте меня если я не прав: Смысл статьи сводится к тому, что система в целом должна переваривать ошибки работы с хранилищем и преподносить пользователю результат — «Ваш баланс на нуле, но не беспокойтесь это, возможно, временно :)»? Нет, в целом, если приложение не падает с ошибкой — «Не удалось прочитать данные по адресу 0xЛяЛяЛя» а продолжает работать, то, возможно, это где-то приемлемо…
Все остальные рассуждения сводятся к репликации контролю за ошибками итп, что, собственно, велосипед. Я работал с системами EMC Symmetrics, там надежность зависит от вложенной суммы денег. И это всегда и везде так. Имейте 2,3,4,… дата центра в разных городах, имейте 2,3,4,… оптических линка на каждый, в итоге вы упретесь в надежность вашей ближайшей АЭС, ГЭС, ТЭЦ…
Суть статьи сводится к следующему: перестать полагаться на нижележащие уровни как на идеальные устройства с 100% надёжностью и гарантиями. Как только вместо good path/bad path в IO появится sad path, у IO появится значительная свобода манёвра, а последствия отказа в IO будут не такими разрушительными и массивными.
Это понятно, ноо… И… Может это для нубов?.. Вот пример: Есть некое распределенное хранилище данных, есть некий кластер серверов, и есть некое пользовательское ПО на терминалах. В каком месте и что именно не должно рассчитывать на надежность нижестоящей системы?
Формализирую. Есть, допустим Java EE кластер на котором крутится сервер приложений, который работает с ораклом, который работает с хранилищем. Сервер приложений делает транзакционные запросы к БД и корректно их обрабатывает, оракл делает запросы к хранилищу и тоже корректно ждет успеха или неудачи без паники. Хранилище, в свою очередь, так же работает с физ накопителями. И это реальную существующую систему я описываю. Где профит?
Или это туториал как писать отказоустойчивые приложения?
Вы хотите «как бы мне новые идеи под старый лад приделать».

Скорее схема будет выглядеть так:

Хранение — некая система, обещающая 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%).

Хранение — некая система, обещающая 99.98% аптайма, 99.97% успешного завершения операций IO, 99.998% достоверность прочитанных данных и 99.997% сохранения записанных.

Это означает, что примерно каждый 5000-10000ый запрос превращается в тыкву. (тривиальность с «ошибка — повторить попытку» я пропускаю).

Вообще говоря любой жесткий диск и обычный CD и DVD диск из себя такую систему и представляет. Для коррекции ошибок там используется CRC в различных его проявлениях. Если бы не использовались то показатель их надежности были бы существенно ниже.

СУБД в курсе потенциальных проблем. В её схеме (sql это, граф, или ещё что-то — не важно) отражено то, насколько важны данные. Например, индексы помечены как неважные, данные в разных колонках помечены разным уровнем критичности. Метаданные самой БД крайне важны и имеют высокий показатель устойчивости.

Эм. Как вам сказать в случае tcp это не так. tcp вообще ничего не знает о надежности среды. Фактически предполагается что среда надежна. Как только ВНЕЗАПНО выясняется что среда не надежна, возникли ошибки и т.п. подключаются алгоритмы компенсации ошибок. Как вы себе это представляете на уровне СУБД?
Эм. Как вам сказать в случае tcp это не так. tcp вообще ничего не знает о надежности среды. Фактически предполагается что среда надежна.

Это не верно.
TCP изначально создавался как протокол, обеспечивающий надежность передачи или выявление ошибки (возможно, по таймауту) по среде с принципиальной ненадежностью.
Возможность выявления ошибок, а не их исправления. Работоспособность там обеспечивается банальной повторной передачей пакета и изменением алгоритма отправки. О том что у него там за среда передачи он ничего не знает. К примеру контроль четности у блоков ZFS работает по тому же принципу.
Извините, а Вы сейчас точно мне отвечали?

О том что у него там за среда передачи он ничего не знает.

Ошибаетесь. TCP точно и однозначно знает, что нижележащая среда принципиально ненадежна. В противном случае TCP был бы не нужен.

Дублирование передачи — тоже метод исправления ошибки, по этому TCP имеет функциональность и выявления ошибок, и их исправления, а также механизм предсказания поведения среды, который основываясь на особенностях поведения сетей позволяет так менять свое поведение, чтобы попытаться уменьшить вероятность возникновения ошибки в будущем (контроль перегрузки).
Извините, а Вы сейчас точно мне отвечали?

Да тут просто есть одна вещь. Начали скатываться на достоверность данных у хранилища. Чего как раз таки нет у TCP.

Ошибаетесь. TCP точно и однозначно знает, что нижележащая среда принципиально ненадежна. В противном случае TCP был бы не нужен.

Возможно не надежна. Иначе бы избыточности закладывали больше в том числе и CRC

Дублирование передачи — тоже метод исправления ошибки, по этому TCP имеет функциональность и выявления ошибок, и их исправления, а также механизм предсказания поведения среды, который основываясь на особенностях поведения сетей позволяет так менять свое поведение, чтобы попытаться уменьшить вероятность возникновения ошибки в будущем (контроль перегрузки).

Фишка как раз в том что ни черта он не знает как выяснилось из-за этого начали городить новые алгоритмы работы tcp в случае перегрузки и потерь.
Начали скатываться на достоверность данных у хранилища. Чего как раз таки нет у TCP.

Если данные доставлены получателю, они достоверны с вероятностью отсутствия коллизии контрольной суммы.

Возможно не надежна. Иначе бы избыточности закладывали больше в том числе и CRC

Гарантировано ненадежна. Да, обычно данные доходят, но мы гарантировано знаем, что они могут и не дойти (совсем, а не прийти битые).
Избыточность увеличивает накладные расходы и никак не спасает от повторных передач. Кроме того, в сетях, в отличие от дисков основной процент отказов — недоставка пакета, а любой уровень избыточности кодирования пакета бесполезен, если пакет не был доставлен (даже контрольную сумму у него не посчитать).

Фишка как раз в том что ни черта он не знает как выяснилось из-за этого начали городить новые алгоритмы работы tcp в случае перегрузки и потерь.

Все эти алгоритмы направлена на лучшее предсказание поведения среды, а не на базовые принципы обеспечения надежности.
Если данные доставлены получателю, они достоверны с вероятностью отсутствия коллизии контрольной суммы.

В случае жесткого диска тоже самое.

Гарантировано ненадежна. Да, обычно данные доходят, но мы гарантировано знаем, что они могут и не дойти

При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.

Избыточность увеличивает накладные расходы и никак не спасает от повторных передач. Кроме того, в сетях, в отличие от дисков основной процент отказов — недоставка пакета, а любой уровень избыточности кодирования пакета бесполезен, если пакет не был доставлен (даже контрольную сумму у него не посчитать).

Если пакет дошел битым, то спасает. То что вероятность того что он вообще не дойдет это да.

При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.
Всё-таки не битовый CRC, а коды Рида-Соломона, чтобы получить нужный уровень избыточности и возможность восстановления.
Да конечно.
При гарантированно ненадежных средах использует CRC смотрим на CD и DVD.

Если CD или DVD в момент между извлечением диска из коробки и установкой в привод может бесследно исчезнуть, то да, его можно сравнивать с TCP. Но раз диск есть всегда и нужно только убедиться правильная ли информация считалась или нет, то механизмы типа CRC подойдут, а с учетом того, что диск все-же обычно не исчезает, то я бы его отнес к возможно ненадежным системам (данные в каком-то виде есть, а не может быть есть, а может быть и нет).
Проблема у CD или DVD в том что один и тот же сектор может считываться по разному.
сумма пени — 200 рублей, достоверность 85%

И что должно прикладное приложение делать с этой информацией? Что должен делать пользователь системы, который хотел внести оплату?
Варианта все равно два: либо система работает и мы платим, либо она выдает вот такую хрень (т.е. не работает) и мы не платим (потому что хз — переплачу я или недоплачу с вероятностью 15%).

Если же вы говорите, что в случае низкой вероятности прикладное приложение должно искать в другом месте, то чем это предложение отличается от текущих реализаций дублирования данных (RAID, репликация в удаленное хранилище)?
И да, как выше уже упомянули, куча ошибок не на стороне хранилища а на стороне системы в него пишущей, в этом случае все сводится к транзакциям, надежности пишущей системы и теории вероятности. Для этого и придумали журналируемые ФС. Если мы даже представим себе 100% надежную систему хранения и ФС, остается пользовательское приложение, которое в последний миг своего существования перед полным крахом по питанию итп, хочет записать куда-то псевдоправдивую информацию. Опять теория вероятности…
Я уважаю автора, но статья похожа на какие-то фантазии. Давайте еще CPU и Память будут вести себя как захотят, иногда правильно, иногда нет. Как приложение может относится к неверным данным и как оно узнает, что они неверные? Возможно для какого то узкого круга данных — это возможно. В моем понимании файловая система должна делать попытки читать данные с реплики если они где-то недоступны. Все остальное похоже на космические технологии.
Я не очень люблю эрланг, но его модель с супервизорами всего — это очень и очень правильный ответ на вопрос «а что нам делать, если процессор сделал что-то не так, как мы хотели».

Вообще, всё-таки между IO и процессором+памятью есть большая разница. IO — это периферия. Её ошибки можно обрабатывать (собственно, на уровне контроллера всё обрабатывается правильно). Ошибки процессора совсем другие (т.к. это начинается история класса «кто сторожит сторожей»). В отношении IO следует просто перестать предполагать бесконечную надёжность. Такого не бывает.
Вообще, всё-таки между IO и процессором+памятью есть большая разница.

Так же как и между IO и TCP — большая разница.
TCP — реально может порваться в любой момент.
IO — если сломался, пусть юзер сначала починит, потом продолжит пользоваться машиной.
Вы изложили текущее положение вещей.

А я предлагаю подумать о такой системе, в которой бы «IO может порваться в любой момент». У неё были бы минусы, но были бы и плюсы.
Тоесть вы хотите такое IO для узкого круга данных? А не для всего в целом? Я более чем уверен такие вещи существуют.
Обьясните мне, что должен делать процесс если вместо 4 он прочитал 5. И откуда он может знать, что он хотел получить 4? систему хранения вообще очень сложно сравнить с сетевым стеком, но вы как-то пытаетесь это сделать. Все очень просто, если нет интернета браузер бесполезен, он не выполняет своих функций. Вы хотите чтобы DB зависала, когда не могла читать данные и все спокойно ждали пока данные появятся? Зачем такие подсистемы?
Была еще фраза про повторы чтения, записи, так это есть даже в мало-мальски серьезных системах хранения информации. И хотя там те же рейды, но там и память и ОС своя, и кэши всех уровней и железо. На курсах по EMC Symmetrics, американец препод заикнулся, что они для NASA поставляли железки с сотнями ГБ оперативки. А учитывая их технологии по репликации и восстановлению этого может оказаться достаточно, чтобы заменить ноду целиком без даунтайма.
ЗЫ
Не реклама. Опыт работы 4 года.
ЗЗЫ
Не успел на минуту :)
С EMC не имел дела в боевых режимах, по некоторым их конкурентам могу сказать, что сыпятся они. Саппорт крутит ушки трубочкой и просит «собрать дополнительные данные, когда это случится снова». Такие аварии происходят реже, чем commodities, но в силу того, что на них кладутся большие объёмы данных и нагрузки, последствия оказываются куда более болезненными (чем в случае распределённых решений с easy fall).
У нас вылетало по несколько дисков из массива за раз. Это расплата за нагрузки. Но тут как заплачено так и за.. работает.
Не, в тех случаях это было исключительно и только долбо… на софте вендора.

Но главное — не бывает бесконечной надёжности. А существующий софт на это закладывается, обещая устроить армагеддон в случае мельчайшего отклонения от этого).
Не согласен с этой идеей.

Система с данными — маленькая (конечная по размеру и маленькая) — ОС, файлы, критически важные данные в БД. Хотите бесконечной надёжности — делайте бесконечное дублирование. То что математически бесконечной надёжности не бывает — это спекуляции — всё равно есть вероятность что все сотрудники фирмы умрут в один час от синдрома «внезапной смерти», на континент упадёт метеорит, а во всех процессорах всех компьютеров системы будет сбой.

Если у системы есть какой-то огромный объём данных, сохранность которых не важна — храните их на отдельных устройствах, в специальных файловых системах, в специальных СУБД, API которых позволят ответить «этой записи больше нет и не будет» и не упасть.

Зачем сюда приплетать весь стек существующих технологий, стандартов, POSIX API, файловые системы и СУБД?
Затем, что если бы из «синдрома внезапной смерти» небольшие ошибки в большом массиве данных обрабатывались бы с небольшими последствиями, то вместо «либо пан, либо пропал» мы бы получили плавный показатель «качества» (частоты ошибок), который бы открыл массу возможностей по построению «чаще всего хорошего» сервиса.

Предполагая любой отказ СХД как аварийный, мы автоматически закладываемся на какое-то количество аварий (которых не ждём) и предотвратить которые можно только «бесконечным дублированием».
Не бывает небольших последствий в серьезных проектах. Лучше какой-то краткий даунтайм и гарантия достоверности и полноты данных, чем сообщение бухгалтеру, что его платежка на $1млн, «скорее сохранилась чем нет»
… После того, как даунтайм станет долгим, дирекция может прийти к выводу, что 90% вероятность успеха платёжки на 1% от дневного оборота фирмы не такая уж большая расплата за продолжение работы.

Кстати, гарантий достоверности всё равно нет. Повторю снова, ни один вендор не гарантирует сохранения данных в неизменном виде. Просто потому, что данные могут побиться так, что пройдут через чексуммы. Так что некоторая вероятность ошибки в системе уже есть, а вот её обработки — нет.
Так подождите. Известно, что чексумма в ip-пакете занимает 16 бит. Это существенно (на 16 двоичных порядков) ниже, чем типичная CRC32, которой защищены сектора на диске (не говоря уже об экзотике с 520-байтными секторами, где под восстановление отводится 64 бита).

Если вы утвердаете, что вероятности незамеченного сбоя на дисках недопустимо велики, придётся признать, что сеть в таком случае чудовищно неустойчива, на несколько порядков хуже себя ведёт.
У любой системы есть некоторое количество данных, которые критически важны (код программы, учётные записи пользователей итд),
работать с ними через API, которое может ответить что данных больше нет — нецелесообразно, так как обработка такой ошибки всегда будет одинаковая — завершение программы.

Их всё равно нужно дублировать.

Я считаю что:
— Большинство сущностей в программе приходится на эти данные (90% сущностей занимает 10% данных по объёму — звучит правдоподобно?).
— Большая часть кода программы обрабатывает эти данные (на каждую сущность нужно написать одинаковое количество кода)
— Размер этих данных мал (в нашем примере 10%)

Уменьшение размера таких данных с гигабайта до мегабайта (к примеру) ничего не принесёт (вплане экономии на дублировании).
Т.к. переписывать 90% кода программы, на новый API, таким образом что оно интелектуально пытается обрабатывать ситуации «запись о юзере уничтожена»,
«файлы программы уничтожены» ради экономии на дублировании гигабайта данных не целесообразно.

Если речь идёт о системе с огромным количеством данных — то большая часть этих данных (по объёму) обрабатывается очень маленькой частью программы.
Вы предлагаете «в новой версии сделать так, чтобы данные снова были достоверными на 100% и работать ка работали». А я хочу сказать, что надо учиться работать в условиях заданной достоверности.

Как я уже говорил, даже в существующих системах вероятность молчаливого искажения данных не нулевая. Но на это все забивают, потому что «редко бывает». А вместо «забивать» — надо научиться обрабатывать без завершения программы.

В этом случае СХД с пониженными показателями надёжности могут открыть целые новые пласты применяемости.
Я говорю что в 90% кода не может быть никакой другой обработки ошибок кроме как завершить программу, либо такая обработка там экономически не целесообразна (т.к. дублирование гораздо проще).
Блин, у меня ощущение, что аргументы не слышат. Дублированная информация всё равно не даёт 100% гарантии неизменности. То есть проблема всё равно остаётся и её невозможно решить, по крайней мере в рамках существующих технологий и существующей квантовой физики.

Насчёт «не может быть никакой другой обработки» — не верю. Допустим, почтовый клиент (оффлайновый). Да, данные для доступа — критические. Остальное? Ну да, показываем письмо с пометкой «содержимое письма доступно с достоверностью 99.9%, что ниже порога в 99.99%, ожидаемого для этих данных». Это же лучше, чем сказать, что письмо недоступно, или вообще, объявить всю почтовую базу к чёрту нерабочей? Даже данные для доступа — лучше попытаться с логином и паролем у которых 30% достоверность, чем сразу же сказать «нету паролей и логинов, и вообще, файла конфигурации нет, ничего нет».

Другой пример — шелл (юниксовый). Он читает history, там часть данных с низким процентом достоверности. Что делать? Можно эти данные показывать с пометкой о недостоверности. Или исключить из автоподстановки. Или вообще, игнорировать.

(Я специально пропускаю вкусные случаи с мультимедиа).
Дублированная информация всё равно не даёт 100% гарантии неизменности

Я написал выше про синдром внезапной смерти — исчезающе малые вероятности вообще неинтересны никому. Т.к. вероятность отказа всёго остального гораздо больше.

Это же лучше, чем сказать, что письмо недоступно, или вообще, объявить всю почтовую базу к чёрту нерабочей?

Храните отдельно огромное колво писем, в отдельной СУБД, на отдельном устройстве. А всё остальное что относится к программе (метаданные писем) не трогайте, храните по старому и дублируйте.

Другой пример — шелл (юниксовый). Он читает history, там часть данных с низким процентом достоверности.

history очень мало занимает, гораздо проще дублировать её, чем менять весь POSIX API. Или даже, чем просто писать новый shell. И даже, если писать новый shell, по другим причинам, проще дублировать, чем обрабатывать такие ошибки.
Ок, я вашу позицию понял. Всё хорошо, нам надо использовать супернадёжные супердорогие суперсхд, а если они навернутся, то саппорт объяснит, как в следующий раз собрать статистику.

В индустрии СХД всё хорошо и никаких проблем нет, а если и есть, то можно приписать два нуля и на ближайшие пол-года проблем снова не будет.

Всё интересное я уже услышал, дальше мы будем просто спорить о том, «надо или нет».
Взать, например, твиттер.

Там большие данные — твиты, и, наверное юзеры. Всё.

Как Вы думаете сколько таблиц в БД у твиттера? Две? Врядли. Я думаю 100 (или больше)
Как Вы думаете, сколько по объёму данных занимают оставшиеся 98+ таблиц? Я думаю очень, очень мало.

Как Вы думаете, что делает 99.9% кода твиттера. Читает твиты/юзеров из БД и решает что делать если твит не прочитался?
Очень сомневаюсь, скорее всего он имеют дело с твитом который уже прочитался. А чтение твита из базы происходит только в одном месте.
Или этот код имеет делао с 98 остальными таблицами и уже прочитанным твитом.

Так зачем эти 99.9% кода и БД переписывать на новый, «отказоустойчивый» API?
По сути, вопрос сводится к степени зрелости технологии хранения данных, по отношению к технологии их передачи. То есть, можем ли мы более высокую степень зрелости софта в области коммуникаций революционно проецировать в проектирование софта в области хранения и обработки данных.

А это уже, на мой взгляд, вопросмконкретных спецификаций. На уровне парадигмы трудно даже доказать или опровергнуть большую зрелость коммуникаций перед хранением и обработкой.

Но, направление исследований, на мой взгляд, задано весьма точно и ясно. Возможно, смена сквозной парадигмы хранения и обработки данных с концепции «все данные особенные и сохраняются по умолчанию на века, пока я не затребую их перемещение илииудаление» на концепцию «интеллектуальное распознавание степени важности каждого фрагмента информации» приведет к более значительным изменениям архитектуры систем обработки и хранения с фунционально-ориентированных на инфраструктурно-ориентированные.

В конечном итоге, мне проще использовать одну команду «найти данные», когда потоки передачи определяют и место и способ их сохранения и обработки, с учетом их ожидаемой доступности и производительности (а так же изменчивости и в доступности, и в производительности).

Мне кажется более разумным специфировать востребованность данных при каждой их передаче, чтобы система хранения выбирала место для их хранения, а так же получать информацию о процессе поиска данных, асинхронно.

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

То есть, я полагаю, что типизировать данные в целях их интеллектуального хранения и обработки — можно, но не столько по их содержанию, сколько по их связанности, востребованности, вариабельности, актуальности, формализованности и т.п.
> Это вместо «Неизвестная ошибка. Операция по карте невозможна, обратитесь в службу поддержки карт вашего банка».

Вот он, момент истины. Теперь смотрим глазами со стороны банка: была команда, которая написала некий банковский софт. Точнее, некую часть софта в «большом» понимании этого слова: баланс ведь не считается как самоцель, он встроен в некую цепочку операций.

Однажды банк обнаруживает, что софт тормозит/глючит в мере, которая уже не позволяет старый с любыми костылями использовать (ибо, если костыли есть еще куда ставить, проще поставить именно их — минимизируем число потенциальных точек возникновения новых гемороев, т.к. старый софт, худо-бедно, уже известно, где и как может глючить). Кому поручают разработку? Правильно, той же команде, которая написала предыдущий (да, как раз тормозящий/глючащий) софт. Команда же берется за дело, неся в себе старые наработки и старые свои шоры, так что получаем что-то, в чем опять нет революционных изменений (что, для банка, даже и неплохо).

Теперь представим, что будет, если команде этой дали задачу переписать их ПО под SDS. В лучшем случае, если они никогда SDS не использовали, они просто перелинкуют с новой lib-ой, SDS обеспечивающей, и повесят взятый из документации хук вида «если что-то не так в любом месте работы с SDS -> выкидываем табличку „приплыли!“»

По уму, конечно, эксепшены надо ловить и обрабатывать в зависимости от серьезности ситуации («ошибка при чтении файла -> пробуем перечитать; если N попыток перечитать дают ошибку, думаем, как восстановить данные и полагаем себе вернуться к этому файлу для восстановления данных в нем позже», «ошибка при записи временного файла с выборкой из БД -> создаем другой файл; если M таких попыток не удалось, пробуем другой алгоритм расчета, без временных файлов» — смысл в том, что от ФС логика должна перейти к работе именно с данными, и логика хранения и восстановления должна поменяться в сторону «что бы ни случилось, мы знаем, по каким следам восстановим то же, или предыдущее состояние данных»). Но чтобы переписать прикладное ПО под такие изменения, нужно а) быть достаточно умным, чего в in-house командах может и не случиться (они уже показали свой уровень, написав само ПО — с чего вдруг будет прыжок на порядок-другой в сложности подхода?), и б) нужно понимать, как извлечь из SDS максимум, не сведя работу с ним к очередной эмуляции DAS (в лучшем случае — NAS).

И что-то мне кажется, что написанного выше вполне хватит рук-ву банка, чтобы сказать — «раз есть риск потери данных именно из-за изменений в схеме, то ну его, это изменение». Ибо для банка ввод SDS (а также ЖК-мониторов вместо ЭЛТ, ввод ядерного реактора вместо генератора во дворе — тут можно любое «новшество» указать) не самоцель, а лишний геморой в уже отлаженном процессе жизни, с потенциально высокой ценой ошибки. Не все на такое пойдут легко, а «тяжело» идти… Так кто сказал, что SDS не сдуется через пяток лет, вытесненный очередным порождением голов маркетологов?
SDS не сдуется, просто потому, что «сдуться» софт не может. Вы хоть раз видели проект, в котором от релиза к релизу число строк уменьшается?

Например, виртуализация — сколько лет баззворду? И где она сейчас?
Какая классная реклама Нетапа и Оракла :)
Но учитывая что присутствуют жалобы на Неттап, получается невольная пропаганда технологического превосходства Оракла :)

Амаро, а к вам еще Nutanix в гости не ездил? Впечатлениями не поделитесь?
Реклама нетаппа? Очень смешно. Их хоронилища данных к реальной нагрузке близко подпускать нельзя. Уютненькое болотце мелкого энтерпрайза — всегда пожалуйста. Хайлоад и нетапп несовместимы.

Насчёт Nutanix — «к нам», это на Кипр?
А что из нетаппа вам давали на погонять? Если не тайна.

Насчёт Nutanix — «к нам», это на Кипр?
Не, это к вам в Селектел. Если че я про этих граждан www.nutanix.com/
Я уже 4 месяца не имею никакого отношения к селектелу.
Ну раз тайна — ок.
Длинный текст, полный поэтических оборотов, которые, на мой взгляд, мешают восприятию. По крайней мере, я не смог составить по его прочтении четкого представления о незнакомом термине software defined storage.

Если речь идет о построении распределенных и масштабируемых хранилищ данных, то «самая большая, сложная и неприятная проблема» — это, если я правильно понял, «смерть» отдельного узла — не кажется мне проблемой. Если мы позволяем софту решать, где и что хранить, то он же может отслеживать состояние узлов и давать сигнал о нарушениях в их работе или даже падениях.
Осенью слушал доклад о том, как организовано хранение вложений на outlook.com: они как раз используют commodity-серверы в нескольких разбросанных по миру дата-центрах, хранят по несколько копий каждого файла, создают новые копии при падении узлов и т.п.
Точно так же можно реализовать софтом «возможность писать в середину файла» — если мы говорим о самой идее, а не о конкретной реализации в форме Swift.

По поводу «от дискового стека ожидают бесконечной надёжности», то наивно ожидать её от чего-либо. Правильнее, на мой взгляд, поступать как это принято в упомянутых Вами Erlang/OTP, когда упор делается не на предотвращение ошибки любой ценой, а на скорейшее восстановление работоспособности.
Я попытался обдумать поднятный вопрос с другой стороны.

Почему сложно сравнивать сетевую среду и среду хранения? Потому что сравнивая, предполагается, что сбои в сетевой среде локальны и после прекращения помехи данные всё-таки пройдут. А вот диски такие, что если умерло, то уже навсегда.

Поэтому справедливо рассматривать такую сеть, где сбой — это обрыв провода, без возможности восстановления в разумное время. И тут у сетей есть что предложить — делаем петли и IP находит альтернативный маршрут. Самое главное, что эта фича доступна в любой системе, не требует подключения прикладных программистов и решается без особых усилий, все технологии и протоколы давно известны.

Но в хранении есть отличная аналогия — торренты, и протокол DHT. Аналогично можно сопоставить ID ноды и вероятность нахождения на ней информации с хешем H. Любая нода может хранить некоторую информацию с ненулевой вероятностью, но на некоторых нодах вероятность нахождения искомого блока близка к 100%. Есть конечно проблемы с латентностью и согласованностью данных при репликации, но последние некоторым образом решены в bitcoin. Вот и ответ! Достаточно разработать протокол DHT-хранилища, и пусть кому нужна надёжность, пользуются готовыми реализациями.

Понятно, что в реальности мало кто делает избыточные сети, большинство сетей — звезда (дерево), обрыв провода фатален и автоматическому восстановлению не подлежит (как и сдохший диск). Аналогично и с хранилищами. Кому надо — заморочится с DHT.
Когда я только начинал работать в банковском IT, старшие товарищи мне очень доходчиво объяснили, что в этой сфере лучше получить втрое больший даунтайм, чем рисковать потерей целостности данных. Т.е. лучше честно сказать «чуваки, с момента X — перезавести всё по-новой», чем допускать шанс расхождения хотя бы в одну копейку, потери хотя бы одной операции.

В примере с карточкой — это не только обслуживание клиента. Это возможно неправильная итоговая сумма, которая выгрузится из процессинга в АБС, это возможно неправильные внешние платежи, которые может не удаться вернуть, это возможно неправильная отчётность, за которую у банка могут отобрать лицензию.

И не зря в СУБД есть всего два состояния — consistent и inconsistent. Т.е. — мы либо верим тому, что нам дали, либо не верим. Промежуточные случаи должны быть доступны только в maintenance-режиме, когда специалист может руками проверить и решить — верны данные или нет.

И сравнение с процессом передачи данных тут, на мой взгляд, некорректно. Критичная разница: передаваемые данные всегда можно передать повторно; потерянные при сохранении (незаписанные, нечитаемые etc) данные — потеряны навсегда.
Amarao прав, хотя и другие доводы верны. С трудом поймал мысль, которая крутилась в голове при прочтении поста + комментариев.

Собственно, текущая парадигма со 100% надежностью — эта наша реальность и в ней есть диски, блочные устройства, файловые системы. Не надо пытаться изменить существующую реальность, оставьте её как есть. Как и приводили в примерах, множество данных правильно хранить именно в такой парадигме.

Просто в новой парадигме не надо использовать старые понятия. Называйте в новой парадигме СХД — вероятностная система хранения данных. Не файл, а объект или документ. Не блочное устройство, а «узел хранения». Тогда уйдет непонимание «зачем это» и придет понимание «нужен новый софт».

Ещё один момент не был озвучен в слух. В новой парадигме, программа записывая данные должна указать с какой надежностью необходимо хранить именно этот объект. Что тоже невозможно в нашей реальности.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории