NoSQL: что означает, что MongoDB или BigTable не всегда доступны

Читая Визуальное руководство по системам NoSQL Натана Херста, он включает треугольник CAP:

  • Cпостоянство
  • Aдоступность
  • Partition Допуск

введите здесь описание изображения

SQL Server — это система AC, а MongoDB — система CP.

Эти определения взяты из профессора Калифорнийского университета в Беркли Эрика Брюэра и его выступления на PODC 2000 (Принципы распределенных вычислений):

Доступность

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

Что в контексте MongoDB или BigTable означает, что система недоступна?

Вы пытаетесь подключиться (например, через TCP/IP), а сервер не отвечает? Вы пытаетесь выполнить запрос, но запрос никогда не возвращается или возвращает ошибку?

Что значит означает быть недоступным?


person Ian Boyd    schedule 07.09.2011    source источник


Ответы (2)


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

Предположим, что у вас есть 3 узла, A, B и C, в гипотетической распределенной системе. A, B и C работают в своей собственной стойке серверов с двумя коммутаторами между ними:

[Node A] <- Switch #1 -> [Node B] <- Switch #2 -> [ Node C ]

Теперь предположим, что указанная система настроена таким образом, что ГАРАНТИРОВАННО любая запись будет осуществляться как минимум на 2 узла, прежде чем она будет считаться зафиксированной. Теперь давайте предположим, что коммутатор № 2 отключен, а какой-то клиент подключен к узлу C:

[Node A] <- Switch #1 -> [Node B]                 [ Node C ] <-- Some client

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

Я бы добавил к этому, что некоторые базы данных NoSQL допускают очень динамичный выбор атрибутов CAP. Cassandra, например, позволяет клиентам указывать количество серверов, на которые должна быть направлена ​​запись, прежде чем она будет зафиксирована для каждой записи. Записи, идущие на один сервер, обозначаются как «AP», записи, идущие на кворум (или все) серверы, — это больше «CA».

РЕДАКТИРОВАТЬ - из комментариев ниже:

В MongoDB вы можете иметь конфигурацию master/slave только в наборе реплик. Это означает, что выбор AP или CP осуществляется клиентом во время запроса. Клиент может указать slaveOk, который будет читать из произвольно выбранного подчиненного устройства (у которого могут быть устаревшие данные): mongodb.org/display/DOCS/…. Если клиент не согласен с устаревшими данными, не указывайте slaveOk, и запрос будет передан мастеру. Если клиент не может связаться с мастером, вы получите сообщение об ошибке. Я не уверен, что именно это будет за ошибка.

person Chris Shain    schedule 07.09.2011
comment
Мне кажется, что ваш пример с A-B-C узлами относится к доступной и устойчивой к разделам системе, которая не обязательно непротиворечива ( т. е. узел C доступен, но не Cпостоянен). Какой должна быть диаграмма для системы, которая непротиворечива и устойчива к разделам, но не обязательно доступна? - person Ian Boyd; 08.09.2011
comment
Он недоступен для записи, поскольку невозможна непротиворечивая запись. Он недоступен для чтения, потому что последовательное чтение может быть выполнено на узлах A и B, и это любое чтение на C не обязательно будет возвращать текущее правильное значение (согласованно зафиксированное). - person Chris Shain; 08.09.2011
comment
Доступная и устойчивая к разделам система была бы такой же, как и выше, если бы записи требовались только для перехода к одному узлу. Это не было бы согласованным, потому что в этом случае, даже в случае раздела, все узлы были бы доступны для записи и чтения, но записи и чтения не были бы согласованными (вы могли бы писать на узле А, а я мог бы написать другое значение на узле B). - person Chris Shain; 08.09.2011
comment
Извините, 1-й комментарий выше должен гласить: он недоступен для чтения, потому что согласованная запись может быть выполнена на узлах A и B, и это любое чтение на C не обязательно будет возвращать текущий правильный ( Постоянная приверженность) значение - person Chris Shain; 08.09.2011
comment
Вы говорите, что база данных не будет Aдоступна при сбое связи между узлами? База данных поймет, что не все узлы обмениваются данными, и не позволит пользователю читать или писать из базы данных? Как этот отказ в доступе будет представлен пользователю? - person Ian Boyd; 08.09.2011
comment
Конкретная реакция на эту ситуацию зависит от реализации системы. Некоторые системы допускают несогласованное чтение в сценарии AP (например, Cassandra), другие настраиваются. Посмотрите эту замечательную серию статей о настраиваемости Mongo в этом отношении: blog.mongodb.org/post/498145601/ - person Chris Shain; 08.09.2011
comment
я прочитал этот пост, и мы не совсем добираемся до ответа на мой вопрос. Из сообщения Для класса A нам нужно ослабить ограничения согласованности. Что, если мы не будем ослаблять согласованность? Что, если мы ослабим А? Что происходит, когда MongoDB настроен на согласованность, а не на доступность? Что происходит, когда я пытаюсь прочитать значение в MongoDB, настроенном для CP, жертвуя A, и возникает внутреннее несоответствие? Используя синтаксис этого поста, что происходит, когда я запускаю R(x)? Возвращает ошибку? Остается ли он в тупике до тех пор, пока не будет восстановлена ​​согласованность? Это прерывает мое соединение? - person Ian Boyd; 08.09.2011
comment
Используя цитируемое определение доступности, Доступность означает именно это — услуга доступна (работает полностью или нет, как указано выше). Когда вы покупаете книгу, вы хотите получить ответ, а не какое-то сообщение браузера о том, что веб-сайт некоммуникабельный. Ну, MongoDB — это не веб-сервер, это база данных. Недоступный веб-сервер возвращает 500, если сервер недоступен. Что возвращает MongoDB, когда база данных не согласована? я знаю, что он не возвращает 500, так как это не веб-сервер. - person Ian Boyd; 08.09.2011
comment
Со страницы, которую я процитировал и связал; Одно решение: Отказаться от доступности Это обратная сторона медали, допускающей отказ от разделов. Обнаружив событие раздела, затронутые службы просто ждут, пока данные не станут согласованными, и поэтому остаются недоступными в течение этого времени. Управление этим может стать довольно сложным для многих узлов, поскольку повторно доступным узлам требуется логика для корректной обработки возврата в оперативный режим. Можно ли настроить MongoDB/BigTable/Hypertable/Hbase/Terrastore/Scalaris/Berkley DB/MemcacheDB/Redis для сделай это? Являются ли они или могут быть CP системами? - person Ian Boyd; 08.09.2011
comment
В MongoDB вы можете иметь конфигурацию master/slave только в наборе реплик. Это означает, что выбор AP или CP осуществляется клиентом во время запроса. Клиент может указать slaveOk, который будет считываться из произвольно выбранного подчиненного устройства (у которого могут быть устаревшие данные): mongodb.org/display/DOCS/. Если клиент не согласен с устаревшими данными, не указывайте slaveOk, и запрос будет передан мастеру. Если клиент не может связаться с мастером, вы получите сообщение об ошибке. Я не уверен, что именно это будет за ошибка. - person Chris Shain; 08.09.2011
comment
Cassandra похожа на MongoDB с точки зрения согласованности, но согласованность определяется писателем (путем указания количества узлов для фиксации), а не читателем. В Cassandra запрос никогда не завершается ошибкой из-за (не)согласованности, но вы можете получить устаревшие данные, если автор этих данных указал небольшое количество узлов фиксации, и данные еще не были переданы другим узлы. С другой стороны, HBase всегда непротиворечив — если данные не могут быть записаны на достаточное количество узлов для обеспечения настроенного коэффициента репликации, запись завершается ошибкой. - person Chris Shain; 08.09.2011
comment
Если клиент не согласен с устаревшими данными, не указывайте slaveOk, и запрос будет передан мастеру. Если клиент не может связаться с мастером, то вы получите ошибку. Отлично, оформите это в виде ответа, и мы сами его и приняли! - person Ian Boyd; 08.09.2011

Теорема CAP применима к распределенным компьютерным системам. MongoDB поддерживает две различные формы распределенных вычислений: сегментирование для горизонтального масштабирования и наборы реплик для аварийного переключения/высокой доступности. Оба могут использоваться вместе или независимо друг от друга. Я думаю, что теорема CAP применяется к этим двум формам немного по-разному:

Уровень разделения. MongoDB хранит данные не более чем в одном официальном сегменте.

  • Строгая согласованность: часть данных существует не более чем в одном шарде. Неверных/устаревших данных не существует.
  • Строгая устойчивость к разделам: даже если сеть разбита на разделы, запросы никогда не возвращают неверные/устаревшие данные. Осколки продолжают работать независимо от других осколков.

  • Слабая доступность: чтение/запись данных на отключенном осколке не удастся.

Уровень набора реплик. MongoDB реплицирует данные в сегменте, обеспечивая согласованность с помощью одного авторитетного основного узла.

  • Строгая согласованность: все операции чтения/записи обрабатываются основным узлом.
  • Сильная устойчивость к разделению: если достаточное количество узлов становится недоступным, выбирается новый основной узел. Процесс выбора гарантирует, что всегда будет не более одного основного узла.

  • Слабая доступность: операции чтения/записи завершатся сбоем, если первичный узел не существует, даже если доступ к данным возможен через вторичные узлы.


Вариант slaveOK/ReadPreference.SECONDARY жертвует некоторой согласованностью (устаревшие данные могут быть прочитаны) для повышения производительности и доступности.

person Leftium    schedule 02.02.2012