Live data from Hacker News

Why you should never use MongoDB (2013)

sarahmei.com

151–160 of 188 posts

Re: Why you should never use MongoDB (2013)

#151

My first introduction to databases was with PHP/MySQL, where normalization was the name of the game. The whole point of normalization is that there is no duplication of data anywhere. If it's possible for duplicate data to exist, that's a symptom of a design flaw in the schema. I've been using Mongo recently, and every time I raise criticism of it, the counterargument I hear is "forget about normalization! Duplicatio…

On the flip side... joins are expensive... I worked on an application, where presenting a single page, representing a single item in the application (classifieds site) required upwards of around 40 joins (iirc 36 or 46, I don't remember)... under load (including search result pages), the app was crushed by its' own weight.

I think the bigger issue is that people are afraid of separating data at clear boundaries, so long as the orchestration is in place. Having definitive data in SQL, and having denormalized documents in elasticsearch/mongo/rethinkdb works very well... other instances (huge read and/or write throughput) may work better in a Cassandra (or other bigtable solution) with application-generated lookup tables may be better. It just depends on your need.

With better support for JSON/XML nested structures and indexes in sql rdbms, it's becoming less of an issue for a lot of types of data/documents.

Re: Why you should never use MongoDB (2013)

#152
post #55

Earlier quoted context omitted.

Here's one: I have an aggregation engine where 99.99something% of the data is cycled out within 3 days, and where the system can be functional again within about ~5 minutes of ingesting new data after a total data loss. There are a lot of applications where your database is not the or even a source of truth, but effectively a big cache that you can either fully rebuild or where rebuilding isn't necessary (the data is…

> There are a lot of applications where your database is not the or even a source of truth, but effectively a big cache that you can either fully rebuild or where rebuilding isn't necessary (the data is too "fast moving" for there to be much point). This use case doesn't mean it's okay to lose data randomly. Cache invalidation should happen intentionally via an intelligent algorithm, and other data stores (such as Re…

First of all, let me make it clear that none of these points are specific to MongoDB. I have used (and do use) it for some projects, and I have used many other storage setups where we accepted risks of data loss. The specific technology doesn't matter.

> This use case doesn't mean it's okay to lose data randomly.

It often does, as long as the frequency is low enough. I've worked on many systems where the decision was explicitly taken to do things in ways we knew would lose data because we could do an easy calculation of "up to x% lost on ingestion will lead to y% increased average increase in updates" and determined that was worth it if it reduced the time spent on a feature or the server costs by a certain amount. It's a completely reasonable tradeoff as long as you can quantify the risk and quantify the cost (here's a tip for something that scarily few engineering organizations does: track not just time spent on projects, but calculate the cost per feature and report on it; it very quickly changes organisational priorities when managers see that what they thought was a minor change ended up costing $10k engineering time)

> and other data stores (such as Redis) provide this

I love Redis, but Redis doesn't offer the same query abilities as document stores like MongoDB. There are plenty of cases where Redis is the better choice, and there are plenty of cases where MongoDB is an option where Redis simply isn't. It depends entirely on the use case.

> Just because some data loss is acceptable doesn't mean it's desirable,

It's never desirable, but other properties of such a change may make the change desirable enough to make it worth dealing with any such data loss.

E.g. I've run platforms putting message queues entirely in memory because the performance / cost reduction was more important than not losing messages in the case of a crash, for example.

> What if the 1% listing happens to include an client's feed when the client is doing a major product launch?

For the case in question it didn't matter at all. Clients would use an XML-RPC call to indicate feed updates, and if they wanted to force re-indexing, they could, and the system adjusted "last ditch" scheduled re-retrievals based on typical update frequency anyway. Or we could force re-indexing too. In any case they had no guarantees of their data being made available on a specific time frame. In practice this was not a problem even once.

This is not hypothetical - we had cases where we restarted servers with said in-memory message queues mentioned above, purging millions of messages without issue, as the system was designed from the outset with the explicit intention that losing data most places was perfectly ok.

> Again, cache invalidation should happen intelligently via a well-thought-out algorithm, not by randomly dropping data, and there are solutions which supply that.

Do you think we just randomly say "oh, lets just lose data for fun?" In each instance I've designed systems like this, it has been a very deliberate choice of determining 1) what the cost and risks of losing data would be. In the above mentioned systems, data was refreshed so regularly, with abilities to do it faster, that the cost was deemed to be extremely low, with virtually no risks (nobody had any guarantees of getting their data into our system). 2) what the costs of avoiding/mitigating the risk of a loss would be.

In these cases, deciding to accept the risk because of the low cost meant that we could opt for less redundancy and fewer servers (e.g. the in-memory queue processing cost us 1/10th as much in server resources as if we hit disk). 3) Other factors: The "cache invalidation" in the case above was the reason for the frequent re-retrieval of feeds. We had no way of knowing whether or not a feed had changed without trying to retrieve it, and we could not depend on the sender supporting E-tag etc. (it was cheaper to just assume everything would be broken and design for it than invest resources in providing support to fix these things), so we had to be prepared to retrieve the whole feeds and compare against the database anyway. We could optimise that by keeping hashes etc., but in practice we found this gave minimal benefits compared to the massive cost reductions we got from being able to reduce redundancy across the entire indexing chain.

And fact is servers crash, disks die, errors in any component could corrupt data. You can choose to spend a fortune trying to prevent that through additional redundancy etc., and you should if your data is valuable and a source of truth. But when it isn't, it is a perfectly valid strategy to simply accept that things will fail and design the system to self-heal.

> What about the memory leaks?

As above: Serves crash. So if your system needs to be available, you need according redundancy. The typical additional scaling cost (accounting for a slightly increased risk of simultaneous restarts, requiring a small amount of extra capacity) of dealing with restarts on resource constraints are often perfectly ok. I tend to design all systems I work on to allow as many components at possible to be restarted at will, because you need to be able to accommodate upgrades etc. anyway. If you first do that, then allowing automatic restarts in the case of failure-types where that is acceptable tends to be trivial.

If crashes or forced restarts poses a risk to your system, then your overall architecture has a substantial unmitigated risk. If it doesn't pose a risk, then memory leaks (unless extreme and rapid/frequent) are rarely an issue.

> And what if your needs change, and you're no longer okay with data loss? Are you willing to take the risk that you're going to have to rewrite your storage layer because you chose a data store that drops data randomly, and your needs changed?

Then you have to pay some of the cost you saved by making those decisions in the first place. It's a calculated risk. Firstly it is rare. Secondly, it depends on your type of business - in a startup for example, future cash is on average far less worth than current cash, and cutting server costs and complexity substantially now is more important than avoiding additional engineering costs a year or two down the road.

E.g. I recently billed a client $30k/more on a project over ~18 months or so because they wanted to move the system between hosting providers a couple of times to make use of free credits of ~$30k. So overall it looks like they gained nothing. The reason they did it was that they did gain something: They deferred most of that cost by more than a year, in which time they did two funding rounds, and the cash they finally paid the remainder with cost them far less.

You have to account for this when considering the potential costs associated with risk of change. When you do, which decisions makes sense often change dramatically.

And you have to account for risk of change for all technical decisions anyway - this applies just as well if you e.g. pick an RDBMS instead and your needs requires you to add on something that will scale cheaper down the line.

So the answer is: Yes, I am often prepared to take that risk when the financials supports it. You need to understand your risks and understand your costs, and understand how the value of your cash on hand is expected to change.

All of this basically boils down not so much to technical choices, but project management, risk management and accounting.

This, to me, is also one of the areas that distinguishes software engineering from "development". Managing project cost and projected returns and risks are all part of sound software engineering, but it's something far too many organisations don't spend time on at all, which is terrifying.

Re: Why you should never use MongoDB (2013)

#153
post #68
post #57

Earlier quoted context omitted.

Don't know about the guy you replied to, but e.g. consider any application that regularly crawl feeds, api's etc. where the data is rapidly changing and only a portion of the data is necessary to give good output. There are lots of applications like that where you just need "enough" data to give good results and/or where any loss will auto-heal next time you crawl the original source.

That makes sense to me. If your MongoDB cluster under preasure will only actually persist 90% of your writes and this is something you anticipate, then MongoDB seems like a good choice, if writing in this style is faster than other nosql systems (that make grander promises about persistance) that is.

Exactly - the important thing is you need to actually understand the risk, and make an informed decision what level of loss is ok to you (and you should understand whether or not it's actually saving you anything - as you say, it makes sense if it is faster; there's no point losing data if you don't gain something from accepting the risk).

This is also perhaps the biggest problem with MongoDB: It's fast but unsafe "out of the box", and not everyone will know that when they use it. I think that's a large part of the problem a lot of people have with it.

Re: Why you should never use MongoDB (2013)

#154
post #143

Earlier quoted context omitted.

> Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like. The trouble is testability, versioning, deployment, and SQL just not being a pleasant language for expressing business logic. And the lack of a library ecosystem. And poor IDE support. And...

> > Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like. > The trouble is testability, versioning, deployment, and SQL just not being a pleasant language for expressing business logic. Most of those, to the extent they are valid, are trouble with using stored procs in SQL for that purpose, but most RDBMSs support stored procs in languages other than SQL.

Testability, versioning, deployment, IDE support and library support are still very much issues with non-SQL stored procedures.

Re: Why you should never use MongoDB (2013)

#155
post #143

Earlier quoted context omitted.

> Or you could use stored procedures. Think of it as making your RDBMS into a microservice, if you like. The trouble is testability, versioning, deployment, and SQL just not being a pleasant language for expressing business logic. And the lack of a library ecosystem. And poor IDE support. And...

>>SQL just not being a pleasant language for expressing business logic No kidding - don't do that. Sprocs are great to present a query interface and avoid sending queries over the wire every time. They can be handy to decouple the actual storage architecture from the query interface, so you can do tricky stuff in SQL without screwing up the clients. That doesn't mean you should stick your business logic in there. >>t…

> And how would any of those problems be solved by using raw SQL strings or a document DB? That just moves the problems back into the schema or the data, where it's even harder to deal with.

I'm arguing for using a non-SQL interface. Either a structured binary query protocol (which leaves you shipping a lot of data around sure, but at least removes the constructing-and-parsing SQL overhead), or a map-reduce style setup where you can run your queries where the data is but in a first-class programming language.

Re: Why you should never use MongoDB (2013)

#156

Earlier quoted context omitted.

> find the barriers to entry on NoSQL lower Not having to think rigorously about the logical structure of your data is a huge selling point for many. For programmers, because it means they don't have to think . And for employers, because it means they can make do with programmers who don't want to think.

That is a scary thought.

Only scary if you are locked into the past and/or closed-minded. (disclaimer: I'm not a mongo fan).

Re: Why you should never use MongoDB (2013)

#157
post #155

Earlier quoted context omitted.

>>SQL just not being a pleasant language for expressing business logic No kidding - don't do that. Sprocs are great to present a query interface and avoid sending queries over the wire every time. They can be handy to decouple the actual storage architecture from the query interface, so you can do tricky stuff in SQL without screwing up the clients. That doesn't mean you should stick your business logic in there. >>t…

> And how would any of those problems be solved by using raw SQL strings or a document DB? That just moves the problems back into the schema or the data, where it's even harder to deal with. I'm arguing for using a non-SQL interface. Either a structured binary query protocol (which leaves you shipping a lot of data around sure, but at least removes the constructing-and-parsing SQL overhead), or a map-reduce style set…

It seems to me that you're advocating changing implementation details (binary query protocol instead of SQL, map-reduce queries instead of sprocs) and claiming that it is somehow fundamentally different. But I don't see how that would be the case.

How is a binary query protocol fundamentally different than calling a sproc?

How is a map-reduce job in Javascript any different on the attributes you mentioned than ad-hoc SQL or a sproc?

Obviously map-reduce is a fundamentally different approach to data processing, but it seems to have similar traits in regards to source control, testability, etc.

Re: Why you should never use MongoDB (2013)

#158

My first introduction to databases was with PHP/MySQL, where normalization was the name of the game. The whole point of normalization is that there is no duplication of data anywhere. If it's possible for duplicate data to exist, that's a symptom of a design flaw in the schema. I've been using Mongo recently, and every time I raise criticism of it, the counterargument I hear is "forget about normalization! Duplicatio…

On the flip side... joins are expensive... I worked on an application, where presenting a single page, representing a single item in the application (classifieds site) required upwards of around 40 joins (iirc 36 or 46, I don't remember)... under load (including search result pages), the app was crushed by its' own weight. I think the bigger issue is that people are afraid of separating data at clear boundaries, so l…

40 joins for a classified ad?

Re: Why you should never use MongoDB (2013)

#159

The post should probably be titled "Why you should not pick a technology based on hype and without evaluating it first". While MongoDB has (and probably still has) some flaws and is not the perfect DB system, there are valid use cases where it can be a good choice. Building a social networking site that requires rich queries along a relationship graph is most definitely not one of them.

The HN consensus seems to be that MongoDB is good only for toy projects, and that you should switch to a real database as soon as things start getting more complex.

I think the consensus is closer to: use Postgres unless you have a very good reason to use something else. SQLite good for dev and toys.

Re: Why you should never use MongoDB (2013)

#160

Earlier quoted context omitted.

This is a problem I've had to explain to too many developers recently. It's not faster just because you throw away data modeling practices and jam bits of info all over the place. If you have semi normalized data relationships, Mongo really doesn't fit the bill that well as your primary data store. Where it shines is when you've got computed pieces of data to display (parts of a user data feed for example, data for a…

> find the barriers to entry on NoSQL lower Not having to think rigorously about the logical structure of your data is a huge selling point for many. For programmers, because it means they don't have to think . And for employers, because it means they can make do with programmers who don't want to think.

> Not having to think rigorously about the logical structure of your data is a huge selling point for many

I'll play the devils advocate: what ever logical structure of the data you come up with will not line-up with relational DB tables - I have had the pleasure of designing relational schemas for cyclic graphs. Hell, we have been trying and failing to do Object-Relational Mapping for years now, and it's still a shit-show. I could name a long list of ORM libraries and an even longer list of their various deficiencies.

Say you've thought rigorously about the logical structure of your data and v1 is out, and now a change comes along and you need an extra field or 5. Renormalize your structure, write some migration scripts (in both directions, just in case you want to downgrade). With NoSQL I'll just dump the new document structure and call it a day (or rather, deal wiht the differences in the application layer).

Post reply on HN