Pull to refresh

Comments 100

Ох как я задолбался повторять этот пример, но покажите как ваш подход работает на обычном интернет-магазине.

Структура простая:
1) Товары и категории
2) Заказы и позиции заказов
3) Покупатели

Задачи:
1) показывать каталог товаров по категориям
2) показывать историю заказов по пользователю
3) показывать «популярные» (с наибольшей суммой продаж за месяц) товары на сайте
4) показывать похожие товары — товары и той же категории, которые чаще всего встречаются в заказах вместе с указанным товаром

Нагрузка предполагается небольшая, нужно максимизировать скорость разработки и корректность данных.
Что Вас смущает? Неужели тут трудно определиться где нужны транзакции, реляционность (ну, наверное для заказов, их отношения к товарам и покупателям), а где — подход к набору данных, как к коллекции документов (ну вот те же товары — вполне себе набор документов). Ведь удобно — у разных товаров могут быть разные поля, легко отнести один товар к нескольким категориям, а запросы типа «популярные» и «похожие» отлично делаютcя через aggregation framеwork.
Я надеялся что вы ответите…

Я этот вопрос задавал многим, кто пропагандирует использование NoSQL, никто ответа не дал. Все начинали про scale рассказывать, но он-то как раз не нужен. Если инет-магазин насчитывает не более 300 позиций и до 1000 заказов в месяц (а таких подавляющее большинство), то это все отлично реализуется на РСУБД с меньшими затратами, чем NoSQL. Все запросы типа «похожие» и «популярные» отлично делаются SQL, пока у вас не миллионы записей.

А ели же вам нужно сильно масштабировать, то просто используйте кеш. Полнотекстовый индекс кстати тоже является кешом в некотором роде и довольно легко прикручивается к РСУБД.
Подробно тут: www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/
Меня вот как-то прям коробит от Вашего тона и игру в экзаменатора… ну да ладно.

А по сути статья об очевидном: что удобней, то и надо использовать. Есть и плюсы, и минусы у каждого подхода.
Да, маленький магазин проще писать с mysql например. А миллиардные хранилища — на Nosql каком-нибудь.

В проекте, над которым я работаю — там используется четыре языка программирования, естественно разные библиотеки, ну и конечно же разные базы данных для разных целей: postgres, mtsql, hbase. И кэширование тоже используется.

А в маленьком проекте конечно тянуть такой зоопарк нереально — просто человеческих ресурсов не хватит.
Так что каждому — свое.
Так вы на вопрос в итоге не ответили.

И зачем в миллиардных хранилищах NoSQL?

например маленький интернет-магазин можно масштабировать в сотни и даже тысячи раз если прикрутить кеш и полнотекстовый индекс на Lucene.
Вы сами задали вопрос и сами же на него ответили: для маленьких магазинов все вполне укладывается в обычные реляционные базы.

Насчет масштабирование в тысячи раз исходя из Ваших данных «не более 300 позиций» мы получим 300 * 1000 = 300000. Ну добавим еще пару нулей. Миллионы. Сомневаюсь, что это так просто отмасштабируется, хотя вполне реально наверно, если сильно помучаться — не пробовал. Я же говорю о миллиардах. Вцелом я не хочу Вас ни в чем убеждать, области применения nosq баз не раз описывались на том же хабре, гугл хранит в nosql базе свои базы для поисковика ну и т.д.
Да и мы стали применять nosql тогда, когда реляционные базы оказались неспособны работать с большими объемами.
То есть у вас уже была вполне конкретная схема данных и не было проблем уложить её в NoSQL.
А если вы начинаете проект с NoSQL, особенно Document DB, то как вы заранее узнаете какую схему создавать

Вообще созданием правильной схемы для Document DB, как Mongo — крайне нетривиальная задача. Даже отсутствие однозначного ответа в случае простого интернет-магазина это очень хорошо показывает.

А в статье рекомендуется начинать в том числе с NoSQL, со всеми вытекающими.
UFO just landed and posted this here
Ну если XML\JSON поле в базе это NoSQL, то да. Если же имеется ввиду NoSQL как отдельная СУБД, то я слабо понимаю смысл в этом.
UFO just landed and posted this here
Позволит ли хранение товаров в NoSQL-базе делать сложные выборки товаров (без загрузки всех товаров в память)?
UFO just landed and posted this here
То, что в SQL осуществляется join'ами. Скажем, отобразить список холодильников дороже 20 тысяч, покупавшихся за последние две недели в таком-то филиале.
Сделать можно, но не всегда это тривиально.
Если тот же mysql преобразует все запросы в сложные выборки внутри базы и наружу торчит только SQL-запрос, то в случае например hbase — трудитесь сами. Для того же hbase есть надстройка в виде Pig — помогает немного упростить жизнь, но сделать ее такой же халявной, как в чистом SQL — фигвам. Опять же, в nosql отсутсвуют множественные индексы (по ключу индекс есть), ибо их обновлять при миллирадном числе записей просто нереально — отсюда вытекает часто чистый перебор данных.
Я правильно понимаю, что для осуществления сложных выборок в NoSQL нужно:
— переносить join'ы в логику приложения;
— загружать в память сразу все данные из коллекций, участвующих в выборке;
— лишиться выигрыша в скорости перед реляционными БД?
Все зависит от задачи. Могу только сказать по hadoop/hbase, с которым приходится работать: да, join'ы делаются на уровне приложения (там по сути используется технология Map-Reduce, поищите в гугле например книжку «Hadoop: The Definitive Guide» — там отдельная глава joinэам посвящена).

Про память: в память большие объемы в принципе загрузить нереально, а на небольших — почему бы и нет, опять же от задачи зависит.

Про скорость. Как Вы догадались, зависит от задачи ;) Кластер с hadoop/hbase миллиарды записей обработает на десятки секунд, а тот же mysql просто помрет или будет неделю считать. Здесь скорость явно за nosql. С другой стороны, запрос к hbase на несколько тысяч записей только инициализироваться будет секунды, пока вся эта махина поднимется и начнет данные пережевывать, в то время как mysql отработает за миллисекунды. Скорость разработки на порядок выше в SQL — потому что всю низкоуровневую работу берет на себя сервер БД и на уровне приложения делать ничего не надо.

Вобщем, как всегда, надо начинать с постановки задачи и выбирать инструмент под нее.
А какой смысл сравнивать analytic engine и rdbms? Это очень частая практика что сами данных хранятся в mysq;l\postgtres\oracle\mssql, а пережевываются и считаются агрегаты в cognos\ssas\hadoop\pentaho.
Это делалось еще 20 лет назад, до изобретения термина NoSQL.

Но это касается только аналитики по всему объему данных, а мелкие агрегаты можно и в materialized view хранить.
В MongoDB можно писать на js функции, которые будут выполняться на стороне БД, такой себе аналог join-ов — не нужные данные на клиент доставляться не будут. Если что, сложный джоин для мускуля — тоже не простая задача…
К сожалению, данными по сравнению скорости джоина и такой js-функции не обладаю…
Если нужны сложные джоины, то лучше выбирать взрослые БД, а не MySQL. В oracle и mssql джоины умеют очень хорошо оптимизировать джоины…

Ну и как обычно нужен кеш для «тяжелых» запросов.
— записывать данные сразу в нужном денормализированном формате, исключающем join
— использовать что-то вроде материализованных представлений

Да и фильтрацию по пользовтаельским условиям можно сделать на стороне базы, но тут не факт, что получится быстрее.
Записывать сразу в денормализованном виде — плохая идея, структура становится негибкой, новые функции становится сложно прикручивать.
Если различные практики простого (относительно) прикручивания новых функций при денормализованной записи для scheme free СУБД. Основная проблема это поддержание целостности в таких СУБД, которые не поддерживают транзакции :(
Как раз целостность обеспечивается записью денормализованных документов. (просто кусков JSON). А вот гораздо интереснее становится когда важно что внутри этого JSON.

Классический пример для NoSQL — БД фильмов, которая хранит фильмы, ревью, комменты к ревью. Каждый фильм это документ, которых хранит все связанные данные. Вот проблемы начнутся тогда, когда надо будет показать все комменты одного автора. А эта задача может появится сильно после того как будет выбрана структура данных.

И это простой кейс, могут быть гораздо сложнее, которые и индексами не покроешь.

А если разнести по разным документам, то получает отсутствие джоинов и транзакций, и все проблемы с этим связанные.

Можно хранить несколько документов, один все по фильму содержит, второй все по автору. Но тогда запись будет происходить в N (>> 2 в реальной системе) документов, что медленно и нетразнакционно. А обрабатывать изменения связей становится очень геморройно.
Можно хранить несколько документов, один все по фильму содержит, второй все по автору.

Именно подобные варианты я и имел в виду. Нужно или соблюдать ссылочную целостность, или обеспечивать гарантированное изменение N денормализованных документов с повторяющейся инфой, «развернутой» с другого конца.
Ну получается что надо:
1) хранить все джоины
2) вычислять джоины ркуками.

Джоинов в программе пропорционально количеству связей. А количество связей пропорционально квадрату количества сущностей.

Это повышает сложность разработки оооооооооооочень сильно. Прикрутить шардинг к любой SQL базе окажется гораздо легче. Это будет локальное одноразовое изменение.
Я не сравнивал. Просто констатировал, что изменение функциональности в целом меньшая проблема чем поддержание целостности в случае фэйлов.
Вы так говорите, как будто изменение структуры в SQL — простая и быстрая процедура в высоконагруженном проекте. Денормализация требует просто дополнительного отслеживания консистентности на уровне системного кода, что, конечно, вызывает трудности у тех, кто этого не умеет. Например, кеш — тоже денормализация.
Я еще не говорил про высоконагруженный проект. Вот например stackowerflow очень даже высоконагруженный, но они вполне допускают простои на час в неделю. Скорее всего как раз из-за накатывания изменений.

Кстати апдейт схемы проблема для MySQL, и вовсе не проблема для MSSQL, пока нету миллиардов записей.

Кеширование денормализованных данных и хранение денормализованных данных — две большие разницы. Денормализованные данные — фактически blob, как только вам становится важно что внутри — начинаются проблемы. Кеш обычно данные как есть отдает другому слою, не вникая. Разбираться в структуре кеша при записи не нужно, его можно просто пересобрать из storage.
Денормализация в общем смысле — просто хранение части данных в нескольких местах.
Про blob: подумайте внимательно, изучите разные NoSQL решения и кейсы их использования, и больше не пишите ерунды.
Для кеша вам тоже нужно понимать его структуру, если вы не хотите его полностью инвалидировать при любом (даже не связанном с содержащимися данными) изменении. Вообще говоря странно, что вы после подробной публикации о способах кеширования пишите подобную ерунду.
О денормализации нет смысла говорить пока никто не пытается разбираться со структурой денормализованных данных.

Я изучал разные NoSQL, некоторые приблизились по надежности к SQL, не потеряв удобства. Увы MongoDB не один из них, хотя де-факто это стандарт в мире NoSQL, на который равняются.

Что касается кешей и их инвалидации, то это называется тегами, в некоторых системах поддерживается явно, если не поддерживается явно, то можно прикрутить. Наличие тегов как раз позволяет не лезть внутрь закешированных данных.
Пока не выявлены нагруженные запросы, вы правы, никакого смысла в денормализации нет.

MongoDB ничуть не стандарт — просто наиболее разрекламированная как якобы универсальная. NoSQL базы обычно заметно более специализированны, нежели традиционные SQL-хранилища, поэтому о едином стандарте говорить бессмысленно. А равняются обычно на действительно крутые базы: Google BigTable/Spanner, Amazon Dynamo итп.

С кешами не всё так просто. В первом приближении, действительно, хватит тегов (хотя уже логика простановки тегов выдаёт структуру кеша). Далее, уперевшись в производительность хранилища, имеет смысл только частично обновлять кеш. Далее, можно переходить на персистентное хранилище для кеша, чтобы при перезапусках не было длительного простоя на разогрев, и при отсутствие данных не нагружать основное хранилище. Далее, для кеша можно использовать что-нибудь более структурированное, нежели простейший key-value типа memcached. Далее, в «кеше» можно данные разделять, и отдавать частично — например, диапазонами. Далее, можно не складывать в такой «кеш» высокодоступные данные в in-memory хранилищах, и использовать его как «индекс», или наоборот, хранить какие-нибудь частоизменяемые счётчики и флаги только в нём. Итд.
Тут на самом деле грань между кешем, индексом и денормализацией данных очень тонкая, и одно в другое при развитии проекта может переходить весьма легко. Я предлагаю обобщить это всё, называть денормализацией и применять единый подход к поддержке консистентности.
Предлагаю как раз не обобщать. Ибо любое обобщение скрывает детали, которые могут оказаться крайне важны.

По поводу кешей — все гораздо проще. Ибо если не валить все кеши в кучу, то очень легко разобраться когда и какой кеш нужен и как его инвалидировать.

Я уже писал что кеш нельзя просто включить, нужно думать головой. Кстати стратегия «сбросить кешь по ключу\тегу» при записи работает для среднего приложения всегда. Теги при этом управляются вызывающим кодом и не требуют обработки данных в кеше.
Точнее сказать, джоины там делаются прямо в структуре данных зачастую ценой денормализации. А вообще, мыслить джоинами на уровне данных не всегда правильно. И уж совсем неправильно пытаться переносить sql-приемы на nosql.

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

Удобства nosql'я начинают проявляться, когда надо работать с документами и фактами (неизменяемая информация).

И самое главное, внимательно читать описание конкретной системы, а не слушать всяких товарищей, которые пишут — «в nosql отсутсвуют множественные индексы».
Просветите-ка меня касательно secondary indexes в hbase…
В цитате ясно написано про nosql, а вовсе не про hbase.

Так и рождаются форумные мифы — сначала говорили про одно, потом обобщили на другое, причем, каждый на свое.

А потом люди ходят и говоят «мы на форумах читали что у вас там индексов нету никаких и данные теряются на каждом шагу ...»
подход поднять обе базы работает на любых данных, в том-то и прикол.

Когда у вас более конкретные описания данных (порядки объемов, связей), и конкретные требования к производительности всего этого на каком-то конкретном железе, то затраты на «выявить какая база нам лучше подходит», можно очень сильно уменьшить. Если в команде есть сторонники каждой базы, выдаются им требования и железо для тестов, время на моделирование, по истечению которого они приносят цифры. Вам интересна «Скорость разработки и корректность данных»? Значит, кто первый принесет, у кого тесты будут проходить, у того выше скорость разработки.
Не до конца понимаю пост. Вообще, NoSQL — это не «не-SQL», а «не только SQL». Появились из-за того, что до некоторых людей дошли общеизвестные сейчас вещи. Когда известно, что именно из CAP нам нужно — можно реализовать это хоть на SQL, хоть на NoSQL-решениях, либо сделать собственное NoSQL-решение. При чём тут MySQL и MongoDB? Транзакции и атомарность в NoSQL — достижимы, пока мы не пытаемся выпрыгнуть за пределы CAP.

Если одной машины хватает, то проблем с CAP-теоремой не возникнет. Если нет — выбираем, что мы хотим в данный момент (доказано, что нельзя получить C, A и P одновременно, но обеспечить разные комбинации в разные моменты времени — пожалуйста).
Если одной машины хватает, то проблем с CAP-теоремой не возникнет.


B MongoDB одной машиной по определению пользоваться нельзя в production. Так что она действительно в какой-то степени «broken by design», как в заголовке одной из ссылок в начале статьи. Конечно, не MongoDB единой жив не-только-SQL.

У меня лично проблема с использованием не-SQL баз заключалась в первую очередь с отсутствием поддержки в генераторах отчетов типа BIRT-a. Только в последнее время понемногу начали прикручивать, вроде. А еще-бы найти генератор отчетов, который данные из REST Web сервисов умеет вытаскивать.

Ну а как только у нас появляется вторая (сотня) машин, ни с SQL-базами, включая MySQL, ни с noSQL чудес не бывает. Либо мы ослабляем консистентность, либо заставляем пользователей ждать минуты из-за проблем с A или P (с несколькими удобными для практического использования компромиссами). Отсутствие этих чудес формально доказано. Почему автор мешает реляционность, транзакции и консистентность в кучу и рассматривает только mysql vs mongodb — не представляю. Да, мы можем выбрать CA и AP одновременно для разных вещей, но для CA не обязательно использовать MySQL и вообще SQL.
И даже больше: если очень хочется, то можно использовать тот же MySQL для CP или AP в том числе.
До чего руки дошли. MongoDB и MySQL — самые простые представители двух миров. Уровень входа: школьник.
Может быть, не самые простые, а самые популярные?
Самый популярный все же SQLLite, его использует каждая 20 программа, а весь Android просто выводит в другую весовую категорию.
Что бы не говорили(MySQL — The world's most popular open source database), я с трудом верю, что количество ежедневно используемых экземпляров вывалило за миллиард. И лично у меня, три программы на PC используют SQLLite, точное количество программ на андроиде сосчитать сложно.
Извините, но большинство из говорящих «монго нельзя использовать на одной машине» абслютно не в курсе сути проблемы, а просто слышали чье-то мнение. А, тем временем, никакого волшебства там нет — что именно происходит в каждом конкретном случае описано в документации. И как обеспециваеется надежность тоже. Вся эта паническая боязнь происходит только от нечитания документации и привычек к майскулю.
Не то чтобы я абсолютно не в курсе проблемы, и документацию читал, и официальный курс проходил на education.mongodb.com, во время которого подчеркивалась необходимость в минимум трех инстансах для production. И форумы курил, в которых народ жаловался на то, что при OOM у них целостность базы иногда нарушалась, что при единственном инстансе равнозначно потере данных от последнего бэкапа. Кстати, если взять CouchDB, к примеру, то у него целостность данных очень даже замечательно обеспечивается.

Так что никакой паники нет, а привычка к базе (не MySQL в моем случае), которая не теряет все данные при падении сервера — есть :-)
Официальный курс, этот который m102 для dba? Тогда лучше m101p послушать, там как-то все более углубленно рассмотрено. Что касаемо докуметации, то

With a journaled write concern, the mongod acknowledges the write operation only after committing the data to the journal. This write concern ensures that MongoDB can recover the data following a shutdown or power interruption.

А на форумах еще много чего пишут. Например, удивляются что Монга может откатить ренее закомиченные данные в репликасете. Хотя эти тонкости тоже указаны в описании механизма автоматического фейловера. (гуглим — Replica Acknowledged)

Привычка к нетеряемым данным проходит с годами. У меня прошла еще когда новейший (на то время) postgresql версии 8.4 однажды сказал мне, что не в состоянии отрековериться. Да, кстати, я тоже помнится, негодовал по этому поводу на форумах :)

Напоследок, о Монге. Если действительно есть ограничение по ресурсам и только одна железная машина, то никто не мешает поднять два инстанса на ней (ну мало ли, вдруг там диск второй есть, хоть на него ще записать — и то хлеб). Только лишь, надо не забыть обеспечить мажорити в реплике.

Поднять 3 инстанса на одной машине? :)
Ну мало ли, как в жизни случается.
На самом деле можно всего два, только надо вотесы поставить правильно.

Если уж мы дошли до того, что говорим о надежности в рамках всего одной физической машины, то может у нее хотябы еще один диск есть, куда данные дублировать можно на худой конец…
Конвертор MySQL запросов в Mongo. www.querymongo.com/
Далеко не всегда оптимален, но для отладки того или иного случая может оказаться полезен.
Простите, а для чего, чисто теоретически, может понадобится этот инструмент??
Для первых суток изучения Монго.
Странный пост. С одной стороны, очевидное: нет никакого смысла для хоть сколько-то технологически сложного проекта иметь только одну базу данных, с другой, предлагается использовать mysql и mongo вместе, что несколько странно в большинстве случаев.

В реальности, баз данных сейчас существует великое множество, не только SQL и NoSQL, но и NewSQL (например, VoltDB, прекрасно работающий, с сотнями тысяч транзакций в секунду, и прозрачно масштабируемый). Помимо этого, есть различные внешние решения для SQL, решающие их проблемы масштабируемости и отказоусточивости. В рамках есть богатые возможности для выбора между знакомыми разработчикам и админам технологиями и новыми для них, но лучше подходящими под задачи. Главное, разбираться во всём этом многообразии баз, с чем, к сожалению, у подавляющего большинства принимающих технологические решения есть проблемы, в результате чего применяются их «любимые» и не слишком подходящие технологии.
Ну так процесс решения задачи такой:
— Ищем похожую задачу, уже решённую.
— Нашли? Используем решение.
— Проблемы? Решаем проблемы.

Дело не в технологической неосведомлённости, а в том, что знакомая дорога всегда кажется короче.
… и решение проблем в неизвестной технологии отнимает 90% ресурсов
Это уже потом, когда решение давно принято и что-то менять очень дорого.
с другой, предлагается использовать mysql и mongo вместе, что несколько странно в большинстве случаев

Скорее исходя из соображений, что эти СУБД а) открыты б) с большой вероятностью знакома хотя бы одна и в) много учебных и справочных материалов
Судя по рынку вакансий, redis несравнимо популярней mongo, при том что он несравнимо проще, надёжней и производительней.
Redis вроде как просто key-value storage, на полноценную СУБД не тянет и чаще всего используется для кэширования, сессий и т. п. где в основном два типа операций записать по ключу, прочитать по ключу. Поиск по значению уже проблематичен. Или даже поиск по ключу типа between key1 and key2
Помимо обычных ключей и хешей там есть множества, взвешенные множества, есть битовые маски и прочие приятные штуки типа pub-sub, транзакций и lua-скриптов. Как ни странно, этого достаточно, чтобы безусловно очень крупный youporn целиком на них переехал. На моём опыте редис удобен для хранения высокодоступных и частоизменяемых данных типа счётчиков, пользовательских флагов итп.
Ну я и говорю — записать по ключу и прочитать по ключу :) Проблема использования Редиса как «обычной» СУБД в том, что он асимметричен, key и value разных типов (хэши, множества и т.д.) не равноценные сущности. Наборы операций над ними разные как семантически, так и технически. В «обычных» же СУБД, что SQL, что NoSQL (афаик) ключевые поля практически ничем не отличаются от остальных.
Вообще говоря zest в редисе умеет between, и в базах данных нередко встречаются сущности разных типов, как всякие кортежи итп в Postgres'е, так и специальные типы данных вроде счетчиков в Cassandra. Реально серьезный недостаток в redis'е — отсутствие вторичных индексов, при надобности эмулируется на уровне приложения или lua-скриптов
Это что ли долго или дорого — поднять обе базы?

Если под «поднять» понимать не только sudo apt-get install, а полное администрирование, то заметно дольше и дороже одной. Вплоть до увеличения штатов админов.
Для каждого набора данных вы сможете на лету решать, куда его положить.

Проблема в том, что очень быстро окажется, что часть данных нужно хранить и там, и там, и не просто хранить, а синхронизировать. Причем зачастую изобретая какой-то механизм транзакций над двумя базами одновременно. Очевидное решение «начинаем транзакцию на SQL, делаем все что нужно с SQL, делаем все что нужно с NoSQL, подтверждаем транзакцию» может оказаться неприменимо.

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

Полное администрирование нескольких бд конечно сложнее, но избавляет от геморроя для админов в последствии, когда перегружается центральная бд, и после, когда не хвататит производительности master — много slave'ов на запись. Дальше, конечно, применяется партицирование, что на уровне приложения означает переделывание его значительной части, а на уровне БД — хрупкое и требующее очень чуткого сопровождения решение.

Что касается денормализации данных: внезапно, для значительного повышения производительности и эффективности использования ресурсов, с определённого момента это необходимо. Простейшие транзакции — блокировки — реализуются миллионом разных способов, вплоть до простейшего в мемкеше/редисе.

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

Проблема в том, что простейших транзакций часто недостаточно, если требуется использование двух и более СУБД. Особенно если одна из них транзакции не поддерживает вообще и нужно создавать механизм отката неудачных действий для неё, если они должны выполняться первыми.

Важная часть умений хорошего разработчика, но, увы, далеко не все такими являются. Я, например, за собой часто замечаю, что переключаясь из парадигмы в парадигму (будь то ФП <-> ООП или РСУБД <-> ДОСУБД) тащу некоторое время «остатки» предыдущей. Собственно поэтому стараюсь писать большими кусками в одной парадигме с обязательным пересмотром в конце куска его начала и искоренения остатков «вражеской» парадигмы до коммита/пуша :)
На самом деле, очень редко требуются сверхнадёжные транзакции, часто просто достаточно отсутствия конкурентный изменений и eventual consistency.
По какому критерию различать когда требуются сверхнадежные, а когда нет? Заказчик обычно требует все надежное, будь-то финансовые транзакции на миллионы или десяток лайков.
В целом согласен, но. Увеличивая количество технологий в проекте мы увеличиваем сложность его расширения и поддержки в будущем, цену разработчиков. В идеальном мире любой студент первого курса знает C, C++, Objective-C, Java, JavaScript, HTML, CSS, SQL, noSQL, Windows, OSX, NIX, network, frontend, backend… В реальности сотрудники как правило хорошо знают 1-2 технологии, остальные — сильно по верхам. И если на проекте вместо одной базы данных используется две — это автоматически означает, что ряд задач будут требовать одних сотрудников, другой ряд — других. А задачи на обе базы одновременно — тех немногих сотрудников, которые достаточно хорошо владеют обоими технологиями.

Телепатия подсказывает, что у тебя, читатель, в голове сейчас мысль — «да что он пургу гонит, монгу любой школьник за выходные освоит, в интернете полно тюториолов 'монго за два часа' и проста она аки лапоть». И я даже соглашусь с этой мыслью — адекватный специалист может за сутки «быстро въехать» практически в любую технологию. К сожалению, быстро разобраться по верхам и практический опыт использования со знанием нюансов — это две большие разницы. И если мы пишем софт за деньги, а не опен соурс проект удовольствия ради — то применять малознакомую технологию — это риски, позднее выливающиеся в повышенное объемы технического долго и нёх повышенного диаметра.

Я видел вживую нёх с двадцатиметровым размахом крыл — когда после нескольких месяцев работы оказывается, что выбранная база данных не поддерживает репликацию на данных заказчика. В песочнице и на тестовых данных поддерживала, а как к реальным данным подключили — репликация начала умирать случайным образом раз в несколько дней. Как показали раскопки — технологию применили «немного не по назначению» о чем знали специалисты с 3+ годами опыта, но не знали спецы, которые технологию изучали «походу дела». И когда понимаешь сколько миллионов вполне реальных денег стоил этот «выбор наилучшего инструмента под задачу» — начинаешь по другому смотреть на пожилых дядек, которые делают проекты с использованием древних технологий. Не потому, что они такие зашоренные и узклобые — а потому, что они точно знают чего от этих технологий ожидать.
Фраза «нёх с двадцатиметровым размахом крыл» добавилась в мой разговорник, просто-таки впечаталась в мозг. По теме — полностью поддерживаю, решение одного «спеца», которое он применил в одном мобильном приложении, сейчас стоит компании десятков тысяч долларов на одновременную поддержку, выпиливание и рефакторинг.
sql backend, nosql frontend — не такой уж и новый тренд. все окей.
Так почему бы просто при старте любого проекта (масштабами покрупнее «домашней страницы моего кота Васьки») не поднимать оба типа баз данных?
Зачем сразу-то поднимать? Почему не сделать это по мере необходимости?
Это и имеется в виду. Просто предполагается, что заранее известно, что проекту одного типа БД не хватит.
А тем временем даже выборка в PostgreSQL с hstore (расширение для хранения и работы с JSON) в версии 9.4 происходит быстрее чем в MongoDB: obartunov.livejournal.com/175235.html Не говоря уж про запись.

У Монго остается единственное преимущество: шардинг «из коробки». Но не так уж много проектов есть, для которых это жизненно важно.
Еще в копилку к плюсам Монги (помимо шардинга)
+ schema less
+ отсутствие impedance mismatch
То же самое и в Mysql — Handlersocket и memcaached api, странно что автор не упомянул, что оба этих мира есть в одном продукте с двумя интерфейсами и без дублирования данных.
Если честно, MongoDB ужасный выбор, выбирайте что угодно другое (тот же redis, шардится без проблем, ACID при настройке)

Я выбрал точно также как и Вы выше в комментарии на этапе начала разработки (mysql — транзакции, mongo — документы, товары), в итоге теперь все приходится переписывать с нуля, проблема? Дело в том, что MongoDB хорош для разработки в nodejs, идеально подходит, в любом другом языке Вам придется корячиться, чтобы разобраться со всеми его коммандами или же изучать совершенно не конвенциональный подход (модули и т.п.).
После redis, синтаксис mongo это просто ужас и оверкилл безумный. Я понимаю сравнение не подходящее (redis все-таки key-value), но это первое что приходит на ум с фразой «легкость пользования».
Ну, например, я работал с MongoDB в Python. И до сих пор периодически что-то пописываю в этой связке. Не понимаю о чем вы.
Аналогично. Написал не один веб сервис с Монго+Пайтон. Все было отлично, здорово и быстро!
Прошу прощения за отход от темы, но решены ли проблемы с Монго-пожиранием памяти? (Особенно на VPS)

Обязательно ли ставить его на отдельный сервер?
Давно уже поставлена точка в споре SQL vs NoSQL.
Polyglot persistence и всё тут.
Раз уж зашла речь о базах данных, разъясните, пожалуйста, такой вопрос по теореме CAP.

Все реляционные БД относятся к классу CA, однако сама по себе реляционность не является критерием CAP-теоремы. Почему не существует CP и AP реляционных БД?
Реляционность — это ведь о связности данных, их зависимости друг от друга. А P — это «partition tolerance», устойчивость к разделению. Так как же можно гарантировать устойчивость связности данных при теоретически случайных разделениях базы?
Очень просто — partition ignorance называется. То есть если между узлами базы пропала связь, то почти все NoSQL базы этого не замечают, распадаясь на независимые части, синхронизируя данные после восстановления связи.

НО. Consistency от этого падает, в некоторых случаях до нуля. Например система по продаже билетов при разделении нод базы потенциально может продать два билета на одно и то же место. Никакая логика приложения не поможет избежать такого случая.
Адекватность поведения баз при split brain — тема длительного исследования, и результаты большей частью безрадостные:
aphyr.com/tags/jepsen

Что касается примера, логика базы/приложения без требований к availability может просто отказать в покупке билета или отложить в очередь, если нужная часть базы по каким-либо причинам требует времени для восстановления консистентности — в этом случае «двух билетов» продать не удастся.
Это переводит систему из разряда AP в CA. Тут возникает другая проблема, типичная для NoSQL.
И вот две «куда-то» потерялись. То есть остальные 8 их не видят. Часть приложения видит две ноды, часть видит 8.

Внимание вопрос — продавать билеты? Вариант поставить в очередь не катит, ибо человеку билет нужно напечтать. Откатить естественно тоже нельзя.

Если да, то где гарантия что не продадут два билета? Если нет, то на кой нам 10 шард и MongoDB вообще? Что делать если две ноды потерялись надолго (умерли машины)?
И здесь выходит на первый план маркетинг, который говорит что да, нужно продавать 2 билета. В 99% случаев после восстановление связности базы и обнаружения конфликта менеджер разрулит его (предложит одному из клиентов другой билет, даст скидку, закажет дополнительный рейс\вагон\автобус, просто извинится и вернет деньги). Продать 2 билета — лучше, чем не продать ни одного, A — важнее, чем C или P. Это один из краеугольних принципов Монги.
Это называется приуменьшением потенциальных проблем. Нет никакой гарантии что это два билета. Можно продать ползала\вагона\салона_самолета два раза в таком случае. Это удар по репутации гораздо сильнее, чем накладные затраты на разруливание. А если еще учесть что Монго не делает acid записи в принципе, то становится совсем грустно.
Это удар по репутации гораздо сильнее, чем накладные затраты на разруливание.

Это нужно решать до проектирования системы.
Если даже продать 2 зала\вагона\салона_самолёта — у компании появятся деньги и возможность подумать головой и решить конфликт. Да, если тормозить — можно потерять и клиентов, и репутацию. Но ведь можно и не тормозить?

А если эти 2 зала\вагона\салона_самолёта сразу отправить нафиг — то тут уже ни денег, ни возможностей. Сиди только и радуйся, что у тебя база целая.
Да ладно, механизмы кворумов придумали давно. При правильном применении так часть, где 8 будет нормально работать и продавать билеты, а та часть где две ноды осталось уйдет в даун. Админы поменяют настройки NLB и через 20 минут все пользователи пойдут на живые ноды.Но это не с mongo.

Если Монго не предлагает третий вариант, то это не значит что его нет ;)

Вообще из-за хайпа вокруг NoSQL появилось дофига «школьников», которые не знают про подходы, используемые в РСУБД десятилетиями. Зато хорошо повторяют маркетинговый буллшит NoSQL. Вот и получаются такие опусы.
MongoDB — сам по себе неудачный пример — распределённое хранилище можно делать и со своей логикой. Например, кластер zookeeper'ов для синхронизации и центрального принятия решения, и ноды с неважно-каким-хранилищем. В рамках этого, «пропавшие» ноды просто помечаются в зукипере как нерабочие, и пока те полностью не синхронизируются с актуальными данными — не помечать обратно. Если пропало 2 ноды, и часть актуальных данных была только на них — это печально, но такое хранилище не может дать возможность изменять эти данные, в частности, покупать билеты.

Так что вариант — поставить в очередь, с возможностью отказа от покупки — вполне вариант.
А если часть системы смотри в две ноды, а другая часть в 8, как они себя будут вести?

Вариант с очередью е вариант, потому что клиент стоит у кассы и ему надо напечатать билет или отказать.
Без Consistency современные РСУБД не имеют смысла, так как базовые гарантии, типа целостности внешних ключей, нельзя выполнить.

РСУБД на одной машине является CA, а на P насрать, его не бывает. В failover режиме БД становится почти CAP, но A и P нестрогие, то есть при некоторых условиях база становится недоступна. В зависимости от вероятности наступления таких условий и можно гарантировать заданный процент доступности при ACID гарантиях.
Но обычно это дорого, вернее ДОРОГО.

NoSQL предлагают дешевый способ организовать AP, теряя consistency (даже в случае acid гарантий записи).

Тут нужно понимать что C,A и P это не просто атрибут, который есть или нет. Нужно понимать в каких условиях достигаются эти параметры, а в каких нет.
По секрету скажу, что кроме документоориентированных субд и реляционных есть и другие виды. Например — графовые. Например — OrientDB. И всякие реляционные и всякие документоориенторованные являются лишь частными случаями графовых. Конкретно OrientDB поддерживает и sql-запросы по базе, и выборки по ключам, и указание схемы, и прямые линки между «документами», и даже наследование между «таблицами».
Cуть в том что NoSQL и SQL подходы можно использовать установив одну единственную СУБД, на столько серверов, сколько вам необходимо. И это не какая-то обходная фича — это официально-рекомендуемый производителем набор подходов к построению БД.

В СУБД Cache — есть возможность использовать прямой доступ и глобалы — это чистый NoSQL ( значительно больше чем просто key-value) — только не новый, собранный в 2000х, а десятилетиями опробованная технология (MUMPS).
В СУБД Cache — есть SQL — то есть вы можете проектировать и разрабатывать вашу БД как обычную реляционную БД.
В СУБД Cache — есть возможность создавать объектные БД.

И конечно же вы можете комбинировать любые эти подходы в любых количествах и в любом необходимом вам месте, так как считаете необходимым.

Я в своём проекте использую прямой доступ (NoSQL), работал также и с SQL — сейчас пока не требуется. С объектным подходом лично не работал.
Sign up to leave a comment.