Мой клиент производит медицинское устройство, которое выполняет различные измерения данного образца и записывает результаты в базу данных. Объем генерируемых данных относительно невелик.
В текущей конфигурации каждое устройство имеет свой собственный компьютер, и на этом компьютере работает экземпляр сервера базы данных. Устройства не подключены к сети.
Клиент хочет модифицировать устройство таким образом, чтобы около пятидесяти из них можно было подключить к локальной сети.
В устройствах используются различные расходные материалы, партии которых пронумерованы и после использования не могут быть использованы повторно. Эти номера партий записываются в базу данных при измерении пробы. Это требование примечательно, поскольку в текущей конфигурации устройство не имеет возможности узнать, использовались ли расходные материалы другим устройством. В предлагаемой конфигурации сети ожидается, что каждое устройство будет иметь немедленный доступ к информации о расходных материалах, используемых другими устройствами.
Устройства также должны отслеживать количество различных химикатов, которые используются в процессе тестирования. Каждая бутылка химиката пронумерована и имеет штрих-код. Когда бутылка вставляется в машину, машина считывает базу данных, чтобы определить, сколько жидкости было израсходовано из бутылки. Ожидается, что пронумерованная бутылка может быть вставлена в любую машину, и машина сможет точно оценить количество жидкости в бутылке.
Клиент хочет порекомендовать, какую из двух архитектур следует использовать:
1.) Каждое устройство будет записывать данные в свою локальную базу данных, как сейчас. Программное обеспечение для синхронизации будет установлено на каждом устройстве, и синхронизация будет выполняться в режиме реального времени. Каждое устройство будет периодически передавать контрольный сигнал (были предложены интервалы от 1 до 5 минут), и это контрольное сообщение будет содержать контрольную сумму CRC. Каждое устройство в сети будет слушать сердцебиение. Устройство инициирует синхронизацию, если контрольная сумма контрольного пакета контрольного сигнала отличается от его собственной. Программное обеспечение синхронизации должно быть внешним по отношению к программному обеспечению, запускающему тесты, и независимым от него. Следовательно, теоретически возможно, но маловероятно, что устройство будет работать, когда оно отключено от сети или пока не запущено программное обеспечение для синхронизации.
2.) Сервер базы данных на каждом устройстве будет удален, и вместо него будет использоваться сервер базы данных.
Клиент обеспокоен тем, что если используется сервер базы данных, все устройства в сети станут непригодными для использования в случае отказа сервера. Эффективно ли снижает этот риск использование одноранговой топологии? Другими словами, если один одноранговый узел в сети выходит из строя, будет ли это обычным делом для всех остальных узлов? Связаны ли с любым подходом какие-либо опасности или преимущества целостности данных?
Изменить в ответ на ответы от iag и MikeyB:
Я вижу, как мой вопрос оставляет место для двусмысленности, поэтому вот он снова, надеюсь, сформулирован более осмысленно.
В среде клиент-сервер отказ сервера является катастрофическим, потому что в случае отказа сервера все клиенты отключаются. Учитывая эту конструктивную особенность, почему некоторые очень важные информационные, инвентарные, финансовые и медицинские системы реализуют архитектуру клиент-сервер, а не одноранговую?
Учтите, что я НЕ спрашиваю: «Как уменьшить риск отказа сервера?» Я ЕСМЬ спрашиваю: «Является ли архитектура одноранговой сети эффективным способом снижения риска отказа сервера?» Почему или почему нет? Влияет ли топология сети на дизайн приложения? Вносит ли одноранговая связь возможность повреждения данных или неоднозначных результатов?
Является ли следующий реальный пример того, что может происходить в одноранговой сетевой топологии?
DeviceA, DeviceB и DeviceC - это компьютеры в одноранговой сети, которые совместно используют общий агент, называемый агентом R. Каждый раз, когда одноранговому узлу необходимо проверить, сколько R доступно, он синхронизируется с другими одноранговыми узлами и вычисляет доступность. Однажды около 13:00 лаборант вставляет бутылку R в DeviceB. DeviceB немедленно синхронизируется с DeviceC и подтверждает, что DeviceC никогда не потреблял R из этой бутылки. Однако DeviceA не отвечает на эхо-запросы с полудня. Может ли DeviceB надежно рассчитать количество R в баллоне?
Я инженер-программист и буду писать приложение, которое позволит этим устройствам обмениваться данными по сети. Честно говоря, у меня есть мнение по поводу вопроса, который я задаю, однако мой клиент не доверяет моему опыту. Я хочу узнать об опыте моих коллег, поэтому мой пост здесь. Я не хочу вкладывать слова в чьи-то слова, поэтому я стараюсь не быть максимально общим и все же объяснять проблему.
Я вижу здесь много возможных проблем.
Во-первых, вам на рассмотрение были представлены два незавершенных решения, которыми сложно управлять в том виде, в котором они представлены, и которые не допускают ошибок.
Во-вторых, вы, кажется, не понимаете, как создавать службы данных. Это больше беспокоит.
Я не уверен, какова ваша ситуация взаимодействия с описанной средой, но я бы рекомендовал ничего не делать и иметь более точные определения требований и лучший план для их достижения, чем случайные коробки с множеством баз данных без резервных копий (живых или иных).
Если вас беспокоит лабораторный инвентарь, есть лоты программного обеспечения, которое решает эту проблему. Если вы работаете с проприетарными странностями от поставщика, установите их экологические требования, найдите способ получить доступ и сохранить эти данные с некоторой степенью уверенности. Уверяю вас, что это уже было сделано раньше.
Ничего из этого не произойдет из-за размещения расплывчатых вопросов исключительно на этом форуме. Если вы чувствуете себя не в своей тарелке, вам следует выделить несколько часов консультанта, чтобы помочь вам.
В данной среде представляется важным наличие единого источника информации для данных. Это правда? Мы не можем сказать.
Всегда будут точки отказа - вам нужно проектировать, исходя из того, что приемлемо.
Вы должны придумать ограничения вокруг своей системы. Должен ли быть единый источник данных? Может ли устройство использовать инвентарь в автономном режиме? Можно ли допустить отказ одного сервера? Может ли система некоторое время работать в режиме «только чтение»?
Как только у вас появятся эти ограничения, вы обнаружите, что как проектирования системы возникает из-за ограничений.
Одноранговая архитектура программного обеспечения может быть эффективным и отказоустойчивым способом распространения информации между узлами, если у вас уже есть избыточность в базовой сети.
Одноранговая архитектура также может защитить вас от потери данных, если данные хранятся на нескольких узлах. В типичных одноранговых системах узлы хранят данные из-за собственных интересов. Вам нужно другое, поскольку вы хотите, чтобы они хранили данные из-за соблюдения политики, а не индивидуальных интересов.
Каждый узел, хранящий все, что он когда-либо видел, прост, пока объем данных ограничен. Но хранить все может быть непрактично из-за места для хранения (или в некоторых случаях из-за требований законодательства). Тогда нужно быть осторожным с тем, что удалить, а что оставить. Это одна из главных ошибок.
Но все это никак не решает проблему целостности и непротиворечивости данных. Если вы просто переключитесь на одноранговую архитектуру, не задумываясь о правильности данных, то надежность системы в этом отношении снизится. Просто есть намного больше мест для внедрения коррупции.
Чтобы реализовать такое решение, вам нужно выяснить, как проверить целостность части данных.
Легче всего иметь дело с фрагментом данных, который может быть обновлен только одним конкретным узлом в системе. Но вы все равно должны задать вопрос о том, каково допустимое поведение системы, если этот узел начинает плохо себя вести. Одной криптографической подписи узла для каждого обновления недостаточно, если он может ошибочно отправить подписанное обновление, чтобы удалить все, что было написано ранее, или отправить несколько подписанных обновлений, которые не согласны с тем, каково новое значение данных. Опять же, простой подход - сохранить все и потребовать ручного вмешательства, если обнаруживаются конфликтующие обновления. Но если вам когда-либо понадобится какое-либо автоматическое решение, которое будет принято на основе данных, этого недостаточно.
Если только один узел может обновлять данные, но у вас есть строгое требование о том, чтобы все остальные соглашались, какое обновление он выполнял, тогда проблема становится немного сложнее.
Решение этой проблемы все еще не очень сложно, и оно дает хорошее представление о методах, используемых для решения таких проблем целостности данных.
Узел, которому разрешено отправлять обновление в первую очередь, может выйти из строя, что предотвратит повторное обновление данных. Но до тех пор, пока он отправляет согласованное обновление, он в конечном итоге будет последовательно храниться во всей одноранговой сети.
Может показаться, что большое количество подписей, необходимых для каждого фрагмента данных, потребует много места для хранения. К счастью, этого можно избежать с помощью метода, известного как пороговые сигнатуры.
Но если вы хотите заменить базу данных, недостаточно, чтобы один узел мог обновить часть данных. У вас есть несколько узлов, которым разрешено обновлять одни и те же данные, но вам требуется, чтобы вся сеть согласовывала, кто был первым. Здесь на сцену выходит византийское соглашение.
Решение этой проблемы на порядок сложнее, чем то, что я описал выше. Но я могу упомянуть несколько ключевых результатов, о которых следует знать.
Вы должны выбрать между двумя моделями отказа. Вы можете предположить, что отказавший узел просто прекращает взаимодействие и никогда не отправляет ни одного поврежденного сообщения. Эта модель требует меньше оборудования, но достаточно всего одного перевернутого бита, чтобы вывести систему из строя.
В качестве альтернативы вы можете выбрать модель византийского отказа, которая позволяет отказавшему узлу делать что угодно, и система все равно выживет. Чтобы терпеть t
отказов в этой модели, нужно 3t+1
узлов всего. Другими словами, чтобы выдержать один отказавший узел, вам нужно четыре узла. Если у вас всего 10 узлов, можно допустить отказ 3 узлов.
Вы также должны выбрать между синхронной или асинхронной моделью связи. Синхронное общение означает, что вы делаете предположения о сроках общения. Если пакетам требуется больше времени для доставки к месту назначения, чем предполагалось, система выходит из строя. Более того, если узел выходит из строя, вы должны дождаться максимально допустимой задержки, прежде чем система сможет продолжить работу.
Асинхронные модели усложняют разработку программного обеспечения, но имеют ряд явных преимуществ. Вам не нужно ждать тайм-аутов, вам просто нужно дождаться, пока вы не услышите более чем 2/3 узлов, прежде чем вы сможете продолжить, это может быть намного быстрее, чем синхронная модель, где вам нужен большой тайм-аут.
Еще одним недостатком асинхронной модели является то, что она должна быть случайной. Время работы алгоритма становится стохастической переменной без ограничения наихудшего случая. Теоретически существует вероятность того, что обновление займет бесконечное время, но можно показать, что вероятность этого равна нулю. И на самом деле можно показать, что среднее количество циклов обмена данными постоянно. Для меня это выглядит намного выгоднее по сравнению с синхронной моделью, которая может выйти из строя в случае задержки связи.
Как вы понимаете, создание такой системы - непростая задача. Для реализации этого требуются целенаправленные усилия разработчиков. Более того, программная ошибка может вывести систему из строя. Если выйдет из строя менее трети узлов, система выживет. Но если в программном обеспечении есть ошибка, вы вполне можете установить это программное обеспечение более чем на треть узлов.