Де стоїть mongodb у теоремі CAP?


121

Куди б я не дивився, я бачу, що MongoDB є CP. Але коли я копаюсь, я бачу, що з часом це відповідає. Це CP, коли ви використовуєте safe = true? Якщо так, чи означає це, що коли я пишу з Safe = true, всі репліки будуть оновлені до отримання результату?

Відповіді:


104

За замовчуванням MongoDB сильно відповідає - якщо ви пишете, а потім читаєте, вважаючи, що запис був успішним, ви завжди зможете прочитати результат написаного вами запису. Це відбувається тому, що MongoDB - це одномовна система, і всі читання за замовчуванням переходять до основного. Якщо ви необов'язково включите читання з вторинних видань, MongoDB з часом стає послідовною, де можливо зчитувати застарілі результати.

MongoDB також отримує високу доступність через автоматичну відмову в наборах реплік: http://www.mongodb.org/display/DOCS/Replica+Sets


13
Відповідно до aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads, навіть якщо ви читаєте з основного вузла в наборі реплік, у вас можуть з’явитися застарілі чи брудні дані. Тож MongoDB сильний?
Майк Аргіріу

3
Дивовижні експерименти Кайла. Це дійсно полює на монго. Цікаво, чи є виробничі системи, наприклад, використовуючи MongoDB, який здійснює платіжні операції? Якщо це лише особистий веб-сайт, який піклується про сильну послідовність.
xin

5
Тільки для запису MongoDB v3.4 пройшов тест, розроблений Кайлом, так, так, MongoDB сильно відповідає навіть ReplicaSet і Sharding: mongodb.com/mongodb-3.4-passes-jepsen-test
Максим

2
Ця відповідь може бути занадто спрощеною, оскільки MongoDB час від часу може жертвувати доступністю, грунтуючись на конфігурації. JoCa краще пояснює ситуації, в яких він веде себе CA / CP / AP
PaoloC

37

Я згоден з посадою Luccas. Ви не можете просто сказати, що MongoDB - це CP / AP / CA, оскільки це насправді є компромісом між C, A і P, залежно від конфігурації бази даних / драйверів та типу катастрофи : ось візуальний резюме та нижче більш детальне пояснення.

    Scenario                   | Main Focus | Description
    ---------------------------|------------|------------------------------------
    No partition               |     CA     | The system is available 
                               |            | and provides strong consistency
    ---------------------------|------------|------------------------------------
    partition,                 |     AP     | Not synchronized writes 
    majority connected         |            | from the old primary are ignored                
    ---------------------------|------------|------------------------------------
    partition,                 |     CP     | only read access is provided
    majority not connected     |            | to avoid separated and inconsistent systems

Консистенція:

MongoDB твердо відповідає, коли ви використовуєте єдине з'єднання або правильний рівень стурбованості запису / читання ( що коштуватиме швидкості виконання ). Як тільки ви не дотримуєтесь цих умов (особливо коли ви читаєте з вторинної репліки), MongoDB стає з часом стійким.

Наявність:

MongoDB отримує високу доступність завдяки Replica-Sets . Як тільки первинна знизиться або стане недоступною, то вторинні визначатимуть новий основний, щоб знову стати доступним. У цьому є недолік: кожне записування, яке було виконано старим основним, але не синхронізоване до вторинних, буде відведене та збережене у відкатний файл, як тільки воно відновиться до набору (стара первинна частина є вторинною зараз). Тож у цьому випадку певна послідовність жертвується заради доступності.

Толерантність розділів:

Завдяки використанню зазначених Replica-Sets MongoDB також досягає толерантності до розділів: Поки більше половини серверів репліка-набору підключено один до одного, можна вибрати новий первинний . Чому? Для забезпечення двох відокремлених мереж обидва не можуть обирати новий основний. Коли між собою підключено недостатньо вторинних даних, ви все ще можете з них прочитати (але послідовність не забезпечується), але не записувати. Набір практично недоступний заради послідовності.


Отже, якщо я використовую правильний рівень стурбованості запису / читання, це означає, що всі розлючені та прочитані переходять до основного (якщо я правильно зрозумів), то що саме робити вторинні? Просто сидіти там у режимі очікування, якщо первинна знизиться?
tomer.z

@ tomer.z Ви можете прочитати цей розділ посібника: Ви можете використовувати вторинники для читання. Якщо ви використовуєте рівень для читання "більшість", читання буде дійсним, як тільки більшість членів визнали прочитане. Те саме стосується і рівня «Письмового рівня більшості». Якщо ви використовуєте "Конкурс-рівень" для обох, ви маєте послідовну базу даних. Ви можете прочитати детальніше про це в посібнику .
JoCa

18

Оскільки в новій статті з'явилися нові яскраві експерименти Кайла в цій галузі, ви повинні бути обережними при маркуванні MongoDB та інших баз даних, як C або A.

Звичайно, CAP допомагає без особливих слів відстежувати, яка база даних переважає про неї, але люди часто забувають, що, наприклад, C у CAP означає атомну консистенцію (лінійність). І це заподіювало мені багато болю, коли я намагався класифікувати. Тож, крім того, що MongoDB надає сильну послідовність, це не означає, що це C. Таким чином, якщо зробити цю класифікацію, я рекомендую також надати більше глибини в тому, як це насправді працює, щоб не залишати сумнівів.


10

Так, це CP при використанні safe=true. Це просто означає, що дані внесли його на головний диск. Якщо ви хочете переконатися, що він також надходить на якусь репліку, перегляньте параметр 'w = N', де N - кількість реплік, на яких потрібно зберегти дані.

див. це та це для отримання додаткової інформації.


3

Я не впевнений у П для Монго. Уявіть ситуацію:

  • Ваша репліка розбивається на дві секції.
  • Писання продовжують обидві сторони, коли обиралися нові господарі
  • Розділ вирішено - тепер усі сервери знову підключені
  • Що відбувається, це те, що обирається новий ведучий - той, який має найвищий опис, але дані другого ведучого повертаються до загального стану перед розділом, і він викидається у файл для ручного відновлення
  • всі вторинники наздоганяють нового господаря

Проблема тут полягає в тому, що розмір дамп-файлу обмежений, і якщо у вас був розділ тривалий час, ви можете втратити свої дані назавжди.

Можна сказати, що це навряд чи станеться - так, хіба що в хмарі, де це звичайніше, ніж можна подумати.

Цей приклад, тому я був би дуже обережним, перш ніж призначати будь-який лист будь-якій базі даних. Стільки сценаріїв та реалізації не є ідеальними.

Якщо хтось знає, чи розглядався цей сценарій у наступних випусках Mongo, будь ласка, прокоментуйте! (Я деякий час не стежу за всім, що відбувалося ..)


2
Протокол виборів MongoDB розроблений таким чином, щоб мати (максимум) єдине основне. Первинний може бути обраний (і підтриманий) лише суворою більшістю налаштованих членів голосуючих реплік (n / 2 +1). У разі мережевого розділу лише один розділ (з більшістю голосів членів) може обрати первинний; попередній первинний розділ меншості відійде і стане вторинним. Це так, як завжди працювали набори реплік. У випадку, якщо колишній первинний прийняв записи, які не були повторені, вони будуть повернуті (збережені на диск), коли цей член знову приєднається до набору реплік.
Стенні

2

Mongodb ніколи не дозволяє записувати до другорядних. Це дозволяє необов'язково читати з другорядних, але не записує. Отже, якщо ваш основний знижується, ви не можете писати, поки вторинна не стає первинною. Таким чином, ви жертвуєте високою доступністю в теоремі CAP. Зберігаючи свої читання лише від первинних, ви можете мати міцну послідовність.


2

MongoDB вибирає послідовність над доступністю, коли є розділ. Це означає, що коли є розділ (P), він вибирає узгодженість (C) над доступністю (A).

Щоб зрозуміти це, давайте розберемося, як працює набір реплік MongoDB. Набір реплік має один основний вузол. Єдиний "безпечний" спосіб введення даних - це записати в цей вузол, а потім чекати, коли ці дані скористаються більшістю вузлів у наборі. (ви побачите цей прапор для w = більшості, коли надсилаєте записи)

Розбиття може відбуватися у двох випадках:

  • Коли Первинний вузол виходить з ладу: система стає недоступною, поки не буде обрано новий основний.
  • Коли Первинний вузол втрачає зв’язок із занадто великою кількістю вторинних вузлів: система стає недоступною. Інші вторинники намагатимуться обрати новий Первинний, а поточний первинний відступить.

По суті, щоразу, коли відбудеться розділ, і MongoDB потрібно вирішити, що робити, він вибере послідовність щодо доступності. Він перестане приймати записи до системи, поки не вірить, що може безпечно виконати ці записи.


"Він перестане приймати записи в систему, поки не вірить, що вона може безпечно виконати ці записи ". Що з прочитаними ? Чи залишиться вона доступною для читання протягом цього часу?
Джош

1

MongoDB забезпечує узгодженість і розділів толерантності .

У контексті розподілених (NoSQL) баз даних це означає, що завжди буде компроміс між послідовністю та доступністю. Це тому, що розподілені системи завжди обов'язково мають терпимість до розділів (тобто просто не було б розподіленою базою даних, якби вона не була роздільною.)

Послідовність - система з часом стане послідовною. Дані рано чи пізно поширюватимуться скрізь, де система повинна продовжувати надходити і не перевіряє послідовність кожної транзакції, перш ніж вона перейде до наступної.

Доступність - За замовчуванням клієнт DB Mongo (драйвер MongoDB) надсилає всі запити читання / запису на лідер / первинний вузол. Це робить систему послідовною, але недоступною через: - Якщо лідер відключається від кластера, потрібно кілька секунд, щоб обрати нового лідера. Таким чином, роблячи його недоступним для запису та читання за ту тривалість.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.