Как стать автором
Обновить

Комментарии 131

Как вы там в 2012-ом?

Тут лучше чем в 2022м)

У вас там всего одна проблема - конец света)

Меня пугает что никто не пишут из 2032 :)

Есть нюанс:)

Ферми это давно знал

Здравствуйте, спокойно, пишу вам из 2032, тут все уже перешли на распределённую крипто базу данных с конвергентной мультимастер синхронизацией написанную на $mol.

Смотрел я в сторону $mol, хотел попробовать прикрутить к своему проекту. Но оказалось что в $mol нет красивых компонентов :(

А так как я сам в CSS ноль, то стал смотреть в сторону quasar, где в наборе уже идут красивые компонентники

Дизайн базовых компонент там намеренно аскетичный, чтобы его легче было кастомизировать под личные представления о прекрасном. Но какое это имеет отношение к базам данных?

В том то и дело, что представление о прекрасном у меня есть, а вот навыков в CSS нет :)

Поэтому пришлось искать там, где уже все украшательства прикручены.

Но какое это имеет отношение к базам данных?

А при чем тут вообще базы данных?

Я бы вам рекомендовал всё же освоить CSS, а не заучивать птичий язык всяких квазаров. Он не сложный.

Вам не кажется странным обсуждать дизайн компонент под статьёй о базах данных?

Как язык CSS и правда несложный. Но это совершенно не означает, что делать дизайн сайта с нуля используя CSS легко.

Не просто легко, а элементарно, справится любой войтивайти за 3 копейки.

В том то и дело, что в quasar стандартный vue с js. Никакой css не нужен.
p.s.я и так что не начну писать, так целую кучу инструментов понапишу, а до того, что изначально планировал так и не добираюсь. :)

А есть какое-то решение для 2022?

PostgreSql или MySql по вкусу (если не можете выбрать киньте монетку. я серьезно). Как БД по умолчанию для любого проекта где вообще непонятно что надо и никаких разумных требований сформулировать не получается. А вот данные хранить надо уже сейчас.

В 2012 те кто поопытнее говорили тоже самое, но кто их в стартапах слушал?

А, в смысле в 2022 MongoDB уже никто не пользует? Ясно, она как-то мимо меня прошла (не было необходимости), только через 10 лет узнал что и нужно было)

Используют. Но только когда понимают зачем она им и почему именно она, а не как вариант по умолчанию.

В постгри есть json колонки, по которым можно делать индексы и квери. Очевидно, что не как вспомогательное решение, но оно отлично подходит для редко использующихся данных и позволяет не городить огород ради записи тэгов или дополнительных полей к сущностям

не читать новости :/

пока только такое

Disclaimer — я не монгофанбой, хотя и знаю её намного лучше чем SQL.


Сейчас я просто опишу свой опыт успешного использования монги для стартапа на 4 бекендеров и предположу, почему автор огреб


Не использовал ORM или хотя бы DTO

Здесь у нас был nodejs + typescript + graphql, соответственно всё, что ты писал в коллекции, валидировалось по схеме. Хочешь поле в базе? Добавь сначала в схему. Ни разу левое поле не записывали, ни разу не читали.


Верил, что без миграций и схем данных в MongoDB будет легче

см. выше про схему


Стрелял в ногу типами данных

Третий аргумент про схему данных? Да хватит!


Думал, что MongoDB быстрая и будет такой всегда

Ну, на базе в несколько гигабайт и с 500000+ записями она была быстрой) Главное индексы ставить.


JOIN это очень дорого, а query по вложенным документам — это гарантия сломать мозги

Делали минимум вложенных документов, только join через агрегации.


сколько у нас объектов N для пользователей B, которые входят в категории C,W,Z и делали вот такие-то вещи

Подскажите, а где-то это легко?


Кстати, агрегации довольно легко читаются если привыкнуть.


Поиск это тоже цирк с двуногими конями

Да это боль. А где нет?


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

Конечно надо делать files в отдельной коллекции.


Стоп, wait a second…


Аргументы автора: нет схемы, join это боль, join это боль, join это боль...


Хммм...


Предполагаю, что автор вместо агрегаций писал джойны в ORM, а потом перешел с ORM на SQL и возрадовался.


Что, считаю, в случае с монго совсем неправильно, и агрегации более правильный путь.


Aggregation pipeline это тот же "язык" запросов на котором можно безболезненно делать любые джойны и прочее. Более того, за счет того что это JSON, очень удобно делать хелперы:


export const lookupUserFiles = (filePipeline) => ({
  $lookup: {
    from: 'files',
    as: 'files',
    let: { userId: '$_id' },
    pipeline: [
      { $match: { $expr: { $eq: ['$userId', '$$userId'] }, } },
      ...filePipeline,
    ]
  }
})

Которые потом можно легко комбинировать, например найти юзера с его файлами, размер которых больше 100мб и у этих файлов взять все комментарии:


db.users.aggregate([
  $match: {$_id: userId},
  lookupUserFiles([
    $match: {size: тут не помню, но типа больше 100мб},
    lookupFileComments()
  ])
]

Так же хочу заметить, что у автора проскакивает инфа о том, что у него было "мало" больших документов вместо множества мелких. Тоже считаю что это ошибка и основной источник проблем с перформансом.




Заключение:


Отсутствие схемы данных — это не преимущество MongoDB

Отсутствие схемы данных — это преимущество MongoDB, потому что схему данных мы можем сделать свою. А зачем свою? А чтобы лучше интегрировать её с остальными частями.


Невозможность делать нормальные джойны

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

Ну, на базе в несколько гигабайт и с 500000+ записями она была быстрой) Главное индексы ставить.

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

И на таких объемах MongoDB действительно сильно уступает по производительности сложных аналитических запросов таким СУБД, как ClickHouse или PostgreSQL. Но замечательно подходит, как буферная БД для сбора информации из внешних сервисов, в которых без предупреждения могут меняться как типы полей, так и появляться новые поля или даже целые подчинённые структуры.

Подскажите, а где-то это легко?

в постгресе, да и в любой реляционке это легко

Да? Типа если есть 3-5 связанных сущностей и надо сделать поисковый запрос по всем — это будет легко все это заджойнить да отфильтровать?

Да, в этом огромное преимущество реляционных БД. Для скорости юзаются индексы + горячие данные хранятся в озу и полируется кешированием. И скорость поиска в районе скорости света:)

Хех, я бы расспросил подробнее, потому что в нереляционных бд тоже есть индексы, а данные-то могут быть и не в озу, но тут публика минусует как будто я с вами спорю, поэтому просто поставлю плюсик, спасибо за объяснение)

Идея в том, что join + индекс это быстро и встроено в бд. Реляционные бд созданы, что бы хранить и обрабатывать связанные объекты из коробки. К примеру в Postgresql есть поддержка json, аналог функционала mongodb. И даже если нужна keydb, можно юзать Postgresql с синтаксисом sql.

Для обеспечения производительности есть рекомендации, советы, инструкции. Первое, это хранение индексов в ОЗУ. Деление данных на горячие и старые холодные данные, что бы обрабатывать меньший объем. Что бы быстро работать с данными нужно думать как база данных:) Я просто начинал с реляционных бд и для меня был некий ступор, что в mongodb как то сложно организовать связи, типа чего? Как делать выборку. Для keydb это очень специфичные задачи типа хранения логов или не связанных данных. Но это сейчас организуется и в Postgresql, так зачем плодить сущности. Шардинг тоже есть.

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


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


Идея Монги была изначально провальной потому, что не бывает вообще никак не структурированных данных. Большая часть данных, с которыми приходится работать, всегда великолепно структурируется. И только небольшая часть может представлять из себя кучу-малу. Идея ради небольшой части делать из всей БД кучу мусора оказалась провальной. Вместо неё сейчас получила развитие гораздо более осмысленный подход с использованием JSON полей в нормальных БД. Который как раз и следует вышеприведенной схеме — большая часть данных нормально структурирована, а для данных типа шаляй-валяй есть отдельный загончик. Который потом можно отдельно проиндексировать эластиком для отдельного случая фасетного поиска.

Истина немного посередине:

  • Данные могут быть хорошо структурированы, но представлять из себя не плоский кортеж, а иерархию.

  • Схемы эволюционируют со временем, а останавливать работу сервиса, чтобы атомарно мигрировать туда-сюда не хочется, тогда и появляется одновременное существование разных структур в одной коллекции.

Так что обе крайности (рсубд с загончиком, дсубд с чем попало) - довольно бестолковые.

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

Каким образом? Налепить несколько таблиц и огрести проблем с индексами, сортировками и прочим? Или сделать одну широкую таблицу с кучей пустых ячеек и на каждую миграцию дважды останавливать сервис для изменения схемы?

Именно что налепить несколько таблиц. Проблем с индексами будет меньше, чем в варианте без схемы.

А какие рсубд умеют в сквозные индексы по нескольким таблицам?

У вашего комментария интересная структура. Верное исходное утверждение про истину посередине, потом два, мягко говоря, спорных утверждения, и далее вывод, который противоречит всему вышеперечисленному.


Насчет истины всё верно: и "Рсубд с загончиком" как раз и является такой "серединой", соединяя нормальную управляемую структуру, плюс резервацию для данных, которые дешевле свалить в кучу, чем нормализовать. То есть это никакая не "крайность". Крайность — это EAV в РСУБД.


С утверждениями всё плохо.


  • проблема в том, что данные, которые представляют собой иерархию, составляют менее 1% от всех данных приложения. И попытка натянуть БД для одного процента на оставшиеся 99% является заведомо провальной. О чем нам и говорят многочисленные истории "успеха" Монги.
  • по поводу "ползучей" схемы — ну, тут я даже не знаю. Возможно, у нынешнего поколения утерян инстинкт самосохранения… Но вот лично во мне четко сидит понимание, что если я оставлю кому-то после себя вот этот вот адов винегрет, то меня будут долго бить, при чем возможно даже ногами. То есть помимо исходной кучи малы вы предлагаете еще и на ходу постоянно менять ее схему, чтобы потом вообще концы нельзя было найти. Извините, но это не укладывается в голове. Мы тут все воюем за SOLID, DDD и прочие красивости — чтобы избежать спагетти-кода, чтобы можно было нормально модернизировать приложение, а не добавлять заплатки одну на другую. А вы решили зайти сразу с козырей, и предложить спагетти-базу данных, состоящую из заплаток чуть более, чем полностью.

 "Рсубд с загончиком" как раз и является такой "серединой"

Нет, это химера: дсубд внутри рсубд. А середина - это дсубд со схемой.

данные, которые представляют собой иерархию, составляют менее 1% от всех данных приложения

Вы просто привыкли не замечать, ни деревья, ни графы в своём домене, а ещё про DDD рассуждаете. Вот, схема профиля пользователя на том же Хабре:

помимо исходной кучи малы вы предлагаете еще и на ходу постоянно менять ее схему

Классический пример кучи-малы - это список уведомлений. Каждое уведомление имеет свою схему. Ну а схемы не меняются со временем только в мёртвых проектах.

Мы тут все воюем за SOLID

Не обобщайте.

Всё это работает только до тех пор, пока между документами не требуется устанавливать связи. А их требуется устанавливать — на тот же профиль пользователя будут ссылаться хотя бы его статьи и комментарии.

А это уже реляционная база, вид сбоку

Простите, 500к записей можно хранить в CSV файле, и оно тоже будет быстрым.

У нас тут недавно автокрементный id типа unsigned int переполнился, вот это было немножко больно:)

Причем в БД это Int64

вы это серьёзно написали? чтобы int32 переполнился я встречал неоднократно, но с int64…
сейчас прикинул, при добавлении записи каждую наносекунду 63 бит (считаем, что счётчик знаковый) хватит почти на 300 лет.

Осталось только понять, зачем это все. Зачем руками поддерживать схему, когда в нормальной БД за целостностью данных следит сам движок. Вы, сами того не замечая, пришли к схеме с двумя базами данных. Одна — это собственно "база данных", в которой все свалено в кучу, а вторая — сделанная на коленке база данных для хранения схемы первой базы данных, чтобы в ней хоть как-то можно было разобраться. :)

Я не понимаю, как ваша статья прошла песочницу.

От статьи ощущение будто вы реально покопались в монге в 2012 в одиночку, а спустя 10 лет решили рассказать, попутно добавив людей, которые яко бы пришли в проект без знаний nosql и даже python. Уровень статьи просто пугает, от работы с кодом будто в тетради с ручкой, а не IDE с Python; До ярких заголовков типа «Поиск — двуногий конь», под которыми вы даже не удосужились обозначить «проблему поиска».

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

За что пользователи ставят высокий рейтинг статье - нет ясности. В статье нет информации какие данные(примеры), сколько их, как писал, как читал, как обновлял почему вообще автор выбрал Mongodb.

Рецептов и готовых решений мало или вообще нет

то есть отличные статьи и "университет" на самом основном ресурсе mongodb - автор пропустил?

Статья - набор клише, вредного субъективного мнения. У mongodb есть и плюсы и минусы, что уж тут говорить, инструмент выбирать по ситуации и умению им пользоваться, очевидно вроде.

За что пользователи ставят высокий рейтинг статье

За попытку донести информацию. Хотя уже давно (с момента начала работы Postgres с JSON, т.е. ~8 лет тому) многое было ясно.

зареву? всегда считал, что разработчик, архитектор выбирают базу данных не "по-любви", а по целям и задачам. Хотя наверно да, сложно относится с понимаем к тем, кто везде всегда выбирает Postgres.

кто везде всегда выбирает Postgres

Если это было в мой адрес - то не везде и не всегда. Как минимум Clickhouse, Greenplum и Vertica в ряде случаев оказались более подходящими.

по целям и задачам

Монго тоже подходит для некоторых задач, например для склада media assets - сырых файлов с тегами и уже агрегированной статистикой. В рекламной сетке удобно, когда баннер/преролл с результатами его работы и настройками кампании лежат вместе и всё это относительно легко шардируется. Но и потерять эти данные если что - не очень-то и жаль.

На самом деле основная проблема, которую описал автор в статье - это не проблема в самой СУБД MongoDB. В статье собрано практически полное собрание антипаттернов использования NoSQL и key-value хранилищ.

То есть, вам нужен был SQL, вы выбрали NoSQL, и поэтому Mongo - это фу? Ясно, понятно.

ну не совсем, сначала надо была "ну хоть какая-нибудь любая БД", а только потом с развитием стартапа выяснилось, что база нужна вот такая-вот, но уже поздно. И это очень нередкая ситуация.

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

Вина хипстеров пытающихся заложить архитектуру и объем обрабатываемых данных как у гугла. Вы простая пиццерия, торговый центр, вам не нужно 100500 микросервисов, mongodb, kafka и другие крутые штуки. Вам нужно обработать быстро клик от пользователя и выдать результат на паре миллионов записей, которые и так лежат в озу. История хранится на другой БД для аналитиков. Но нет, они же все будущие гугл с петабайтами информации. Ну вы поняли к чему я:)

О, да! В первой версии бэкенда мобильного приложения(без заказов) одной из сетей быстрого питания всё было спроектировано максимально упорото. Что можно было сделать просто, делалось максимально сложно и наоборот. В итоге проблемы с производительностью решались путём натягивания совы на глобус.

А по факту на 300к юзеров в сутки всего-то надо было базу подтюнить и некоторые запросы переписать =]

Здесь я перечислил то, как я вижу правильное назначение для MongoDB:

Вообще, первый пункт, когда нужно выбирать монгу: данные непрерывно растут в объеме и необходимо дешевое горизонтальное масштабирование.

Конечно, это не мешает использовать монгу на одном инстансе. Но нужно помнить, что для реализации дешевого горизонтального масштабирования создателям монги пришлось пойти на ряд компромиссов. И когда вы не используете главную фичу монги, вы не получаете самую важную ценность монги, но при этом получаете в нагрузку все недостатки монги, которые и в одном инстансе никуда не делись.

Аналогичная история с кафкой.

Еще одна интересная особенность MongoDB - если файл на диске поврежден (в нашем случае повреждено nvme (waaat????) и побиты некоторые коллекции, то при попытке прочитать что-то из такой коллекции полностью крашит весь процесс. То есть весь прод ложится из-за повреждения одной коллекции. В mysql таблица просто помечается битой и вся остальная база продолжает работать.

По объему - да, монга работает быстрее с большими данными, но видимо из-за принципа работы. Если в mysql сделать select на таблице в 100млн записей, то они все летят на фронт. В Монге ты делаешь итерацию по объекту и данные подтягиваются по мере продвижения по массиву (хотя может я застрял в прошлом веке и mysql так же умеет?). Без индекса ходить в коллекцию нет смысла, получишь timeout (на большом объеме), как и в mysql.

Я фигею, дорогая редакция. Вы думаете что в СУБД нет пагинации?

Статья настолько же странная - вот что бывает, когда на проект вместо архитектора берут джуна. Оказывается, что в монге сложно джойнить! Кто бы мог подумать!

Дело не limit, а в принципе отправки данных с сервера клиенту - если этот эффект делает под капотом ORM на запрос SELECT * FROM table, то ок, а если это by design самого mongodb, то вот и отличия.

Мне не нужны такие байдизайны.

Если мне нужно 10 записей, я кверю 10, если миллион, я кверю миллион.

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

Так то sql создавался для домохозяек простой язык запросов. Это было раньше, уровень образования и погружения в компьютерную науку был выше. Теперь тяп ляп на орм и в прод. Ибо горит, бизнес требует. Все быстро и что бы работало. Медленно, быстро все равно. Главное сегодня и сейчас. Как то так. Вот вам и вынужденное обезьянство.

Нормальная ORM идёт с построителем запросов (query builder), который умеет вызывать что-то кроме select * from …. Если ORM такого не умеет — её просто не надо использовать в принципе. Так что чтобы не выбирать ненужных записей — надо лишь найти как эти самые запросы правильно строить.


А если программист вместо ORM и её построителя запросов фильтрует массивы — это и есть обезьянство, притом добровольное.

В Монге ты делаешь итерацию по объекту и данные подтягиваются по мере продвижения по массиву (хотя может я застрял в прошлом веке и mysql так же умеет?).

А разве выборка результат построчно это не станадртная функция всех СУБД?

Похоже, что это уже слой ORM. Так как если сделать "select * from table" на 100 млн записей то все эти данные сначала летят клиенту (в processlist висит статус Sending data), а там уже разгребай их в foreach, если памяти хватит.

в php есть итераторы, которые в связке с ORM позволят сделать foreach на такой запрос быстрым, добавляя под капотом в запрос limit.

Так как если сделать "select * from table" на 100 млн записей то все эти данные сначала летят клиенту 

В нормальной СУБД с нормальным клиентом не летят. И ORM тут не причем, LIMIT тоже. Если у вас летят, то у меня для вас плохие новости. Хотя зависит от того как вы на уровне клиента данные запрашиваете.

php 8.1.11
memory_limit = 1024M
mysql 5.7.39
таблица 3гб

<?php
$mysqlhost = "hostname";
$mysqluser = "user";
$mysqlpass = "password";
$mysqldb = "db";

$mysqli = new mysqli($mysqlhost, $mysqluser, $mysqlpass, $mysqldb);
$result = $mysqli->query("SELECT * FROM bigtable");
while ( $row = $result->fetch_assoc() ) {
	var_dump($row);
	die();
}
PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 276840448 bytes) in /test.php on line 8

из коробки выкачивает все данные на сторону клиента.

Монга с таким подходом 300 гиговую базу спокойно отдает построчно в итерации.

Скажите, а вы в курсе про \PDO в PHP? Вот так будет построчная выборка:

$object = new PDO($dsn,$user,$password);  
  
$sql="select * from student";  
$result = $object->query($sql);  
while($arr=$result->fetch()){  
    print_r($arr);  
}  

А вы в курсе про тестирование?

<?php
$mysqlhost = "hostname";
$mysqluser = "user";
$mysqlpass = "password";
$mysqldb = "db";

$pdo = new PDO("mysql:host={$mysqlhost};dbname={$mysqldb}", $mysqluser, $mysqlpass);
$res = $pdo->query("SELECT * FROM bigtable");
while ( $row = $res->fetch() ) {
	var_dump($row);
	die();
}
PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 276840448 bytes) in /test2.php on line 8

Ваш пример вообще ничем не отличается от предыдущего.

Я не PHP-шник, я из другого мира, но доки читать умею. Про fetch_assoc написано

Выбирает следующую строку из набора результатов

то есть выборка все же построчно. А потом вы через while обходите все строки. Внезапно, это означает, что все строки придется выгрузить на клиент.

Речь про реализацию драйвера. Тот же foreach в монге на 300гб коллекции не получает ее всю на клиента, а бегает по ней по сети:

$res = $mongodb->db->bigtable->find( [ ] );

foreach ( $res AS $d ) {
	var_dump($d);
	die();
}

С одной стороны, это удобней (не нужно строить цикл с перебором страниц). Код был чище.

Ну то есть ваш первоначальный посыл, который, позволю себе напомнить, звучал как

Если в mysql сделать select на таблице в 100млн записей, то они все летят на фронт.

неверен? И, как я уже писал, это проблема клиента, так ведь?

Посыл остался прежним - клиент эту проблему не решает. Выше меня пытались переубедить что нужно PDO, но нет.

Решить эту проблему - накрутить ORM? Который этот код превратит через итераторы в пагинацию...

О нет, ваш посыл поменялся. Изначально вы проклинали MySQL, а теперь проклинаете клиент. Это уже большая разница. Потому что это означает что можно найти нормальный клиент.

Решает, если почитать доку. В РНР можно делать и так и так — можно забрать все сразу, можно цедить по строчке.

Если клиенту нужно вернуть 100 млн записей, то это не клиент а аналитик. Аналитик работает с другой бд. Если именно клиенту нужно 100 млн записей, то ему реально не нужно 100 млн записей, ему скорее всего нужно пару цифр посчитать или вывести по критерию.

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

А потом вы через while обходите все строки.

Там вызов die() не просто так, он ровно одну строку "обходит". Но драйверу почему-то всё равно нужны все

Драйвер делает разумное предположение что раз пользователь вот это запросил наверно оно ему нужно. И максимально оптимально читает и отдает пользователю весь ответ сервера.

select * from ...

А о какой именно ORM речь? Ни разу не видел таких запросов.

Так же, если речь про mysql, то отправлять ли результат целиком на клиент будет определяться с помощью PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 

А всё казалось таким простым:

As long as there are pending records waiting to be fetched, the connection line will be busy and all subsequent calls will return error Commands out of sync.

Придется открывать отдельное соединение к базе только ради этого.

Работал с MongoDB на двух проектах:

  • В первом в MongoDB хранились логи - все ок

  • Во втором, на MongoDB хранились основные данные, и это пц. Просят доработать функционал сортировки - в процессе оказывается, что на каких-то элементах сортировка не работает. Вникаю в данные - а там в каких-то записях параметр отвечающий за сортировку int, в других string, в третьих вовсе отсутствует. И так по всем данным.

Дело было в 2018-2019 годах. Использовалось в связке с php.

  • В первом в MongoDB хранились логи - все ок

Для таких задач key db и предназначены. Если юзать для всего, начинается процесс заката солнца вручную.

Нет, логи это не то, для чего были сделаны NoSQL БД. Для логов хороши либо спец-хранилища вроде Loki, либо просто колоночная БД вроде Clickhouse/Vertica/etc.

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

База должна выбираться по принципу того какие запросы она исполняет.

NoSQL неплохи для записи больших объемов (LSM деревья помогают, хотя в колоночных используются они же часто) и запроса единичных ключей, но так себе для линейного чтения (нужно читать много sstables с диска, отбрасывать старые версии если они есть и т.п.) и поиска + вторичные индексы по ним довольно сложно реализуемы.

Какие запросы к логам обычно? Найти какой-то текст в заданном интервале времени с какими-то фильтрами небольшими типа имени хоста. Для этого обычно принято юзать полнотекстовый поиск (привет Elastic и ко), но в последнее время прямое сканирование в современных колоночных БД оказывается часто быстрее т.к. данные расположены линейно, правильно партиционированы (по дате, например, хосту и так далее) и прочее.

В NoSQL такие запросы выполняются не очень эффективно.

С типами данных в монге можно еще выстрелить в ногу - если поле string, и к нему есть индекс, то если передать для поиска переменную с типом int, то индекс уже не работает. Тоже самое наоборот. Приходится внимательнее следить за переменными.

Всякие авито, Яндекс для своих сервисов юзают postgresql. Хранят и перемалывают терабайты информации. Конечно это не MongoDB не стильно не модно и не молодежно, но разработчики справляются и с масштабированием и с нагрузками и с сопутствующими проблемами. И что собственно вам мешало заюзать реляционную бд с поддержкой json, стандартным sql? Уверовали key db и стали его пихать всюду. Проблема даже не в кривых руках, а в неадекватных инструментах для решения вашей задачи.

А Uber?

MySQL все нормально, тоже реляционная.

Когда начинались некоторые проекты рсубд были совершенно другими, они страдали одной большой проблемой - горизонтальное масштабирование, отсутствие работы с xml/json, стоимость лицензий.

Сейчас есть NewSQL.

За статью в таком же духе, но про мак меня попёрли из хабра))))

Ну это уже слишком, я про мак естественно;)

Я за 8 лет монги наелся достаточно.

Из проблем которые у меня возникли:

Постоянно разваливалась реплика из 3х серверов, то арбитр упадёт, то какаета реплика. Но это не страшно.

Самое страшное, это когда у тебя проподают индексы из коллекции причём ладно это был единичный случай, но нет, 4 раза Карл.

Создавал индексы всегда через бекграунд опцию, данных не много 300гб.

А как это непотребство на проде то юзать? Это же отвага и слабоумие. Не в вашу сторону, я о молодых, стильных, молодежных. Ест проблемы с фундаментальными вещами типа надёжность, как юзать то?

>Я за 8 лет монги наелся достаточно.

8 лет монга основная субд

>Постоянно разваливалась реплика из 3х серверов, то арбитр упадёт, то какаета реплика

кривое железо или нет места на диске.

>когда у тебя проподают индексы из коллекции

бред, как и всё вышенаписанное.

данных терабайты. и реплики и standalone.

Вот-вот, как только заканчивается место на диске — монга вместо того чтобы выдать ошибку начинает терять индексы или данные. Это вообще нормальное поведение для СУБД?

И толку-то от того, что она выдаст ошибку, когда у вас место закончится? Вы логи постоянно читаете? Успеете среагировать?

Для мониторинга состояния оборудования, ресурсов и софта есть специальные инструменты для мониторинга, а для них дэшборды с красивыми, понятными индикаторами, графиками, алертами.

Выкинутую ошибку приложение может как то обработать. Например показать пользователю, что "упс, все упало"

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

Это называется борьба за живучесть:)

Действительно, динамически типизированный ЯП + БД без схемы данных + отсутствие хороших практик - казалось бы, что тут может пойти не так?

Как и в любой практике тут важно отделять наработанный опыт от фундаментальных проблем.

Можно говорить про потребление памяти Монги, но для агрегаций есть опция allowDiskUse, если сильно надо.
Можно говорить про json-поля в Постгре, но я в упор не понимаю, почему одно невалидное string::json-поле рушит весь запрос, а не возвращает просто null, как могло бы быть в Монге.

Или вот, индексы. Я долго вкуривал, почему индекс не применяется к запросу find({}), пока не понял, что играет роль порядок полей в запросе и в индексе. Понял и теперь это не проблема, а просто trade-off.

И такого много. Возможно мои проекты не самые крупные в мире, зато ушибов и ссадин при работе в обеих БД было достаточно. В итоге получилось так, что для конструирования сложных фильров в postgres был найден sql-билдер mongo-sql для node с синтаксисом mongo-like json, вот такие повороты сюжета :)


Вернуть бы времена, когда хватало couchdb и SPA-фронтенда.

Вернуть бы времена, когда хватало couchdb и SPA-фронтенда

Так до сих пор много для каких простых штук хватает )

Сейчас и MySql + Php еще юзают. Как говорится было бы желание. Так сказать ИТ 90-ых еще в моде:)

В конце получился отличный ответ на вопрос, для чего нужна монга.


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

Файлы, кликхаус, локи


Данные, по которым вы никогда не будете искать дальше самого верхнего уровня. Максимум: взять какой-нибудь документ по его ID или другому полю (например, user_id, который вы до этого взяли из другой БД).

Непонятно, зачем в этом случае вообще городить отдельную датабазу. Берем документ по его ID из той же базы, где лежит и всё остальное.


Данные, которые вы будете писать большую часть времени разом и одним документом. Редко когда придется менять отдельные поля.

Это что-то из пальца высосанное. А, главное, те же грабли — вид сбоку: "сейчас мы воображаем, что отдельные поля менять не потребуется. А потом пойдем писать на Хабр о том, почему это оказалось недальновидным решением".


Кэш большого объема, для удобства разбитый по отдельным полям. Его быстро можно прочитать, легко инвалидировать. Он в виде структурированного документа может быть сразу использован вашим приложением.

Редис


Сессии (хотя вопрос скорости работы все еще остается). Аналогично кэшу. Создали документ, бросили его в MongoDB и взяли через какое-то время одному-двум полям. Без глубокого поиска. Максимально просто. MongoDB, кстати, удобно шардится и реплицируется — это прям реально ее преимущество.

Редис


Очереди. Точнее, можно использовать MongoDB как БД для хранения очередей данных для последующей обработки. Аналогично кэшу и сессиям MongoDB дает возможность хранить структурированный документ с данными очереди.

Осталось только понять, зачем использовать для очередей не специально предназначенные для этого инструменты, а Монгу.

Статью лайкают те, кто 10 лет назад минусовал подобные комментарии под статьям-антонимами?

Еще одно подтверждение в тему того, что прежде чем использовать какой-то инструмент, нужно сначала понять для чего он был создан и в чем его особенности работы. Выбирать под задачи ТС NO-SQL базу было
как минимум странно, и тут не важно, что он не смог ее приготовить, ошибка была еще до начала использования. Вопрос к компетенции того, кто отвечал за архитектуру. И к тому же у них на сайте есть достаточно подробное описание того, для чего ее стоит использовать. Стоит читать не только стартовую маркетинговую страницу
Еще одно подтверждение в тему того, что прежде чем использовать какой-то инструмент, нужно сначала понять для чего он был создан и в чем его особенности работы.

Так и для чего этот инструмент все же использовать? Пихать разнородные данные в одну коллекцию а потом делать по ним какие-то сложные выборки? Ну выглядит крайне сомнительно.
Вон автор попытался найти достаточно конкретные юзкейсы но облажался лишь в том что для каждого пункта есть альтернатива специально заточенная под это дело.
А вот подход от создателей, по вашей ссылке в самом низу, вида «используйте Mongo для Payment processing» это лажа в квадрате. Типа если у меня платежный шлюз то тут Cassandra и Redis не подойдут, берем Mongo. Весьма авторитетно.
Пока что ничего в голову не идет кроме — а давайте напрямую портянки json сохранять с рестового ендпоинта на ноде, в стиле MEAN образца 2012 года. Ну да, в 2012 так можно было за день запилить стартап. А сейчас зачем?

Нормальных бесплатных GUI нет

MongoDB Compass?

мнда, судить по базе, не используя ее основную функцию агригейтов - это конечно очень сильно ))

Кто-нибудь, подскажите толковый учебник по NoSql вообще и MongoDB в частности.
моя благодарность.

Если вам кажется что монга плоха - попробуйте кассандру :) - и вы поймете что монга - не так уж и плоха :)

Взяли ScyllaDB пока все гуд ) правда с оригинальной кассандрой не имели опыта, сразу взяли сциллу. пока покрывает кейсы

А меня монга 10 лет устраивает всем, кроме кластеризации. Она отлично работает, когда у вас облака, много нод и хорошая сетевая связность. Но я делаю автономное приложение, которое должно в отказоустойчивом режиме работать на двух железных серваках рядом. И если между ними я могу использовать ucarp, haproxy и тп для выбора мастера, то кластер монги в принципе не работает, если отключен один из пары хостов. Аналогичная проблема с распределенным приложением, где узлы могут оказаться изолированными от сети на время.

Но ведь Монга не работает на паре хостов когда один из них отказал. Это та БД которой надо 3 хоста минимум.

Вот именно. В мире полно сценариев, когда железки для отказоустойчивости ставят в пары: роутеры, фаерволлы, контроллеры какие-нибудь. И тут я прихожу со своим софтом, и говорю «дайте мне три сервера, потому что у меня монга и у неё арбитр».

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

Если кто сталкивался и знает, как выкрутиться малой кровью, пишите в ЛС.

В Монге очень плохой оптимизатор, при сложном логическом запросе с И и ИЛИ он использует не тот индекс, если указать его хинтом то он его использует, но подставляет не все поля. Даже с учётом правильного порядка полей в индексе, и одинаково начала у составных индексов, что-то идёт не так :) хотя бороться можно.

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

Если есть один массив в коллекции, то жить впринципе можно, допустим с проверкой ACL, но в $text поиск нельзя добавить массив для фильтрации индекс. Так как текстовое поле представляет собой индекс, и место массива в текстовом индексе уже занято по дефолту, а два массива в индексе нельзя.

Ну а если в коллекции нужно делать фильтр по двум массивам, вот тут начинается самое главное :)

Шардинг тоже имеет тучу нюансов к lookup и индексам.

Хорошие моменты тоже есть, разработки на с#, мапинг, дескриминатор, это всё круто и удобно, codeFirst, просто класс, в базу даже не нужно заглядывать создавать какие-то там типы, строго типизировать коллекции, но если нужен поиск и фильтрация что-то тяжелее чем по id_, filed1 && filed2, и есть массив вот тут приходит крах производительности.

Codefitst , mapping, orm это все конечно красиво, но до первого сложного запроса. Или проблем с производительностью. Все равно надо будет лезть в базу, мониторить профайлером запросы, создавать индексы и опять профайлить. И ещё потратить много времени, что бы заставить orm генерировать приемлемый запрос sql. И вся красота рушится как карточный домик. Да сурово, хотелось избежать сложности, получить лёгкий перенос между бд, писать на орм и не учить эти ваши старые и сложные sql. Хотелось чик чик и в продакшн. Но даже сервер с Овер ядер не выдержал тяпа ляпа. Что же делать? Пройти тернистый путь, найти горячие места, добавить вручную индексы, оптимизировать запросы на чистом sql. Ещё возможно переделать архитектуру, подумать как уложить данные так, что бы база данных обрабатывала максимально эффективно. Да реальная жизнь намного суровее.

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

писать на орм и не учить эти ваши старые сложны sql

SQL в разы легче, больше инструментов, оптимизаторы которые десятилетия допиливыли. Простой синтекс, поддержка индексов везде. Но в sql есть проблема, это описание структуры данных, когда ты не знаешь что у тебя будет ещё добавлено в систему, какие будут требования. У сильно изменяемой системы. Вот тут решение nosql...

Тут как бы архитектор и аналитик нужен, а не nosql

Собственно, про выбор инструмента под задачу уже много раз в комментариях сказали, я же хотел бы отменить один, как мне кажется, важный факт: база относительно легко перенеслась на РСУБД. Отсюда можно сделать предположение, что и построена она была исходя из принципов построения реляционных баз данных, коей MongoDB не является. Для нее нужно совершенно иначе нужно проектировать структуру базы, и тот случай, когда одна сущность у вас разбита на несколько документов и/или коллекций - вызывает большие вопросы. В общем, Mongo - это не про взял и начал писать, сперва неплохо хотя бы базовый курс по ней пройти, раньше бесплатный был, теперь - не знаю. С добавлением транзакций спектр применения значительно расширился, однако, сейчас, с учётом наличия поддержки массивов и JSON-полей с возможностью поиска по ним, Postgres для проекта с неизвестными конечными целями и перспективами роста можно считать наиболее привлекательной СУБД. Мое субъективное мнение.

с учётом наличия поддержки массивов и JSON-полей с возможностью поиска по ним, Postgres для проекта с неизвестными конечными целями

Есть опыт перехода на постгри от монги? В чем там проблем больше/меньше? Фильтр массивов, join, индексы на все это дело? Драйверы на c# нормально поддерживают мапинг json?

EF.Core более менее нормально поддерживает json колонки, даже кверить можно.

.NET в сложном проекте используем MongoDb, никаких проблем, единственное хотелось бы чуть больше свободы в модификации Mongo.Driver

Расскажите какого характера данные вы обрабатывает?

Что именно допиливаете в драйвере?

Нельзя просто встроиться в поток команд, например чтобы прикрутить прозрачный аудит - кто и что менял. Пришлось оборачивать коллекцию.

Ещё мы используем multitenancy и тоже пришлось костыль добавлять чтобы скрывать реальное имя коллекции от кода драйвера в однном из сценариев.

Еще хотелось бы склеить некоторые коллекции и добавить имя коллекции в ключ в id, но чтобы это было прозрачно для кода. Есть OfType<> который внутри использует приватную обертку над коллекцией, но её не переиспользовать, слишком много зависимостей и все приватное.

Я бы выбрал RavenDB. Просто работает из коробки: авто индексы, поиск, быстрый, лёгкая и простая настройка. До момента когда реально понадобится лицензия можно годами использовать.

Меня удивила следующая странность в Монго: создать-удалить индекс на реплике можно, реиндексировать-нельзя. Надо в standalone кластер переводить.

А ещё с версии кажется 4.2 поменяли формат логов и существовавшие тулзы для анализа медленных запросов оказались бесполезны. На данный момент такой тулзы не существует, насколько я знаю. Если кто нашёл-поделитесь пожалуйста.

Вообще складывается ощущение что монговцы всех загоняют в свой атласклауд насильно. Каких ещё сюрпризов ждать от монги после изменения формата логов?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации