MongoDB for Developers and DBA

    Заканчиваются курсы по MongoDB для разработчиков и архитекторов баз данных от 10gen, компании разработчика MongoDB.
    Финальный экзамен отправлен на проверку и хотелось бы поделиться впечатлениями от курса и полученной информации, рассказать о плюсах и «минусах» MongoDB.


    Общее впечатление от курса


    Я записался сразу на два курса, для DBA и для разработчиков. В целом нагрузка не слишком большая, в неделю уходило 3-4 часа на просмотр видео и 1-2 часа на домашнее задание в очень неспешном темпе. При желании я думаю временные затраты можно сократить раза в два.
    В целом впечатления положительные. Несмотря на то, что большинство информации, которое представлено на курсах можно почерпнуть из официальной документации, осваивать материал через курсы гораздо интереснее. Я и раньше слышал о MongoDB и пару раз «щупал» что это такое, но после курсов появляется более глубокое понимание возможностей и сферы применения этой базы данных. Поначалу были кое-какие накладки. Несколько моментов были связаны с формулировками вопросов, которые подразумевали неоднозначные ответы, но воможно это была проблема с пониманием английского языка. Затем было пару проблем с обнулением результатов, и кое-какие накладки из-за урагана Сэнди. Был веселый вопрос, который я назвал «Mission Impossible», в котором надо было выбрать один из трех вариантов ответа. При этом для ответа на вопрос дается обычно три попытки.

    Сильные стороны


    Репликация (manual)

    Репликация настраивается легко: запускаются серверы с указанием имени реплики, настраивается конфиг, участники реплики выбирают PRIMARY сервер, остальные становятся SECONDARY серверами. При этом можно настроить приоритеты для каждого сервера, можно вообще запретить серверу становиться PRIMARY. PRIMARY сервер позволяет производить операции запись-чтение, с SECONDARY серверов можно только читать.
    При падении сервера есть много нюансов, в зависимости от того, SECONDARY или PRIMARY сервер упал, была ли запись в PRIMARY сервер после того как он стал недоступен и был выбран новый PRIMARY сервер и т.п. Но в целом в большинстве случаев восстановление работы реплики автоматизировано и не потребует ручного вмешательства, кроме как поднять упавший сервер.

    Шардинг (manual)

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

    Географические индексы (manual)

    Сейчас многие стартапы или соц. сети используют функционал вида: найти что-то, не дальше чем X км от пользователя. Вот для такого функционала в MongoDB можно использовать географические индексы.

    Schemaless

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

    Capped коллекции (manual)

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

    Aggregation framework (manual)

    С помощью данного фреймворка можно из исходных данных формировать выборки с группировкой, суммированием, подсчетом записей и т.п. По сути это реализация GROUP BY, COUNT, HAVING и т.п. конструкций в SQL. Исходные данные проходят через массив так называемых pipe, которые преобразовывают данные и отдают их в следующий pipe. Очень похоже на консольные команды вида: «cat file | grep boobs | grep -v small».

    Map-Reduce (manual)

    Если возможностей Aggregation Framework недостаточно, можно использовать MapReduce функционал. На вход map функции подаются данные, преобразуются и подаются на вход reduce функции.

    Подводные камни



    Ограничение составных (compound) индексов

    Если у вас есть запись вида: {a: [1, 2], b: [1, 2]} — создать индекс {a: 1, b: 1 } не получится. Собственно как и вставить подобную запись с полями, которые проиндексированы. Подробнее тут, ищите «Compound Multikey Indexes May Only Include One Array Field»

    Sparse индекс и уникальность (manual, Sparse Indexes)

    Допустим у нас есть записи в коллекции:
    { "_id": ObjectId(«50caeec479705c3852e9e61b»), «a»: «1» }
    { "_id": ObjectId(«50caeeeb79705c3852e9e61d»), «a»: «2», 'b': 1 }
    { "_id": ObjectId(«50caefb179705c3852e9e621»), «a»: «3» }
    и мы хотим чтобы свойство «b» у документов было уникальным. Создать обычный уникальный индекс не получится, первая и третья запись будет считаться что b: null и это нарушает уникальность.
    Но мы можем создать уникальный sparse индекс, и тогда записи, которые не имеют «b» будут не включены в этот индекс. Казалось бы все хорошо, индекс создали, уникальность есть. Но! Если допустим мы попросим выбрать все записи из нашей коллекции и попросим их отсортировать по полю b, MongoDB использует созданный нами sparse индекс, в котором отсутствуют записи без «b». В результате на выходе мы получим только одну запись.

    Зависимость от интерфейсов приложения

    В курсе неоднократно отмечалось, что в MongoDB удобно хранить документы, так, как они используются для вывода. Допустим у вас есть блог, там комментарии. Рядом с комментарием выводится имя автора и email. Удобно в объекте, который хранит комментарий также хранить информацию об авторе. Соответственно если у вас что-то поменяется в этом плане — есть вероятность, что надо будет изменять место хранения данных. В принципе это не совсем уж подводный камень и вероятность такого развития событий мала, но что-то в этом утверждении мне не особо понравилось.

    Нельзя сменить shard key

    После того, как коллекция была разнесена, поменять ключ автоматически не получится. Поэтому выбор ключа очень важная операция. Подробнее docs.mongodb.org/manual/faq/sharding/#faq-change-shard-key

    Отсутствие транзакций в пределах нескольких документов

    Операция над одним документом атомарна, а вот для нескольких докуметов предлагается использовать транзакции на уровне приложения docs.mongodb.org/manual/tutorial/perform-two-phase-commits

    Вывод


    Отличные курсы. MongoDB подкупает своей гибкостью и простотой, ее использование в различных ситуациях весьма и весьма оправдано.
    Если у кого возникло желание пройти курсы, 21 января курсы стартуют еще раз. Так же 25 февраля стартуют курсы для Java-разработчиков. https://education.10gen.com/
    Share post

    Similar posts

    Comments 40

      +5
      «Финальный экзамен отправлен на проверку...»
      Проверка после 20 декабря. Не пиши так! А то я не все доделал и слегка напугался… O_O
        +1
        Финальный экзамен в DBA классе до 20го можно сдавать. Я имел ввиду что я написал ответы и нажал кнопку Submit на последнем вопросе и получил в ответ «Submited». Формально, мой экзамен отправлен. Извиняюсь что напугал.
        +1
        Говорят, map/reduce в монге блокирующий. И медленный. Т.е. попытка собрать статистику по нескольким миллионам записей будет не очень приятным сюрпризом. Поправьте, если не так.

        Кстати, ещё в копилку к подводным камням: count с условием игнорирует индексы и вообще жутко медленный.
          +3
          «Говорят, map/reduce в монге блокирующий.» Нет. Не блокирующий. Поэтому при интенсивной записи можно получить не корректную статистику.

          «И медленный» Собирал статистику на 6 миллиардах записей. Медленно, но у меня был один сервер. Потенциально есть возможность ускориться за счет применения шард.

          «count с условием игнорирует индексы» count — это метод курсора запроса. Т.е. индексы использует. Просто может показаться — запрос не попавший в индекс но с лимитом выполнится быстрее, т. к. полного сканирования не происходит. А count выполнит сканирование.
            +6
            На счет count я всё таки настаиваю.

            И map/reduce всё таки блокирующий, хоть и местами:
            • read lock на каждые 100 документов
            • The JavaScript code (i.e. map, reduce, finalize functions) is executed in a single thread, taking a JavaScript lock;
            • The insert into the temporary collection takes a write lock for a single write.

            Самое грустное что map/reduce — однопоточный. :(
              0
              Спасибо за замечание!
              Я, оказывается, обычно использовал тот count, который внутри аггрегатора.
              +2
              Практика MongoDb до v 2 —
              MapReduce медленный из-за того, что при сканировании вся коллекция блокируется, что отражается на производительности.

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

              соunt — полной сканирование всего первичного индекса. Быстро, но недостаточно…
            +2
            В курсе неоднократно отмечалось, что в MongoDB удобно хранить документы, так, как они используются для вывода.

            Немного поправлю. MongoDB является документо ориентированной БД. Т.е. все что мы храним это «документы».
            Допустим у вас есть блог, там комментарии. Рядом с комментарием выводится имя автора и email. Удобно в объекте, который хранит комментарий также хранить информацию об авторе. Соответственно если у вас что-то поменяется в этом плане — есть вероятность, что надо будет изменять место хранения данных. В принципе это не совсем уж подводный камень и вероятность такого развития событий мала, но что-то в этом утверждении мне не особо понравилось.

            Вообще монго не является реляционной БД, хотя какие-то отношения между объектами можно построить. Часто при построении объектов применяется де нормализация, как в вашем примере. С помощью нее можно добиться большого прироста производительности и удобство хранения, но конечно есть и ограничения. Скорее это подводный камень де нормализации а не монго.
              +1
              Что касается шардинга:
              — после переконфигурации — перемещение данных между шардами запускается автоматически — это точно.
              — нельзя обращаться к шардам напрямую, только через mongos
              — При решардинге рекомендуется все данные шард разбивать пополам или на части кратные степени 2.
                +3
                Периодически с моим крайне несовершенным английским некоторые вещи вводили в ступор. Списывался с англичанином, его путало тоже :) Говорит, много американизмов.
                  +7
                  Я все ждал, когда же будет такой пост.
                  Немного моих ощущений от курса:

                  Я к сожалению не записался сразу на DBA, хотя к 5ой неделе стало интересно, мне было интересно не столько прохождение экзамена, сколько послушать материал который там дают, Как уже сказано выше 21 Января будет стартовать очередной курс DBA, на который я уже записался, но если есть желание просто ознакомится с материалами лекций, добрый человек уже собрал все видео в списки на youtube

                  Из основных плюсов для меня были:
                  + mongo + python в заданиях
                  + неплохие лекции, в которых разжевываются большинство тем. Материал на английском, но понимать речь довольно легко, если есть проблемы, автоматический субтитры на 60-70% правильно распознают речь (кроме специфических слов mongo, db etc.)
                  + community

                  — в курсе for Developers не было ни слова о MapReduce
                  — задания иногда можно перевести по разному. Тут наверное лучше всего характеризует состояние дел фраза из обсуждения одного задания:

                  — "… agree, and those are the hardest for not-native-english-speakers."
                  — «Heck I'm a native English speaker and I evaluate the crap out of what each of the statements mean.»

                  Ну а теперь плюшки, очень хотел поделиться со всеми снипетом для build mongo в SublimeText2, но на пост это никак не тянуло:
                  Tools -> Build System -> new build system
                  {
                  	"selector": "source.js",
                  	"shell":true,
                  	"cmd": ["mongo < ${file}"]
                  }
                  

                  сохраняем, пользуемся (CTRL+B)
                  Вроде 3 строчки, но у меня заняло 2 часа чтобы найти как правильно передавать параметры в shell

                  чем удобно:
                  + привычная подсветка кода + multiline
                  + результат билда открывается в консоли sublime (ошибки компиляции тоже показываются)
                  + не нужно переключаться между редактором и консолью и копипастить
                  + синтаксис тот же что и в mongo shell + js

                  use test;
                  //очистили базу если там что то было
                  db.test.drop();
                  //заполнили ее заново
                  for(var i=0; i< 100; i++){
                        db.test.insert({a: i, b:i, c:i});
                  }
                  
                  //query
                  db.test.find().limit(5).pretty();
                  


                  — мне пока не удалось сделать mongoimport прямо из скрипта
                    0
                    MapReduce нету, зато про Aggregation Framework много.
                      0
                      Aggregation Framework только в 2.2 появился. Я думаю что MapReduce в изначально именно как механизм для реализации аггрегирующих операций появился, с появлением Aggregation Framefork необходимость в его использовании снизилась, всё-таки он медленнее и сложнее.

                      Думаю MapReduce в Монго уйдёт в специфическую область, тем более для него Hadoop можно использовать.
                    0
                    Сори не в тему. А кто-нибудь знает ресурс который отслеживает все it и около курсы?
                    0
                    Кстати, к минусам (субъективным) могу добавить формат лекций.
                    На мой взгляд видеоформат — это не то, что нужно для таких вещей.
                    Нужен текст, по которому можно будет быстро пробежаться глазами.
                      0
                      Спорно. Это личные особенности — многим нравятся туториалы в формате видео. На Youtube такие популярны.
                        +1
                        Я бы сказал, что текст нужен в дополнение, чтобы не бегать по видео. А само видео убирать не нужно — там все как и должно быть: «ручкой» по «бумаге», а не готовая презентация.
                          +1
                          Меня в этих лекциях больше всего напрягала рука, мечущаяся по экрану. Лучше бы просто курсор оставили.
                          +3
                          В некоторых случаях полезно использовать Sparse для экономии памяти,
                          например, я в одном из проектов использовал поле "{ update:1 }", для маркирования объектов для передачи в другую систему, при обычном индексе и коллекции в 1М объектов, данный индекс весил порядка 250Мб, после переключения его на «Sparse-индекс», вес индекса был всего несколько килобайт, т.к. объектов для синхронизации, всегда, было не много.
                            +3
                            Да, отличный курс… Было довольно интересно. Exams еще не делал, просто просмотрел. Никаких сложных моментов там не углядел. Думаю сделаю на выходных…

                            Для себя из курса вынес понимание, что MongoDB это не СУБД в общем смысле этого слова (а ля MySQL, PostgreSQL или, не приведи господь, Oracle). MongoDB — это storage (а la BerkeleyDB, только намного мощнее). Сами монговцы используют именно это слово… Базой данных MongoDB станет вместе с вашим приложением.

                            Многое из того, что «взрослые» CУБД делают автоматически вам в приложении придется делать вручную… Но это дает вам очень плотный контроль за производительностью, масштабируемостью и надежностью системы. Возможности кластеризации как у весьма серьезных СУБД. Учитывая объем кодовой базы, это весьма неплохо…

                            Чтобы эффективно использовать mongodb надо четко продумывать набор коллекций и политику кластеризации на перед… Всегда на этапе проектирования можно оценить динамику роста объема данных в коллекциях, какие коллекции возможно придется шардить и т.д… Соответственно продумать структуры ключей для шардинга и прочая…

                            Ни одного принципиального ограничения, я в MongoDB не вижу. Индексирование по массивам это весьма специфичная штука, я с трудом представляю где может понадобиться индекс с двумя массивами в ключе. Тем более что вам ничего не мешает сделать два индекса (в каждом по массиву) и в запросах будут автоматически использоваться оба индекса…

                            Те кто будет пытаться бездумно пересесть на монго с mysql или с postgresql тупо переносить схемы бд на коллекции и считать, что count() в sql и это тотже ...find(...).count() в mongodb будут с вероятностью 80% сильно разочарованы…

                            Меня как старого db-программера (начинал во времена dBase, Foxbase, Paradox и Clipper. Foxpro тогда не имел отношения к MS. А Oracle тогда еще был корявой и некрасивой поделкой) mongodb радует…
                              0
                              > Многое из того, что «взрослые» CУБД делают автоматически вам в приложении придется делать вручную…
                              А можно пример?

                              > Чтобы эффективно использовать mongodb надо четко продумывать набор коллекций и политику кластеризации на перед…
                              Это из собственного опыта? Мне просто показалось что наоборот, MongoDB из-за своей гибкости и простоты прощает ошибки, которые можно совершить на начальном этапе. У вас был опыт когда было неудачно выбраны коллекции и т.п. и потом пришлось переделывать? Какие впечатления?
                                +1
                                А можно пример?


                                Много чего… Например реализация транзакций, многоколлекционные запросы, учитывать латентность при запросах к slaveOk() secondary серверу… Проще наверное написать, что не придется делать вручную…

                                Это из собственного опыта? Мне просто показалось что наоборот, MongoDB из-за своей гибкости и простоты прощает ошибки, которые можно совершить на начальном этапе. У вас был опыт когда было неудачно выбраны коллекции и т.п. и потом пришлось переделывать? Какие впечатления?


                                Конечно из опыта… Продумывать надо всегда не зависимо от того. используешь ты RDBMS или Mongo. Простота документоориентированных БД обманчива. Сложность в них никуда не исчезла. Она просто переместилась в другие аспекты.

                                Это такой своеобразный закон сохранения сложности… Если этого не учитывать, то вы рано или поздно уткнётесь носом в эту проблему.

                                С неудачно выбранными коллекциями это первый же опыт всех тех, кто после RDBMS осваивает Документоориентированные базы данных. Всё тот же тупой перенос схем в коллекции. (Например вы решили проект на рельсах перевести на Mongodb подключив mongoid). В итоге элементарный в mysql запрос превращается в mongo в целый ворох запросов по нескольким коллекциям и естественно в сравнении с mysql откровенно тормозит.

                                Типичный пример: Пользователь с почтовыми адресами. Обычно в mysql это схема user, хранящая например номер квартиры и ссылку на запись в справочнике домов, то в свою очередь на справочник улиц, те на справочник улиц, дальше районы, и могут быть даже города…

                                Перенесём это в MongoDB и попытаемся определить всех пользователей в некоем одном микрорайоне или даже городе… Прикиньте сами количество запросов, которое вам понадобится и как быстро вы пошлёте все это на…

                                В продашкне при более-менее нормальном объеме данных это начнёт тормозить нещадно. И в случае жалоб менеджер проекта потребует в кратчайшие сроки вернуть всё назад, и забыть про MongoDB…
                              0
                              Спасибо за статью!

                              У меня было время только на DBA курс. Как у Вас впечатление? Стоит на Developers записываться или курса DBA достаточно?
                                +1
                                Несмотря на то, что там многие темы совпадают, в курсе для Developers я не стал полностью смотреть лекции только по Sharding (и думаю зря :)), ибо посмотрел их уже в DBA и решил что в DBA более углубленно должны были дать этот материал. В целом многие темы там пересекаются, но когда смотрел лекции не было желания промотать вперед, ибо «где-то это уже слышал». Мне еще было интересно Python пощупать, я до этого о нем только слышал, поэтому мне было интересно и в Developers классе. Думаю что на Java тоже запишусь, несмотря на то, что лекции скорее всего будут теми же.
                                  0
                                  Спасибо! Буду записываться =)
                                    +1
                                    В курсе для Developers освещался вопрос про getLastError и параметры j и w, а в DBA этого не было. Поэтому пришлось пересмотреть лекции для Developers :)
                                  0
                                  Не совсем понимаю, на какие лекции ушло 3 недели по 8 часов? Я изначально думал, что это 2 дня по 8 часов.
                                    0
                                    Каждый курс длился 7 недель. Каждую неделю на один курс я тратил 3-4 часа на лекции и 1-2 часа на домашнее задание. Где-то меньше, где-то больше.
                                    +2
                                    «Capped коллекции (manual)
                                    При создании таких коллекций необходимо указать количество записей, который могут храниться в коллекции.»
                                    Точнее, не количество, а общий объем коллекции.
                                      0
                                      Финальный экзамен M101 «MongoDB for Developers» сдал на 9/10, осталось доделать в M102 последние вопросы про шардинг :)
                                      Курс классный, без особого напряга за 7 недель получил неслабое представление о MongoDB, при выполнении некоторых HW и заданий финального экзамена частенько обращался к их документации, которая, кстати, написана весьма неплохо.
                                      Сейчас пишу на MongoDB небольшой проектик, just for fun :)
                                        0
                                        В каком вопросе ошиблись, если не секрет? :)
                                          0
                                          Конечно не секрет :) во втором, где надо эту Веронику Эспинозу сагрегатить :)
                                          В общем я его делал понемногу каждый день, ну, не очень я разобрался с агрегацией. Самое бесючее, когда написанный запрос возвращает result: [ ], если же че-то возвращал запрос, то это было не 2181.
                                          Вчера вроде получилось, после того как все дискуссии по этому вопросу перечитал, хотя подсказок особых там не было. Но вместо одного запроса я написал функцию на JS. которая просто проверяла все пары из возможных в вопросе (5 там или 6 их), и самое прикольное, что почему-то неправильно получилось, хотя для Эспинозы и recipients запрос возвращал 2181.
                                          Кстати, когда вчера я сделал-таки q2, прошелся по остальным вопросам, на которые уже ответил, перечитывая дискуссии по ним. И ведь подправил еще 2 или даже 3 вопроса, в итоге оочень не зря оказалось это.
                                          Но утром, когда вскрылись результаты, был зол на q2.
                                            0
                                            Ну, сертификат-то в итоге получили? :)
                                              0
                                              А вы разве сами курс не проходили?
                                              Да, 95% набрал — второй вопрос блин -5%, минимум надо было 65% для сертификата. пару недель назад они писали что через какое-то время после финального экзамена они подпишут и разошлют сертификаты. Насколько я понял, они только в электронном виде)
                                              В январе стартует тот же курс, но вместо питона там джава будет)
                                                0
                                                Питон тоже будет
                                                  0
                                                  Ну да, тот же питоновый M101 остается, просто еще дополнительно M101J будет)
                                                  Так то пофиг на чем писать, сам на пхп пишу, джаву изучаю, питон тоже язык неплохой, но после первых недель я на нем не писал, либо JS либо вот разок на PHP писал для HW)
                                              0
                                              Я в 8 чуть не ошибся, где вопрос про репликацию и падение мастера. Додумался до правильного ответа когда начал делать домашнюю работу по M102 :) Всё-таки мысль проходить сразу два этих курса — очень правильная.
                                                0
                                                Это точно) Помимо курсов, я еще и жил в документации, отрадно все это в текстовом виде иметь перед глазами.

                                        Only users with full accounts can post comments. Log in, please.