Транзакции в NoSQL?
Я изучаю NoSQL для масштабирования альтернатив базе данных. Что мне делать, если мне нужны вещи на основе транзакций, которые чувствительны к такого рода вещам?
11 ответов:
вообще говоря, решения NoSQL имеют более легкую транзакционную семантику, чем реляционные базы данных, но все же имеют средства для атомарных операций на некотором уровне.
Как правило, те, которые делают репликацию master-master, обеспечивают меньшую согласованность и большую доступность. Поэтому нужно выбрать правильный инструмент для правильной проблемы.
многие предлагают транзакции в одном документе (или строке и т. д.) уровень. Например, в MongoDB есть атомарность в одном документе - но документы могут быть довольно богатыми, поэтому это обычно работает довольно хорошо - Подробнее здесь.
Это самый близкий ответ, который я нашел, который будет применяться к любой базе данных NoSQL. Это на блоге 2007 года от Адама Уиггинса из Heroku.com:
старый пример использования транзакции базы данных для переноса перевода денег с одного банковского счета на другой-это total bull. Правильное решение состоит в том, чтобы сохранить список событий книги (переводы между счетами) и показать текущий баланс в виде суммы книги. Если вы программируете на функциональном языке (или думаете таким образом), это очевидно.
от:http://adam.heroku.com/past/2007/12/17/a_world_without_sql/ (его сайт отлично подходит для идей по масштабируемости.)
Я интерпретировал вышеприведенный абзац как:
- создать базу данных для учетных записей участников.
- создать очередь сообщений. Прозвище его "Леджер".
- добавить в фоновом режиме работников для выполнения каждого запроса в очереди.
Подробнее. на очереди / фоновые работники: http://adam.heroku.com/past/2009/4/14/building_a_queuebacked_feed_reader_part_1/
клиент (он же участник или клиент) выполняет следующие действия, чтобы взять деньги:
- подать заявку на вывоз денег.
- запрос отправляется на сервер.
- сервер помещает его в очередь. Сообщение таково: "возьмите $5,000."
- клиент показан: "Пожалуйста, подождите, как запрос выполненный..."
- клиентские машины опрашивают сервер каждые 2 секунды, спрашивая: "был ли выполнен запрос?"
- на сервере фоновые работники выполняют предыдущие запросы от других членов в режиме первого входа / первого выхода. В конце концов, они добираются до запроса вашего клиента, чтобы взять деньги.
- как только запрос был выполнен, клиенту выдается сообщение с их новым балансом.
вы можете использовать Heroku.com для создания небольшого макета быстро, если вам удобно с узлом.js или Ruby / Rack.
общая идея кажется довольно простой и намного лучше, чем использование транзакций, запеченных в базе данных, которые делают ее супер-трудной для масштабирования.
отказ от ответственности: я еще не реализовал это в любом случае еще. Я читаю об этих вещах из любопытства, хотя у меня нет практической необходимости в них. Да, @gbn прав, что СУБД с транзакциями, вероятно, будет достаточно для нужд Тимми и меня. Тем не менее, было бы интересно посмотреть, как далеко вы можете взять базы данных NoSQL с помощью инструментов с открытым исходным кодом и веб-сайта под названием "Торнадо бритвенных лезвий".
NoSQL охватывает широкий набор инструментов и услуг, включая магазины ключей, документов, графиков и широких столбцов. Они обычно пытаются улучшить масштабируемость хранилища данных, обычно путем распространения обработки данных. Транзакции требуют кислоты свойства того, как DBs выполняет пользовательские операции. ACID ограничивает, как можно улучшить масштабируемость: большинство инструментов NoSQL ослабляют критерии согласованности операционных систем, чтобы получить отказоустойчивость и доступность для масштабирования, что делает реализацию кислотных транзакций очень сложной.
обычно цитируемое теоретическое рассуждение распределенных хранилищ данных является CAP теорема: согласованность, доступность и допуск разделов не могут быть достигнуты одновременно. SQL, NoSQL и NewSQL инструменты могут быть классифицированы в соответствии с тем, что они отказываются; хорошая цифра может быть найдена здесь.
новый, более слабый набор требований заменяя кислоту базовый ("в основном доступное, мягкое состояние, конечная консистенция"). Однако в конечном итоге согласованные инструменты ("в конечном итоге все обращения к элементу вернут последнее обновленное значение") вряд ли приемлемы в транзакционных приложениях, таких как банковское дело. Здесь хорошей идеей было бы использовать в памяти, ориентированные на столбцы и распределенные базы данных SQL / ACID, например VoltDB; Я предлагаю посмотреть на эти решения "NewSQL".
просто хотел прокомментировать совет по денежным транзакциям в этой теме. Транзакции-это то, что вы действительно хотите использовать с денежными переводами.
пример, приведенный как сделать que переводы очень красиво и аккуратно.
но в реальной жизни перевод денег может включать в себя сборы или платежи на другие счета. Люди получают бонусы за использование определенных карт, которые поступают с другого счета, или они могут получать сборы, снятые с их счета на другой счет в той же системе. Гонорар или платежи могут варьироваться в зависимости от финансовой транзакции, и вам может потребоваться поддерживать систему бухгалтерского учета, которая показывает кредит и дебет каждой транзакции по мере ее поступления.
Это означает, что вы хотите обновить более одной строки одновременно, так как кредит на одном счете может быть дебет на одном или нескольких счетах. Сначала вы блокируете строки, чтобы ничего не могло измениться до обновления, а затем вы убедитесь, что записанные данные согласуются с транзакцией.
вот почему вы действительно хотите использовать транзакции. Если все идет не так запись в одну строку вы можете откатить всю кучу обновлений без финансовых транзакций данные заканчиваются несогласованно.
Проблема с одной транзакцией и двумя операциями (например, одна платит $5,000, вторая получает $5,000) - это то, что у вас есть два счета с одинаковым приоритетом. Вы не можете использовать одну учетную запись для подтверждения второй (или в обратном порядке). В этом случае вы можете гарантировать, что только одна учетная запись будет правильной (что подтверждено), вторая (что подтверждение) может потерпеть неудачу. Давайте посмотрим, почему это может не сработать (используя сообщение aproatch, отправитель подтверждается получателем):
- запись + $ 5,000 в приемник аккаунт
- если успех-напишите - $ 5,000 на счет отправителя
- если не удается-попробуйте еще раз или отменить или показать сообщение
Это гарантирует экономию на № 1. Но кто даст гарантию, если № 2 потерпит неудачу? Же в обратном порядке.
Но это можно реализовать, чтобы быть в безопасности без транзакций и с NoSQL. Вы всегда можете использовать третью сущность, которая будет подтверждена со стороны отправителя и получателя и гарантирует, что ваша операция была выполненный:
- создание уникального идентификатора транзакции и создание объекта транзакции
- напишите + $ 5,000 на счет получателя (со ссылкой на идентификатор транзакции)
- Если успешно-установите состояние транзакции для отправки
- запись - $ 5,000 на счет sedned account (со ссылкой на идентификатор транзакции)
- Если успешно-установите состояние транзакции для получения
Эта запись транзакции будет гарантировать, что это было нормально отправить / получить массаж. Теперь вы можете проверить каждое сообщение по идентификатору транзакции, и если оно имеет состояние получено или завершено - вы учитываете его для баланса пользователя.
зависит от вашей БД, но ... Я бы сказал, В общем, вы можете использовать 'оптимистичный сделок' чтобы достичь этого, но я думаю, что нужно обязательно понять реализацию базы данных атомарность гарантии (например, какие операции записи и чтения являются атомарными).
кажется некоторые обсуждения в сети о HBase транзакции, если это поможет.
вы всегда можете использовать подход NoSQL в БД SQL. NoSQL, как правило, использует "хранилища данных ключей / значений": вы всегда можете реализовать это в своей предпочтительной СУБД и, следовательно, сохранить хорошие вещи, такие как транзакции, свойства ACID, поддержка от вашего дружественного DBA и т. д., реализуя преимущества производительности и гибкости NoSQL, например, через таблицу, такую как
CREATE TABLE MY_KEY_VALUE_DATA ( id_content INTEGER PRIMARY KEY, b_content BLOB );
бонус - вы можете добавить дополнительные поля здесь, чтобы связать свой контент с другими, правильно реляционными таблицами, пока еще сохраняя свой громоздкий контент в больших двоичных объектов (или текст, если поле атсэ).
лично я предпочитаю текстовое представление, поэтому вы не привязаны к языку для работы с данными, например, используя сериализованные средства Java, вы можете получить доступ к содержимому из Perl для отчетности, скажем. Текст также легче отлаживать и, как правило, работать с разработчиком.
вот почему я создаю решение для хранения документов NoSQL, чтобы иметь возможность использовать "реальные" транзакции в корпоративных приложениях с использованием неструктурированного подхода к данным. Взгляните на http://djondb.com и не стесняйтесь добавлять любую функцию, которую вы считаете полезной.
- новое хранилище ключ-значение FoundationDB
- старый ключ-значение хранилище Berkley DB
наверняка есть и другие
вы можете реализовать оптимистичные транзакции поверх решения NoSQL, если оно поддерживает сравнение и набор. Я написал пример и объяснение на GitHub страница как это сделать в MongoDB, но вы можете повторить это в любом подходящем решении NoSQL.