Транзакції в NoSQL?


77

Я шукаю NoSQL для пошуку альтернатив базі даних. Що робити, якщо я хочу чутливі до такого роду речі на основі транзакцій?


3
FYI ... Бази даних NoSQL все ще є БД, вони просто не є реляційними. Що стосується транзакцій, то транзакція - це просто логічне групування запитів та оновлень. Нереляційні БД все ще забезпечують обидві ці функції. Які речі до яких речей чутливі?
joejoeson

1
ну, я хочу робити грошові операції або, принаймні, думати про них. але я все одно хочу певної цілісності в цьому сенсі.
Тіммі

3
Скільки терабайт даних у вас є, і ви не можете використовувати стандартну основну СУБД, яка має вбудовану підтримку транзакцій?
gbn

@gbn Кількість ТБ даних не має нічого спільного з необхідністю використання баз даних NoSQL. Можливо, він хоче позбутися моделі EAV у своїй реляційній БД.
Зелений

Відповіді:


41

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

Як правило, ті, які виконують реплікацію майстер-майстер, забезпечують менший рівень узгодженості та більшу доступність. Тож слід вибрати правильний інструмент для правильної проблеми.

Багато пропонують операції на рівні одного документа (або рядка тощо). Наприклад, з MongoDB існує атомність в одному документі, але документи можуть бути досить багатими, тому це зазвичай працює досить добре - докладніше тут .


5
Деякі бази даних NoSQL, такі як MarkLogic, насправді забезпечують реальні транзакції ACID.
Eric Bloch,

5
RavenDB також забезпечує реальні транзакції ACID.
Метт Джонсон-Пінт,

5
FoundationDB також забезпечує транзакцію ACID з кількома ключами в кластері з декількома вузлами.
eonil

5
Neo4j - це магазин NoSQL і надає властивості ACID.
Nadjib Mami

3
RavenDB не забезпечує справжні транзакції ACID. Він використовує слабку форму ізоляції, яка називається "моментальна ізоляція". Він забезпечує глобальні транзакції через зовнішнього координатора, але використання не рекомендується foundationdb.com/acid-claims
Акіра Ямамото

18

Це найближча відповідь, яку я знайшов, і яка стосується будь-якої бази даних NoSQL. Це у дописі блогу 2007 року від Адама Віггінса з Heroku.com:

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

З: http://adam.heroku.com/past/2007/12/17/a_world_without_sql/ (його веб-сайт чудово підходить для ідей щодо масштабованості.)

Я трактував вищезазначений параграф як:

  1. Створіть базу даних для облікових записів членів.
  2. Створіть чергу обміну повідомленнями. Прізвисько це "книга".
  3. Додайте фонових працівників для виконання кожного запиту в черзі.

Більше інформації. щодо черг / фонових працівників: http://adam.heroku.com/past/2009/4/14/building_a_queuebacked_feed_reader_part_1/

Клієнт (він же член або замовник) виконує такі кроки, щоб забрати гроші:

  1. Подайте запит на вивезення грошей.
  2. Запит надсилається на сервер.
  3. Сервер поміщає його в чергу. Повідомлення: "Вийміть 5000 доларів".
  4. Клієнту відображається: "Будь ласка, почекайте, поки запит буде виконано ..."
  5. Клієнтські машини опитують сервер кожні 2 секунди, запитуючи: "Чи виконано запит?"
  6. На сервері фонові працівники виконують попередні запити інших членів у режимі першого входу / виходу. Зрештою, вони потрапляють на прохання вашого клієнта взяти гроші.
  7. Після того, як запит виконано, клієнту надходить повідомлення з новим балансом.

Ви можете використовувати Heroku.com, щоб швидко створити невеликий макет, якщо вам подобається Node.js або Ruby / Rack.

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

Застереження: Я ще ніяк не реалізував це. Я читав про ці речі з цікавості, хоча в них у мене немає практичної потреби. Так, @gbn має рацію, що RDBMS з транзакціями, мабуть, буде достатнім для потреб Тіммі та мене. Тим не менше, було б цікаво спостерігати, наскільки далеко ви можете зайняти бази даних NoSQL за допомогою інструментів з відкритим кодом та веб-сайту, що називається " Торнадо з Бритви ".


35
Здається, це дивна критика прикладу "транзакцій" до "привіт світу". Що станеться, якщо під час створення однієї з "подій книги" щось не вдається? Тоді залишок на цьому рахунку буде неправильним. Це не звучить як дієва заміна транзакцій для мене.
a_horse_with_no_name

21
Пов’язана веб-сторінка демонструє приголомшливий ступінь незнання щодо необхідності застосування кислоти практично у всіх фінансових системах. По-перше, стаття аргументує "продуктивність", в той час як вона ігнорує продуктивність, необхідну для читання КОЖНОГО ОДНОГО ОПЕРАЦІЇ з історії, щоб обробити нову транзакцію. По-друге, і що більш важливо, як працює це рішення у випадку, коли на одному рахунку трапляються ВІДХОДНІ запити, і коли комерційна операція складається з оновлень для кількох суб’єктів? Що станеться, якщо сервер помре в середині обробки?
Андрій не святий

2
Це все про двофазні коміти. Навколо Google, і ви побачите, що ви можете отримати послідовність без транзакцій.
Папіпо

2
Ендрю, що станеться, якщо транзакція вашої картки провалиться на півдорозі. Ви коли-небудь бачили виписку з банку із зворотною операцією?
Алістер

16

NoSQL охоплює різноманітний набір інструментів та послуг, включаючи сховища ключ-значення, документи, графіки та широкі стовпці. Зазвичай вони намагаються поліпшити масштабованість сховища даних, зазвичай розподіляючи обробку даних. Для транзакцій потрібні ACID властивості того, як БД виконують операції користувача. ACID обмежує можливість покращення масштабованості: більшість інструментів NoSQL послаблюють критерії узгодженості операцій, щоб отримати відмовостійкість та доступність для масштабування, що ускладнює реалізацію транзакцій ACID.

Типовим теоретичним міркуванням розподілених сховищ даних є теорема CAP : не можна одночасно досягти узгодженості, доступності та допуску до розділів. Інструменти SQL, NoSQL та NewSQL можна класифікувати за тим, від чого вони відмовляються; тут можна знайти гарну цифру .

Новим, слабшим набором вимог, що замінюють кислоту, є BASE ("в основному доступний, м'який стан, можлива консистенція"). Однак врешті-решт послідовні інструменти ("зрештою всі звернення до елемента повернуть останнє оновлене значення") навряд чи прийнятні в транзакційних додатках, таких як банківська справа. Тут гарною ідеєю було б використовувати вбудовану в пам’ять, орієнтовану на стовпці та розподілену базу даних SQL / ACID, наприклад VoltDB ; Я пропоную розглянути ці рішення "NewSQL".


"більшість цих інструментів відмовляються від узгодженості і, отже, кислоти". Здається, ви плутаєте суворість, як у ACID, з послідовністю, як у CAP. C в CAP означає, що всі копії даних рівні. в той час як C в ACID - це туманний і неоднозначний термін ... загалом кажучи, наявність не суперечить ACID. Приклад Google Spinner це підтверджує.
Олексій

Послідовність ACID вимагає, щоб транзакції здійснювались, оскільки низка клієнтських операцій може походити лише з дійсних станів бази даних і закінчуватися ними. Це лише схоже на C в CAP, тож це правильно, вони не однакові і не суперечать. Реалізувати транзакції ACID в системі точки доступу дуже важко, що зазвичай припускається для масштабованості. Я переформулюю свою відповідь. Оглядаючись зараз, я виявляю, що теорема CAP та категорії CAP були занадто розмитими, не надаючи реальної допомоги в класифікації цих інструментів. Я думаю, що CAP залишається лише цікавим теоретичним прикладом компромісів щодо розподіленої системи.
csaba

13

Просто хотів прокоментувати поради щодо грошових операцій у цій темі. Транзакції - це те, що ви дійсно хочете використовувати для грошових переказів.

Наведений приклад того, як здійснювати трансфери, дуже приємний та охайний.

Але в реальному житті переказ грошей може включати збори або платежі на інші рахунки. Люди отримують бонуси за користування певними картками, що надходять з іншого рахунку, або вони можуть отримувати збори зі свого рахунку на інший рахунок у тій самій системі. Комісії або платежі можуть різнитися залежно від фінансової операції, і, можливо, вам доведеться підтримувати бухгалтерську систему, яка відображає кредит і дебет кожної операції в міру її надходження.

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

Ось чому ви дійсно хочете використовувати транзакції. Якщо щось піде не так, напишучи в один рядок, ви можете відмотати цілу купу оновлень, не закінчуючи суперечливі дані про фінансові операції.


1
Є й інші, можливо, кращі способи боротьби з побічними ефектами угоди. Транзакція є початковою подією, і якщо вона записана атомно, будь-яка інша помилка або проблема може бути простежена до цієї події.
Chris Nicola

6

Проблема однієї транзакції та двох операцій (наприклад, одна платить 5000 доларів, друга отримує 5000 доларів) - полягає в тому, що у вас є два рахунки з однаковим пріоритетом. Ви не можете використовувати один рахунок для підтвердження другого (або у зворотному порядку). У цьому випадку ви можете гарантувати, що лише один рахунок буде правильним (що підтверджується), другий (що підтверджує) може мати помилки. Давайте подивимося, чому це може не вдатися (використовуючи підхід до повідомлення, відправник підтверджується отримувачем):

  1. Напишіть + 5000 доларів на рахунок одержувача
  2. Якщо успіх - напишіть - 5000 доларів на рахунок відправника
  3. Якщо не вдається - спробуйте знову, скасуйте або покажіть повідомлення

Це гарантовано заощадить №1. Але хто гарантує, якщо №2 зазнає невдачі? Те саме для зворотного порядку.

Але це можливо, щоб реалізації були безпечними без транзакцій та з NoSQL. Завжди дозволяється використовувати третю особу, яка буде підтверджена від відправника та одержувача та гарантує, що ваша операція була виконана:

  1. Створення унікального ідентифікатора транзакції та створення сутності транзакції
  2. Написати + 5000 доларів на рахунок одержувача (з посиланням на ідентифікатор транзакції)
  3. Якщо успіх - встановіть стан транзакції для відправки
  4. Запис - 5000 доларів США на залишений рахунок (з посиланням на ідентифікатор транзакції)
  5. Якщо успіх - встановіть стан транзакції для отримання

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


1
Що робити, якщо кроки 3 та 5 провалились? Це додає багато складності, через яку транзакції в базі даних є настільки корисними.
Skill M2

Зазвичай така система ніколи не покладається на можливість sql для перевірки транзакції. А також за реальним сценарієм кредитування та дебетування в основному відбуваються в часі та банках - що виходить за рамки sql або nosql - можливостей ... про це може піклуватися лише добре продумана архітектура - яка безперебійно працює для транзакцій у системі чи через системи.
Калпеш Попат

Я вважаю, що такий підхід хороший. Однак ми також повинні подумати про розподілене виконання частин транзакції (одна частина, що працює, скажімо, в мікросервісі 1, а інша частина, скажімо, в мікрослужбі 2, яка працює на сервері в іншому домені в хмарі ). Без якоїсь фонової роботи, яка обробляє ці транзакції, належним чином встановлюючи статуси пов’язаних записів, що знаходяться на декількох серверах, розподілені транзакції в NoSQL важко зробити (але неминучі).
Прасад

2

Залежить від вашої БД, але ... Я б сказав, загалом, для досягнення цього ви можете використовувати "оптимістичні транзакції", але, думаю, слід переконатися, що розумієте гарантії атомності реалізації бази даних (наприклад, який тип операцій запису та читання є атомними ).

Там , як видається, деякі дискусії в мережі про Hbase угод, якщо то будь-яка допомога.


1

Ви завжди можете використовувати підхід NoSQL у SQL DB. Здається, NoSQL зазвичай використовує "сховища даних ключ / значення": ви завжди можете застосувати це у бажаній системі СУБД, а отже, зберігати такі добрі речі, як транзакції, властивості ACID, підтримку вашої дружньої DBA тощо, одночасно реалізуючи переваги продуктивності та гнучкості NoSQL. , наприклад, через таблицю, таку як

CREATE TABLE MY_KEY_VALUE_DATA
(
    id_content INTEGER PRIMARY KEY,
    b_content  BLOB
);

Бонусом є те, що ви можете додати сюди додаткові поля, щоб зв’язати свій вміст з іншими, належним чином реляційними таблицями, зберігаючи при цьому громіздкий вміст у головному полі BLOB (або TEXT, якщо це зручно).

Особисто я віддаю перевагу поданню ТЕКСТУ, щоб ви не були прив'язані до мови для роботи з даними, наприклад, використання серіалізованої Java означає, що ви можете отримати доступ до вмісту з Perl для звітування, скажімо. ТЕКСТ також простіше налагоджувати і, як правило, працювати з ним як розробник.


1

подивіться на scalaris, це не no sql db з чіткою послідовністю та реалізованими транзакціями.


1

Ось чому я створюю рішення сховища документів NoSQL, щоб мати змогу використовувати "реальні" транзакції в корпоративних програмах із силою підходу до неструктурованих даних. Погляньте на http://djondb.com і сміливо додайте будь-яку функцію, яка, на вашу думку, може бути корисною.



0

Ви можете реалізувати оптимістичні транзакції поверх рішення NoSQL, якщо воно підтримує порівняння та встановлення. Я написав приклад і пояснення на сторінці GitHub, як це зробити в MongoDB, але ви можете повторити це в будь-якому підходящому рішенні NoSQL.

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